Introduction #
EVIO API is a regulated, MCP-native financial-data platform built for two audiences at once:
- Autonomous AI agents that discover, choose, call, and recover from EVIO endpoints without a human ever rendering a webpage.
- The humans who configure, govern, debug, and pay for those agents.
Where existing financial-data APIs ship raw bytes to a single human developer building a single application, EVIO ships ranked, decision-shaped outputs with reasoning traces, citations, and confidence scores — and treats agents as first-class entities with their own keys, budgets, and audit trails.
EVIO, Inc. is a Colorado corporation (HQ Henderson, NV), publicly traded on the OTC Current tier of OTC Markets (ticker OTC: EVIO). The Company files annual and quarterly disclosures and audited financials through OTC Markets' Alternative Reporting Standard. EVIO is not an SEC-registered issuer.
Quick start #
- Get an API key at app.evioinc.com/sign-up?invite=alpha. Test keys are prefixed
evk_test_*and bypass billing while still logging usage. - Make a request:
curl -H "Authorization: Bearer evk_test_..." \
"https://api.evioinc.com/v1/options/unusual?ticker=XNAS:AAPL&lookback=30d&limit=5"
You'll get back JSON with results, _reasoning, _citations, _confidence, _links, and _meta. See response envelope below for the full shape.
Authentication #
API surface uses Bearer API keys, exclusively. OAuth is available for the human-facing dashboard at app.evioinc.com only — never on the API surface itself.
Header
Authorization: Bearer evk_test_xxxxxxxxxxxxxxxxxxxxxxxx
| Prefix | Environment | Counts toward bill | Logs usage |
|---|---|---|---|
evk_test_* | Test | No | Yes |
evk_live_* | Live | Yes | Yes |
Per-agent keys
Per-agent keys are strongly recommended over org-wide keys. Each agent gets:
- Its own monthly call cap
- Its own budget cap (in cents)
- Its own audit trail
- Its own pause / revoke kill switch (1-second propagation guarantee)
Manage agents at app.evioinc.com/agents.
Rotation, hashing, and revocation
- API keys are SHA-256 hashed at rest. Plaintext is shown once at creation. Copy it immediately.
- The
Rotatebutton generates a new key and marks the old one asrevokingwith a 24-hour grace period before deletion. - Pausing an agent revokes all its keys with 1-second propagation across all
api.evioinc.comedges.
Response envelope #
Every successful (2xx) response carries the same five fields, plus the actual results:
{
"results": [ /* endpoint-specific payload */ ],
"_reasoning": ["sentence 1.", "sentence 2."],
"_citations": [{ "step": 0, "source": "...", "locator": "..." }],
"_confidence": { "score": 0.87, "label": "high", "factors": ["..."] },
"_links": [{ "id": "XNAS:AAPL", "endpoints": ["..."] }],
"_meta": {
"request_id": "req_01HXY...",
"latency_ms": 142,
"data_freshness": "mock",
"tokens_estimated": 318,
"version": "v1"
}
}
| Field | Purpose |
|---|---|
_reasoning | Ordered, atomic, one-sentence reasoning steps. Pass directly to your LLM — no re-derivation. |
_citations | Each citation links a _reasoning step to its data source (endpoint, dataset, snapshot ID). |
_confidence | Numeric score (0..1) + categorical label + factors[] that raised or lowered it. |
_links | Canonical IDs surfaced + EVIO endpoints that accept them. Composability hint for agent planners. |
_meta | request_id, latency_ms, data_freshness (mock/shadow/live), tokens_estimated, version. |
Opt-in fields
Pass ?include=alternatives,counterfactual,suggestions to add:
| Field | Purpose |
|---|---|
_alternatives | Results that ranked just below. |
_counterfactual | What the result would be if a single key input changed. |
_suggestions | 0–3 follow-up tool calls the agent might want to make next. |
These are off by default — they cost tokens, and you should only pay for them when you can route on them.
data_freshness
| Value | Meaning |
|---|---|
mock | Returning deterministic mock data (default during closed alpha) |
shadow | Real provider was called and logged for diff; mock data still returned to client |
live | Returning real provider output |
The transition mock → shadow → live is a single env-var flip on the server. Field names, types, and the envelope are stable. Customer code never changes.
The _meta.tokens_estimated field reports cost computed against tiktoken o200k_base so agents can budget — no competitor publishes this.
Error envelope #
400 Bad Request tells an agent nothing and a human almost nothing. EVIO makes every error machine-actionable AND human-readable.
{
"error": {
"code": "invalid_ticker_format",
"message": "Field 'ticker' must be in MIC:SYMBOL format. Received 'apple'. Try 'XNAS:AAPL'.",
"recoverable": true,
"retry_after_ms": null,
"docs_url": "https://evioinc.com/api/docs/#errors",
"request_id": "req_01HXY...",
"hints": [
{ "field": "ticker", "action": "transform", "suggestion": "XNAS:AAPL" }
]
}
}
| Field | Purpose |
|---|---|
code | Stable, namespaced identifier. Never repurposed. |
message | Human-readable. Includes the offending value AND a fix. |
recoverable | true → agent can fix the input and retry. false → escalate to human. |
retry_after_ms | Non-null only on rate-limit and transient-failure errors. |
docs_url | Stable per-error-code URL. Agents will follow links. |
request_id | Same as the X-Request-Id response header. |
hints[] | Structured {field, action, suggestion} triples. Agent doesn't have to parse prose. |
Catalog
| Code | HTTP | Recoverable | Description |
|---|---|---|---|
missing_authorization | 401 | yes | Missing Bearer token. Set Authorization header. |
invalid_api_key_format | 401 | yes | Token must start with evk_test_ or evk_live_. |
invalid_api_key | 401 | no | Key not recognized; may have been revoked or never existed. |
invalid_ticker_format | 400 | yes | ticker must be MIC:SYMBOL (e.g. XNAS:AAPL). |
invalid_request_body | 400 | yes | Body failed schema validation. See hints. |
invalid_accession_number | 400 | yes | accession_number must match ##########-##-######. |
agent_budget_exceeded | 429 | no | Agent hit monthly cap. Resets next month. |
rate_limit_exceeded | 429 | yes | Per-key limit exceeded. See retry_after_ms. |
data_freshness_stale | 503 | yes | Provider returned stale data; will be re-fetched. Retry recommended. |
data_provider_unavailable | 503 | no | EVIO_DATA_MODE=live but provider not implemented. |
job_not_found | 404 | no | Job ID does not exist or belongs to a different org. |
internal_error | 500 | no | Unexpected server error. Contact support with request_id. |
Stability promise
- Error codes never change meaning.
- New codes are added; old codes are not repurposed.
- Codes are namespaced:
invalid_*,rate_limit_*,agent_budget_*,data_*.
Conventions #
| Item | Convention |
|---|---|
| Tickers | ISO 10383 MIC + symbol, e.g. XNAS:AAPL, XNYS:JPM |
| SEC filings | Accession number, format ##########-##-###### |
| Dates | ISO 8601 strings; never separate year/month/day |
| Currencies | USD as numbers (no string formatting, no commas) |
| Booleans | true / false only |
| Null vs. omit | Omit null/missing fields. Don't expect both forms. |
| Request IDs | req_<base32> — opaque; surfaced in X-Request-Id header |
| Idempotency | POST endpoints accept Idempotency-Key: <UUIDv4> header |
Pagination & rate limits #
Pagination
List endpoints support cursor-based pagination:
?cursor=opaque_string&limit=50
limitdefault 50, max 200.cursoris opaque — do not parse it. Pass it back exactly as received.- Next-page cursor returned in
_meta.next_cursor(null when exhausted).
Rate limits
| Tier | Per-key (req/min) |
|---|---|
| Indie | 60 |
| Studio | 600 |
| Pro | 6,000 |
| Enterprise | Custom |
Per-agent overrides configurable from /agents/[id]. Headers on every response:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 45 # seconds until the bucket fully refills
X-Request-Id: req_01HXY...
When exhausted, the server returns 429 with the standard error envelope and retry_after_ms populated. Respect that value rather than guessing.
Field selection #
Every endpoint accepts a fields query parameter and a verbose flag.
| Setting | Behavior |
|---|---|
| (default) | Slim shape — minimum surface for typical agent decisions |
?fields=a,b,c | Comma-separated allow-list |
?fields=* | Full payload (alias for verbose=true) |
?verbose=true | Same as ?fields=* |
The ?include= query parameter is separate — it adds the opt-in envelope fields _alternatives, _counterfactual, _suggestions.
Options — unusual flow #
Top N tickers with statistically unusual options activity over a lookback window. Each result includes contract details, a volume z-score vs. baseline, an open-interest delta indicating new vs. closing positioning, and a reasoning trace.
Parameters
| Param | Type | Default | Notes |
|---|---|---|---|
ticker | string | required | MIC:SYMBOL or comma-separated batch up to 50 |
lookback | string | 30d | One of 7d, 14d, 30d, 60d, 90d |
limit | integer | 5 | 1..50 |
Example
curl -H "Authorization: Bearer $EVIO_KEY" \
"https://api.evioinc.com/v1/options/unusual?ticker=XNAS:AAPL&lookback=30d&limit=5"
When to use: unusual options flow, gamma squeeze candidates, accumulation signal candidates.
When NOT to use: backtesting strategies (use evio_backtest_run); computing portfolio Greeks (use evio_portfolio_risk).
Factor — multi-factor score #
Multi-factor decomposition (value / momentum / quality / low-vol / size) plus composite score for a basket of up to 50 tickers.
Body
{
"tickers": ["XNAS:AAPL", "XNAS:MSFT"],
"factors": ["value", "momentum", "quality", "low_vol", "size"],
"as_of": "2026-05-01"
}
When to use: ranking a basket on factor exposures, screening tilts, explaining a portfolio's profile.
When NOT to use: single-name research (use evio_equity_research); risk decomposition (use evio_portfolio_risk).
Backtest — strategy run #
Submit a strategy spec; receive equity curve, Sharpe, max drawdown, exposure stats. Three execution modes:
- Sync (default): respond when done, 60-second hard timeout.
- Streaming: pass
Accept: text/event-stream; SSE progress events. - Async: pass
mode: "async"(or useevio_backtest_run_async); receive ajob_idto poll at/v1/jobs/{id}or subscribe tojob.completedwebhook.
Body (minimum)
{
"name": "60-40 monthly rebalance",
"universe": ["XNAS:AAPL", "..."],
"rules": { },
"start": "2020-01-01",
"end": "2025-12-31",
"mode": "sync"
}
Equity — research package #
Composite equity research package for a single ticker — rating, target price, top drivers (positive + negative), comparable set, upcoming catalysts.
curl -H "Authorization: Bearer $EVIO_KEY" \
"https://api.evioinc.com/v1/equity/research?ticker=XNAS:AAPL&horizon=12m"
Regime — macro classification #
Macro regime classification (risk-on / risk-off / late-cycle / early-cycle) with confidence and configurable history. Subscribable via regime.changed webhook.
curl -H "Authorization: Bearer $EVIO_KEY" \
"https://api.evioinc.com/v1/regime/classify?region=us&history=30"
News — sentiment vs. baseline #
Aggregated news tone for a single ticker over a window, with 90-day rolling baseline and z-score; returns top contributing headlines.
curl -H "Authorization: Bearer $EVIO_KEY" \
"https://api.evioinc.com/v1/news/sentiment?ticker=XNAS:AAPL&window=7d"
SEC — filing structured summary #
Pulls an SEC filing by accession number, returns a structured section summary, and (by default) diffs against the prior filing of the same form type.
curl -H "Authorization: Bearer $EVIO_KEY" \
"https://api.evioinc.com/v1/sec/filing?accession_number=0000320193-25-000001&diff=true"
Portfolio — VaR, ES, factor exposure #
Submit a portfolio (positions + weights/qty). Returns 1-day and 10-day VaR, expected shortfall, factor exposures, named-scenario impacts, and top concentration risks.
curl -X POST -H "Authorization: Bearer $EVIO_KEY" \
-H "Content-Type: application/json" \
-d '{"positions":[{"ticker":"XNAS:AAPL","weight":0.3,"qty":100}],"horizon_days":10,"confidence":0.95}' \
https://api.evioinc.com/v1/portfolio/risk
MCP server #
The same eight endpoints are also exposed as a first-class MCP server at https://api.evioinc.com/mcp across all three current MCP transports:
stdio— Claude Desktop, Cursor, local agentshttp+sse— legacy cloud agentsstreamable-http— modern hosted-agent default (per November 2024 spec)
Discovery via https://api.evioinc.com/.well-known/mcp returns the server URL, transport list, auth method, and capability summary in JSON.
Tool description discipline
EVIO's MCP tool descriptions are prompts, not docs. Each follows the same template (imperative · when to use · when NOT to use with the alternative tool name · distinguishing features · concrete example, all under ~600 tokens). The "when NOT to use" pattern is the agent-visibility lever — frontier LLMs see all enabled tool descriptions on every call, so giving them disambiguation hints raises tool-pick accuracy.
Claude Desktop #
Drop into ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"evio": {
"url": "https://api.evioinc.com/mcp",
"transport": "streamable-http",
"headers": {
"Authorization": "Bearer evk_test_REPLACE_ME"
}
}
}
}
Restart Claude Desktop. EVIO's nine tools (eight endpoints + the async backtest variant) appear in the tool picker.
Cursor #
Drop into ~/.cursor/mcp.json:
{
"mcpServers": {
"evio": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-fetch", "https://api.evioinc.com/mcp"],
"env": { "AUTHORIZATION": "Bearer evk_test_REPLACE_ME" }
}
}
}
LangChain (Python) #
import os
os.environ["EVIO_API_KEY"] = "evk_test_..."
# Pull the wrapper from github.com/JpDeSilva17/evio-schemas
from langchain_tools import EVIO_TOOLS
from langchain.agents import create_react_agent
from langchain_anthropic import ChatAnthropic
agent = create_react_agent(
ChatAnthropic(model="claude-sonnet-4-6"),
tools=EVIO_TOOLS,
)
result = agent.invoke({"input": "What's the unusual options activity in AAPL today?"})
CrewAI (Python) #
import os
os.environ["EVIO_API_KEY"] = "evk_test_..."
from crewai_tools import EVIO_TOOLS
from crewai import Agent, Crew, Task
analyst = Agent(role="Quant analyst", goal="...", tools=EVIO_TOOLS)
crew = Crew(agents=[analyst], tasks=[Task(description="...")])
crew.kickoff()
Anthropic SDK (tool use) #
import anthropic, json
client = anthropic.Anthropic()
with open("anthropic-tools.json") as f:
tools = json.load(f)
resp = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
tools=tools,
messages=[{"role": "user", "content": "What's the macro regime?"}],
)
Anthropic returns tool_use blocks; you make the HTTPS call to api.evioinc.com with the user's evk_test_* key in the Authorization header, then send the result back as a tool_result.
OpenAI Agents SDK / function calling #
from openai import OpenAI
import json
client = OpenAI()
with open("openai-functions.json") as f:
tools = json.load(f)
resp = client.chat.completions.create(
model="gpt-5",
messages=[{"role": "user", "content": "Find unusual options on AAPL."}],
tools=tools,
)
Vercel AI SDK / Mastra / Voltagent (TypeScript) #
import { tool } from "ai";
import { z } from "zod";
export const evioOptionsUnusual = tool({
description: "Top N tickers with unusual options activity over a lookback window.",
parameters: z.object({
ticker: z.string(),
lookback: z.enum(["7d", "14d", "30d", "60d", "90d"]).default("30d"),
limit: z.number().int().min(1).max(50).default(5),
}),
execute: async ({ ticker, lookback, limit }) => {
const r = await fetch(
`https://api.evioinc.com/v1/options/unusual?ticker=${ticker}&lookback=${lookback}&limit=${limit}`,
{ headers: { Authorization: `Bearer ${process.env.EVIO_API_KEY}` } },
);
return r.json();
},
});
Definitions for the other seven endpoints follow the same pattern. A generated TypeScript module is on the v1.1 roadmap.
Webhook events #
| Event | When |
|---|---|
regime.changed | Macro regime classification flipped |
agent.budget_warning | Agent crossed 80% of monthly cap |
agent.budget_exceeded | Agent hit 100% |
job.completed | Async job finished |
job.failed | Async job failed terminally |
alert.fired (v1.1) | User-configured threshold crossed |
Webhook delivery #
- Auth: HMAC-SHA256 signature in
X-Evio-Signatureheader. Verify before processing. - Retries: exponential backoff up to 24 hours, then dead-lettered.
- Idempotency: every event has a UUID; customers should dedupe.
- Replay: from
app.evioinc.com/settings/webhooks, last 100 events kept.
Verifying the signature
# Python
import hmac, hashlib
def verify(secret: str, body: bytes, signature: str) -> bool:
expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature)
// TypeScript
import crypto from "node:crypto";
export function verify(secret: string, body: string, sig: string): boolean {
const expected = crypto.createHmac("sha256", secret).update(body).digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig));
}
Discovery surfaces #
Both human and machine. Both must work.
Machine surfaces (agent first contact)
| URL | Returns |
|---|---|
evioinc.com/llms.txt | llmstxt.org-compliant overview optimized for LLM ingest |
evioinc.com/llms-full.txt | Full reference in one fetchable file |
api.evioinc.com/.well-known/mcp | MCP server URL, transports, auth method, capabilities |
api.evioinc.com/.well-known/openapi | Pointer to current OpenAPI document |
api.evioinc.com/.well-known/agent-capabilities | Compact JSON tool/schema/example manifest |
api.evioinc.com/openapi.json | OpenAPI 3.1 (mirror of v1.yaml in evio-schemas) |
evioinc.com/.well-known/security.txt | Standard security contact (RFC 9116) |
Public schemas repo #
The OpenAPI 3.1 spec and per-framework tool wrappers are mirrored to a separate, public, MIT-licensed repo:
github.com/JpDeSilva17/evio-schemas
It contains:
v1.yaml— OpenAPI 3.1 specframeworks/anthropic-tools.jsonframeworks/openai-functions.jsonframeworks/langchain_tools.pyframeworks/crewai_tools.pyframeworks/mcp-manifest.jsonexamples/claude-desktop.json,examples/cursor.jsonCHANGELOG.md— SemVer + min 90-day deprecation timelines
Every breaking change ships with at least 90 days of deprecation notice via the Deprecation and Sunset HTTP headers on the live API and a ## Deprecated section in the schemas CHANGELOG.md.
Status & support #
| Resource | URL |
|---|---|
| Status page | status.evioinc.com |
| Changelog | /api/changelog.html |
| Security | /api/security.html |
| Pricing | /api/pricing.html |
| Terms / Privacy / AUP | /api/legal/* |
| info@evioinc.com |
Closed alpha. The eight endpoints currently return mock JSON in their final response shape. Live market-data integration is targeted Q3 2026 as a transparent provider swap — field names, types, and the envelope are stable, so customer code does not change.
