API Reference
kRouter's endpoints on localhost:20128: OpenAI Chat Completions, Anthropic Messages, the Responses API used by Codex, models, media, and auth.
kRouter serves one API on http://localhost:20128 (or the port you chose with --port). It accepts three request formats, OpenAI Chat Completions, Anthropic Messages and the OpenAI Responses API, and translates each into whatever the chosen provider speaks. The model field decides where a request goes: <provider-alias>/<model-id>, or the name of a combo.
Authentication
- Requests from the machine kRouter runs on need no key, unless kRouter was started with
REQUIRE_API_KEY=true. - Requests from anywhere else need a kRouter API key. Without one they get
401with "API key required for remote API access". - Send the key as
Authorization: Bearer <key>or asx-api-key: <key>. - "Same machine" is decided from the connection's peer address, not the
Hostheader. Requests that arrive through a reverse proxy always count as remote. - Create keys on the dashboard's Endpoint page, in the API Keys section.
The examples below send $KROUTER_KEY. From the machine kRouter runs on you can leave that header out.
Endpoints
| Method and path | What it does |
|---|---|
POST /v1/chat/completions | OpenAI Chat Completions |
POST /v1/messages | Anthropic Messages, used by Claude Code |
POST /v1/messages/count_tokens | Anthropic token count |
POST /v1/responses | OpenAI Responses API, used by Codex |
POST /v1/responses/compact | Responses context compaction |
GET /v1/models | Models of your connected providers, plus your combos |
GET /v1/models/tts (also stt, embedding, image, video, web) | Models of one kind |
POST /v1/embeddings | Embeddings |
POST /v1/images/generations | Image generation |
POST /v1/audio/speech, POST /v1/audio/transcriptions, GET /v1/audio/voices | Text to speech, speech to text, voice list |
POST /v1/videos/generations, GET /v1/videos/ID | Video generation and its result, through xAI only |
POST /v1/search, POST /v1/web/fetch | Web search and URL fetch |
POST /api/v1beta/models/MODEL:generateContent | Gemini format; note the /api prefix |
POST /v1/api/chat | Ollama-compatible chat |
A doubled /v1/v1/... path is accepted too, and /codex/... is an alias for /v1/responses. The media endpoints are covered in Multimodal & Agent Skills.
POST /v1/chat/completions
Standard OpenAI shape. Streaming and tool calls use the OpenAI formats whichever provider serves the model.
curl http://localhost:20128/v1/chat/completions \
-H "Authorization: Bearer $KROUTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "cc/claude-opus-4-7",
"messages": [
{"role": "user", "content": "Hello!"}
],
"stream": true
}'POST /v1/messages
The Anthropic Messages API, used by Claude Code and other Anthropic clients. Point them at http://localhost:20128/v1 (for Claude Code, ANTHROPIC_BASE_URL). The model does not have to be a Claude model: kRouter translates to and from the provider's format.
curl http://localhost:20128/v1/messages \
-H "x-api-key: $KROUTER_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "cc/claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello!"}]
}'POST /v1/responses
The OpenAI Responses API. Send model, input (a string, or a list of message, function-call and function-call-output items) and, optionally, instructions, tools and "stream": true. kRouter converts the request for whichever provider serves model, then converts the reply back: Responses events when streaming, a Responses object when not. Any connected model, and any combo, can sit behind a Responses client. How the two OpenAI formats differ: Responses API vs Chat Completions.
curl http://localhost:20128/v1/responses \
-H "Authorization: Bearer $KROUTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "cc/claude-sonnet-4-6",
"instructions": "Answer in one sentence.",
"input": "What does HTTP 429 mean?",
"stream": true
}'kRouter does not store responses, so it cannot resolve a previous_response_id. Send the whole conversation in input on every request.
POST /v1/responses/compact takes the same body and asks for a compacted conversation. It is meant for OpenAI Codex models: with a cx/... model, kRouter forwards it to Codex's own compact endpoint.
Codex uses this endpoint. kRouter's Codex setup (dashboard CLI Tools, OpenAI Codex CLI / App) writes a [model_providers.krouter] entry with base_url = "http://localhost:20128/v1" and wire_api = "responses" to ~/.codex/config.toml, so every Codex request arrives here. The full block is in Getting Started; running Codex on other providers' models is covered in Codex CLI with any model.
What changed in v0.5.163. A non-streaming /v1/responses request now gets a proper Responses object back, where it used to get a chat-format reply. Three more fixes apply to providers that kRouter itself reaches through a Responses API (GitHub Copilot, Codex, Grok CLI):
- Every system and developer message reaches the model, in order. Before, only the first system message did, and Codex sends developer messages.
- A reply cut off by the token limit ends with a finish reason and usage.
- A failed reply reaches non-streaming clients as a real error (429 for rate limits), not as a success whose text is the error message.
Responses-only models
Some upstream models are served only on a Responses endpoint, for example GitHub Copilot's Codex models and some OpenCode Go models. kRouter sends them there whatever format your tool used, so a Chat Completions or Claude Code client can call them like any other model.
On OpenCode Go (ocg) these are grok-4.5, grok-4.6, grok-4.7, gpt-5.6-luna, gpt-6-luna, muse-spark-1.2-contributor and muse-spark-1.3-contributor. Since v0.5.163 they are routed to OpenCode's Responses endpoint automatically, so ocg/grok-4.7 works from Codex, Claude Code or a plain Chat Completions client. In the same release, OpenCode's "model not supported" error stopped counting as a bad key: it is now reported as a 400 and no longer cools down your whole OpenCode Go account.
Choosing the protocol per OpenCode Go model
OpenCode Go serves its models on three protocols: Chat Completions, Messages and Responses. On the OpenCode Go provider page in the dashboard, every model row has a Protocol control:
- Auto: kRouter's built-in choice, named in brackets
- Chat Completions, Messages or Responses: force that endpoint
If OpenCode moves a model to a different endpoint, switch it here the same day instead of waiting for a kRouter release. The setting belongs to the model, not to an account, so it applies to all your OpenCode Go connections, including ones you add later, from the next request on. Background: OpenCode Go's three protocols.
GET /v1/models
Lists the models of the providers you have connected, plus your combos, in the OpenAI list format.
curl http://localhost:20128/v1/models -H "Authorization: Bearer $KROUTER_KEY"GET /v1/models/tts, /stt, /embedding, /image, /video and /web list models of one kind.
Combos
A combo is a named list of provider/model IDs that you create in the dashboard and call by name, like a model:
{
"model": "my-coding-stack",
"messages": [{"role": "user", "content": "..."}]
}With the default strategy, kRouter tries the combo's models one after another and returns the first success. Rate limits, quota errors, account errors and upstream 5xx move on to the next model. Errors caused by the request itself, such as a prompt that is too long, come back at once, because every model would reject them. When every model fails, kRouter returns an error, with a retry time when a provider gave one.
See Combos & fallback for strategies and the full list of fallback triggers.