codai docs
API reference

API reference

How to read the reference — base URLs, authentication, the error envelope, SSE conventions and where changes are announced.

The reference is generated from hand-authored OpenAPI 3.1 documents that mirror the code route by route. A parity test in the repo fails whenever a public route exists without documentation, or a documented route no longer exists, so what you read here is what the servers register.

Three services, three base URLs

ServiceBase URLReferenceAuth
Gateway (inference + platform)https://ai.codai.roGatewayAuthorization: Bearer codai_…
Resolve (verified bug fixes)https://resolve.codai.roResolvesame codai_ key
Auth (OpenID Provider)https://auth.codai.roAuthOAuth 2.1 / OIDC

Try-it panels in each operation send real requests from your browser. Paste a key you are happy to spend a few cents with; the panels never store it.

Authentication

Every gateway and Resolve call carries a codai API key in the bearer header. Keys start with codai_, are shown once in the hub and are revocable there. /v1/messages also accepts the Anthropic-style x-api-key header. Ephemeral tokens from POST /v1/tokens are accepted only by the realtime WebSocket — a raw key in a query string is refused.

Apps that sign users in obtain a scoped key through the OIDC connect flow instead of asking for one.

The error envelope

The gateway answers every failure with one JSON shape:

{
  "error": {
    "message": "Invalid request body",
    "type": "invalid_request_error",
    "code": "bad_request",
    "details": { "fieldErrors": { "messages": ["Required"] } }
  }
}
StatuscodeWhen
400bad_requestBody or query failed validation — details holds the field errors
401invalid_api_keyMissing, revoked or paused key
402subscription_inactiveThe subscription behind the key is inactive
403forbiddenModel allow-list, role or ownership check failed
404not_foundNo such resource, or it belongs to someone else
409lease_held, seq_conflict, task_not_confirmable, host_offlineOptimistic-concurrency conflicts on sessions, tasks and hosts
413payload_too_largeRequest body over 12 MB
429rate_limit_exceeded, quota_exceededRate limit / spend cap, or task quota — read Retry-After
502upstream_errorEvery upstream lane failed after failover
503search_unavailableThe search service behind /v1/tools/search is down
500internal_errorUnexpected fault; already reported to us

Resolve and Auth are different services with their own, simpler shapes: Resolve returns { "error": "<string>" }, Auth returns the OAuth { "error", "error_description" } pair. Each reference page documents its own.

Streaming conventions

  • SSE endpoints answer text/event-stream. Chat Completions, Messages and Responses use their wire format's framing; the usage chunk on a Chat Completions stream is always emitted, whatever stream_options says.
  • codai's own streams (agents, sessions, hosts) use named event: frames documented on each operation, plus : ping comments as heartbeats where noted.
  • No stream emits id: lines and Last-Event-ID is not read. Resume with the cursor the endpoint offers (after on sessions) or accept a full replay (agents).
  • Cost headers on a stream read x-codai-cost-estimate: pending; the metered cost lands later on GET /v1/receipt.

Versioning and changes

The gateway is unversioned beyond the /v1 prefix. Additive changes (new fields, new headers, new endpoints) ship without notice; anything that removes or renames is announced in the changelog first. Field names are returned exactly as the code sends them — a few objects mix camelCase and snake_case, and the reference reflects that rather than hiding it.

On this page