Skip to content
Talk to our solutions team

AI Gateway API

The gateway serves two API dialects on the same port. The dialect is chosen by the route; everything behind it — alias resolution, budgets, cache, the upstream call, metering, audit — is dialect-agnostic and operates on one canonical representation.

Client dialect is independent of upstream dialect. An Anthropic-SDK caller can be served by a vLLM upstream and an OpenAI-SDK caller by Anthropic.

Every request to the data plane carries the platform tenancy headers:

HeaderRequiredPurpose
X-Kis-TenantyesTenant id — partitions registry, cache, budgets and audit
X-Kis-ProductyesProduct id
X-Kis-EnvironmentyesEnvironment id
X-Kis-BlockyesCalling block, for cost attribution
X-Kis-CustomernoCustomer id
X-Kis-Prioritynocritical, normal (default) or background

A request missing a mandatory header is rejected rather than served against a default tenant.

POST /v1/chat/completions chat completion, sync or SSE
POST /v1/embeddings embeddings
GET /v1/models aliases resolvable by this caller
POST /v1/batches submit a batch
GET /v1/batches/{id} batch status
POST /v1/batches/{id}/cancel cancel a batch
GET /v1/batches/{id}/results batch results
POST /images/generations image generation
POST /audio/speech text to speech
POST /audio/transcriptions speech to text
POST /v1/messages message completion, sync or SSE
POST /v1/messages/count_tokens token count without generating

model names a gateway alias, not a provider model — support.classifier.v3, not claude-haiku-4-5. Which upstream that resolves to is configuration.

{
"model": "support.classifier.v3",
"messages": [{ "role": "user", "content": "where is my order?" }]
}

Both dialects stream over SSE when the request asks for it. Mid-stream events are recorded, so a replayed streamed call reproduces the stream rather than only the final text. Cancelling mid-stream is supported and recorded as such in the audit trail.

A separate port behind mTLS and platform authentication.

POST /admin/v1/aliases create an alias
GET /admin/v1/aliases list aliases visible to the tenant
GET /admin/v1/aliases/{name} one alias, with resolved inheritance
PUT /admin/v1/aliases/{name} publish a new version
DELETE /admin/v1/aliases/{name} retire a tenant alias
GET /admin/v1/prompts/{name} fetch a prompt, any version
PUT /admin/v1/prompts/{name} publish a new version
GET /admin/v1/budgets/{tenant} current consumption against every scope
GET /admin/v1/audit/{request_id} the audit record for one request
GET /admin/v1/stats gateway statistics
GET /admin/v1/health readiness

Alias objects carry name, dialect, cache (with enabled and mode), budget (including cost_ceiling_usd_per_tenant_per_day), fallback_count and ab_routing. Platform-owned aliases are readable but not writable by a tenant.

The error body is rendered in the caller’s dialect.

OpenAI envelope:

{
"error": {
"message": "human-readable, no customer data",
"type": "invalid_request_error",
"code": "canonical_error_code"
}
}

Anthropic envelope:

{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "human-readable, no customer data"
}
}

Note the asymmetry: the OpenAI envelope carries the canonical code, the Anthropic one does not. If you are matching on error identity, use the OpenAI dialect or the request id.

StatusMeaning
400Malformed request
401 / 403Authentication or authorisation failure
404Alias not resolvable for this tenant
429Budget or rate limit exceeded — sets Retry-After
5xxAll upstreams in the fallback chain failed

429 responses set the Retry-After header in seconds. Messages never contain customer data, so they are safe to log and surface.