Gateway API
The data plane your applications call. It is OpenAI-compatible: point an existing SDK at https://aam.example.com/v1 with a virtual key and it works. Every endpoint runs the same pipeline — authentication, budget gate, guardrails, routing with fallback, audit — regardless of surface.
Authentication: Authorization: Bearer sk-… or x-api-key: sk-… on every endpoint.
Chat completions
POST/v1/chat/completions
The workhorse. OpenAI-compatible, used by most applications and SDKs.
| Parameter | Type | Required | Notes |
|---|---|---|---|
model | string | yes | A catalog alias, not a vendor model id — routing and audit key on it |
messages | array | yes | OpenAI message objects (role, content); text is what guardrails screen |
stream | boolean | no | true returns Server-Sent Events (chat.completion.chunk frames) |
temperature, max_tokens, top_p, stop, seed, response_format, tools, tool_choice, … | — | no | To an OpenAI-protocol deployment these pass through losslessly, including unknown and future parameters. Translating adapters (Anthropic/Gemini/Vertex) carry the mapped set: sampling params, text/image content, and full tool/function calling |
curl -s https://aam.example.com/v1/chat/completions \
-H "Authorization: Bearer sk-..." \
-H "Content-Type: application/json" \
-d '{"model": "fast", "messages": [{"role": "user", "content": "hello"}]}'
Sample response (the gateway may rewrite model back to the requested alias):
{
"id": "chatcmpl-9x2...",
"object": "chat.completion",
"created": 1752480000,
"model": "fast",
"choices": [
{
"index": 0,
"message": { "role": "assistant", "content": "Hello! How can I help?" },
"finish_reason": "stop"
}
],
"usage": { "prompt_tokens": 9, "completion_tokens": 8, "total_tokens": 17 }
}
Streaming. With "stream": true, frames arrive as data: SSE lines ending with data: [DONE]. Usage is read from the streaming usage chunk, so streamed calls are metered and budgeted like any other. Response guardrails screen the stream inline; a block emits an error frame and stops the stream.
Errors. 401 unknown/revoked key · 403 content_blocked (request guardrail; nothing sent upstream) · 429 over budget or rate-limited (Retry-After on rate limits) · upstream errors are relayed with their original status after retries and failover are exhausted.
Embeddings
POST/v1/embeddings
Same routing, budget, guardrail (request-direction), and audit pipeline as chat.
| Parameter | Type | Required | Notes |
|---|---|---|---|
model | string | yes | A catalog alias whose deployment supports embeddings |
input | string or array | yes | Text(s) to embed |
Serves an OpenAI-compatible upstream natively, or translates to a Gemini or Vertex embeddings target. (Anthropic has no embeddings API.) Response vectors are not screened — there is nothing readable to screen.
Models
GET/v1/models
Lists the calling org's registered aliases from the catalog — a direct read, no upstream call. This is what fills model menus in OpenAI-compatible clients.
{
"object": "list",
"data": [
{ "id": "fast", "object": "model" },
{ "id": "chat", "object": "model" },
{ "id": "local-llama", "object": "model" }
]
}
Responses (OpenAI native surface)
POST/v1/responses
Accepts the OpenAI Responses wire format (used by Codex). The body is opaque to the gateway except model and stream; budget and request guardrails run over every string leaf of the JSON.
- Routed to an
openai-protocol deployment: passthrough — the body is relayed verbatim (the alias rewritten to the upstream model), the response relayed byte-for-byte. Lossless; unknown features just work. - Routed to any other protocol: translated through the canonical chat shape, so an Anthropic or Gemini backend can serve it. Carries instructions, input, sampling params, and tool/function calling including prior tool-use history; image/file inputs and reasoning items are not yet mapped on the translate path.
Messages (Anthropic native surface)
POST/v1/messages
Accepts the Anthropic Messages format (Anthropic SDKs, Claude Code). Same branch-by-protocol behaviour:
- To an
anthropic-protocol deployment: passthrough, lossless, including native streaming SSE. - To any other protocol: translated — system, conversation, images, sampling params, and full tool use are mapped; the response is mapped back to the Messages shape, with streaming emulated as a native SSE sequence.
Governance is identical on both branches: budget gate, request guardrails, response screening (inline on streams, with cross-chunk carry-over), and audit.
What is deliberately not served
Batches, audio, images, video, vector stores, realtime, evals, moderations, and the deprecated Assistants API are not exposed. If you need that breadth, register a LiteLLM instance as a provider and keep the gateway's keys, budgets, guardrails, and audit in front of it — see Ollama, vLLM & LiteLLM.