Download OpenAPI specification:Download
Read an application's governed-traffic usage and the Cortega Agents'
verdicts back out. This is the control-plane read side; to send
governed traffic, see the
Gateway API. The same crt_ key
also invokes Cortega Agents at POST /agents/run when it has scope
agents:run.
A tenant admin issues an API key under System → API Access; the key
is a bearer token prefixed crt_ and is shown once at creation. (Distinct
from the gateway's ck_ virtual key.)
Authorization: Bearer crt_...
Every response carries X-RateLimit-Limit / X-RateLimit-Remaining /
X-RateLimit-Reset; a 429 includes Retry-After (seconds).
A key carries one or more scopes and, optionally, a restriction to specific applications. The key's tenant, scopes, and app restriction are resolved from the key itself — never from a request parameter, so a key can only ever read its own tenant's data.
| Scope | Grants |
|---|---|
analytics:read |
the /analytics/* endpoints |
observability:read |
the Observability MCP endpoint |
agents:run |
POST /agents/run (invoke a Cortega Agent; Legal Agent first) |
An Application is a named thing an admin registers, with the request header that identifies it. Cortega groups all of that app's governed LLM and MCP traffic by the value the app puts in that header (an "instance" — e.g. a session id or conversation id) and reports usage per instance.
Returns the enabled applications the key is allowed to see (a key may be restricted to specific app slugs). Requires analytics:read.
curl -H "Authorization: Bearer $CORTEGA_API_KEY" \ "https://$CORTEGA_HOST/api/v1/analytics/apps"
{- "apps": [
- {
- "slug": "vcontest",
- "name": "vContest Voice",
- "id_header": "X-VCon-UUID",
- "applies_to": "both",
- "description": "LiveKit voice app"
}
]
}| slug required | string The application's URL-safe slug. |
| from | string <date-time> Window start (RFC3339). Default is 24h before |
| to | string <date-time> Window end (RFC3339). Default now. The span is capped at 90 days. |
curl -H "Authorization: Bearer $CORTEGA_API_KEY" \ "https://$CORTEGA_HOST/api/v1/analytics/apps/vcontest?from=2026-09-01T00:00:00Z"
{- "app": {
- "slug": "string",
- "name": "string",
- "id_header": "string",
- "applies_to": "llm",
- "description": "string"
}, - "window": {
- "from": "2019-08-24T14:15:22Z",
- "to": "2019-08-24T14:15:22Z"
}, - "traffic": {
- "cost_usd": 0,
- "llm": {
- "call_count": 0,
- "prompt_tokens": 0,
- "completion_tokens": 0,
- "total_tokens": 0,
- "cost_usd": 0,
- "models": [
- {
- "model": "string",
- "provider": "string",
- "call_count": "string",
- "prompt_tokens": "string",
- "completion_tokens": "string",
- "cache_read_tokens": "string",
- "cache_write_tokens": "string",
- "reasoning_tokens": "string",
- "total_tokens": 0,
- "cost_usd": 0
}
]
}, - "governance": {
- "call_count": 0,
- "cost_usd": 0,
- "functions": [
- {
- "function": "string",
- "model": "string",
- "provider": "string",
- "call_count": "string",
- "prompt_tokens": "string",
- "completion_tokens": "string",
- "cache_read_tokens": "string",
- "cache_write_tokens": "string",
- "reasoning_tokens": "string",
- "total_tokens": 0,
- "cost_usd": 0,
- "raw_cost_usd": 0
}
]
}, - "mcp": {
- "call_count": 0,
- "tools": [
- {
- "server": "string",
- "tool": "string",
- "call_count": "string",
- "allowed": 0,
- "blocked": "string",
- "error": "string",
- "p50_latency_ms": 0
}
], - "servers": [
- {
- "server": "string",
- "call_count": 0,
- "blocked": 0
}
]
}
}
}Instances overlapping the window, newest last-seen first. Page with limit and the next_cursor from the previous response.
| slug required | string The application's URL-safe slug. |
| from | string <date-time> Window start (RFC3339). Default is 24h before |
| to | string <date-time> Window end (RFC3339). Default now. The span is capped at 90 days. |
| limit | integer <= 500 Default: 100 |
| cursor | string Opaque cursor from a previous response's |
curl -H "Authorization: Bearer $CORTEGA_API_KEY" \ "https://$CORTEGA_HOST/api/v1/analytics/apps/vcontest/instances?limit=50"
{- "app": {
- "slug": "string",
- "name": "string",
- "id_header": "string",
- "applies_to": "llm",
- "description": "string"
}, - "window": {
- "from": "2019-08-24T14:15:22Z",
- "to": "2019-08-24T14:15:22Z"
}, - "instances": [
- {
- "instance_id": "string",
- "first_seen": "2019-08-24T14:15:22Z",
- "last_seen": "2019-08-24T14:15:22Z",
- "llm_call_count": 0,
- "mcp_call_count": 0
}
], - "next_cursor": "string"
}One ID value's LLM usage (per model / provider) and MCP usage (per server / tool). The window is the instance's own first-seen … last-seen span; this endpoint takes no from/to.
| slug required | string The application's URL-safe slug. |
| instanceId required | string The value the application sent in its ID header (e.g. a vCon UUID). |
curl -H "Authorization: Bearer $CORTEGA_API_KEY" \ "https://$CORTEGA_HOST/api/v1/analytics/apps/vcontest/instances/0191ae8b-7412-7000-8800-aad4f5bf0bd5"
{- "app": {
- "slug": "vcontest",
- "id_header": "X-VCon-UUID",
- "applies_to": "both"
}, - "instance_id": "0191ae8b-7412-7000-8800-aad4f5bf0bd5",
- "traffic": {
- "cost_usd": 0.00034,
- "llm": {
- "call_count": 4,
- "total_tokens": 1130,
- "cost_usd": 0.00031,
- "models": [
- {
- "model": "us.meta.llama3-3-70b-instruct-v1:0",
- "provider": "bedrock",
- "call_count": "4",
- "total_tokens": 1130,
- "cost_usd": 0.00031
}
]
}, - "mcp": {
- "call_count": 6,
- "tools": [
- {
- "server": "crm_mcp",
- "tool": "get_customer",
- "call_count": "3",
- "allowed": 3,
- "blocked": "0",
- "p50_latency_ms": 120
}
]
}
}, - "computed_at": "2026-09-07T18:25:00Z"
}For an application with a threat-level policy: the current level (0 when none is raised), the violations counted, and the seconds until the level resets. A key scoped to specific applications can read only those. Returns 503 when the level store cannot be read, so a caller never mistakes an outage for level 0.
| application required | string The X-Cortega-Application value. |
curl -H "Authorization: Bearer $CORTEGA_API_KEY" \ "https://$CORTEGA_HOST/api/v1/analytics/threat/apps/policy-out-of-scope-demo"
{- "application": "string",
- "countdown_seconds": 0,
- "refresh_on": "hit",
- "max_level": 0,
- "level": 0,
- "hits": 0,
- "expires_in_seconds": 0,
- "expires_at": "2019-08-24T14:15:22Z"
}Background agents (Scorer, Risk & Fraud Detection, Sentiment, and others) that analyse a whole session. Their verdicts are readable per application instance. POST /agents/run invokes an agent immediately (Legal Agent first).
Every session agent's latest result for one ID-header value. Only agents the tenant has enabled and licensed, and whose configuration names this application, appear. An unknown or not-yet-analysed instance returns agents: [] with 200.
A session is scored once it has been quiet for the agent's quiet period and finalised after a period of silence; until then a row comes back with status: "accumulating" and no score. score can change across run_count re-runs as the conversation grows.
| slug required | string The application's URL-safe slug. |
| instanceId required | string The value the application sent in its ID header (e.g. a vCon UUID). |
| agent | string Narrow to one agent domain, e.g. |
curl -H "Authorization: Bearer $CORTEGA_API_KEY" \ "https://$CORTEGA_HOST/api/v1/analytics/apps/vcontest/instances/0191ae8b-7412-7000-8800-aad4f5bf0bd5/agents?agent=risk"
{- "app": {
- "slug": "vcontest",
- "id_header": "X-VCon-UUID",
- "applies_to": "both"
}, - "instance_id": "0191ae8b-7412-7000-8800-aad4f5bf0bd5",
- "agents": [
- {
- "domain": "scorer",
- "agent_id": "6f0e2a1c-0000-0000-0000-000000000001",
- "name": "Customer support quality",
- "status": "processed",
- "score": 82.5,
- "summary": "Billing question resolved after identity check.",
- "detail": {
- "criteria": [
- {
- "id": "identity-verification",
- "weight": 2,
- "score": 100
}
], - "weighted_score": 82.5
}, - "run_count": 2,
- "processed_at": "2026-09-07T18:22:04Z"
}, - {
- "domain": "risk",
- "status": "processed",
- "score": 12,
- "label": "clean",
- "severity": "none",
- "summary": "No fraud signals. Identity verified on first attempt.",
- "detail": {
- "signals": [ ],
- "risk_factors": [ ],
- "recommended_action": "none"
}, - "processed_at": "2026-09-07T18:22:05Z"
}
]
}Runs a Cortega Agent against caller-supplied text and returns the result immediately. First agent is Legal (Legal Agent): CourtListener lookup plus the claim-support/relevancy judge. Same pipeline as the in-product console, without writing findings and without the inline correction loop. Requires agents:run. agent accepts legal, ai_verifier, and legal_citation (empty defaults to legal).
| agent | string |
| response_text required | string |
| request_text | string |
{- "agent": "string",
- "response_text": "string",
- "request_text": "string"
}{- "domain": "string",
- "truth": "true",
- "rationale": "string",
- "citations": [
- {
- "citation": "string",
- "truth": "true",
- "rationale": "string"
}
]
}Per-developer usage of Claude Code and Codex, from the telemetry those tools send to the client telemetry collector. Separate from governed gateway traffic.
One entry per developer email seen in the window, busiest first (Claude Code cost, then tokens). Counts are window totals. Claude Code reports its own API-equivalent cost estimate. Codex reports no cost, so Cortega computes one from its token counts and the lowest list price for the model in its rate catalog (cached input at the cache-read price). Neither is a charge on a subscription. A model with no catalog price has cost_known: false and is named in unpriced_models, and its cost is not counted. by_model splits both tools by model. matched is true when the email belongs to a Cortega user. Prompt and response text is never stored. The window is capped at 90 days. A tenant key sees the rows its devices labelled with that tenant. A platform (Tenant 0) key sees every row, including rows from hand-configured clients that carry no tenant label. The label is supplied by the device with the shared collector token, so it separates tenants in the report but is not a security boundary. Returns 502 when the client telemetry store is not available, for example before the client telemetry tables are migrated.
| from | string <date-time> Window start (RFC3339). Default is 24h before |
| to | string <date-time> Window end (RFC3339). Default now. The span is capped at 90 days. |
curl -H "Authorization: Bearer $CORTEGA_API_KEY" \ "https://$CORTEGA_HOST/api/v1/analytics/coding-tools/usage?from=2026-10-01T00:00:00Z"
{- "window": {
- "from": "2019-08-24T14:15:22Z",
- "to": "2019-08-24T14:15:22Z"
}, - "developers": [
- {
- "email": "string",
- "name": "string",
- "matched": true,
- "last_active": "2019-08-24T14:15:22Z",
- "claude_code": {
- "sessions": 0,
- "active_days": 0,
- "active_seconds": 0,
- "cost_usd": 0,
- "input_tokens": 0,
- "output_tokens": 0,
- "cache_read_tokens": 0,
- "cache_creation_tokens": 0,
- "lines_added": 0,
- "lines_removed": 0,
- "commits": 0,
- "pull_requests": 0,
- "edits_accepted": 0,
- "edits_rejected": 0,
- "models": [
- "string"
], - "by_model": [
- {
- "model": "string",
- "input_tokens": 0,
- "output_tokens": 0,
- "cache_tokens": 0,
- "cost_usd": 0,
- "cost_known": true,
- "tool_calls": 0
}
]
}, - "codex": {
- "sessions": 0,
- "turns": 0,
- "tool_calls": 0,
- "active_days": 0,
- "input_tokens": 0,
- "output_tokens": 0,
- "cached_input_tokens": 0,
- "reasoning_tokens": 0,
- "models": [
- "string"
], - "auth_modes": [
- "string"
], - "cost_usd": 0,
- "unpriced_models": [
- "string"
], - "by_model": [
- {
- "model": "string",
- "input_tokens": 0,
- "output_tokens": 0,
- "cache_tokens": 0,
- "cost_usd": 0,
- "cost_known": true,
- "tool_calls": 0
}
]
}
}
], - "by_model": [
- {
- "model": "string",
- "input_tokens": 0,
- "output_tokens": 0,
- "cache_tokens": 0,
- "cost_usd": 0,
- "cost_known": true,
- "tool_calls": 0,
- "tool": "claude_code",
- "developers": 0
}
], - "totals": {
- "developers": 0,
- "matched": 0,
- "unmatched": 0
}
}A Model Context Protocol server (Streamable HTTP, stateless JSON responses) exposing the tenant's governed-traffic telemetry as MCP tools: traffic_summary, recent_failures, model_performance, spend_breakdown, guardrail_activity, mcp_tool_activity. Requires observability:read. Every query is scoped to the key's tenant. The request and response bodies are MCP JSON-RPC and are not modelled here — point an MCP client at this URL with the crt_ key as a bearer token.
An MCP JSON-RPC request.
{ }