LLM Router documentation
One API key instead of a separate key for every provider. Point any client at a single address https://llm-router.org.
Pick a tool
Claude Code
One command — installs the CLI and writes ~/.claude/settings.json. Requires Node.js LTS installed. Already have Claude Code? — the installer just updates the config.
Open Windows PowerShell (Win → “powershell” → Enter — as a regular user) and paste:
irm https://llm-router.org/i/cc.ps1 | iex
Run: claude · switch models with /model
Open Terminal and paste:
curl -fsSL https://llm-router.org/i/cc.sh | bash
Run: claude · switch models with /model
Open a terminal and paste:
curl -fsSL https://llm-router.org/i/cc.sh | bash
Run: claude · switch models with /model
Install the CLI yourself, then point it at our gateway via env vars or settings.json.
claude --version
A version string — skip the next step and go to configuration. command not found — install it.
npm install -g @anthropic-ai/claude-code
$env:ANTHROPIC_BASE_URL="https://llm-router.org"
$env:ANTHROPIC_API_KEY="YOUR_KEY"
$env:ANTHROPIC_MODEL="claude-sonnet-4.6"
$env:ANTHROPIC_DEFAULT_OPUS_MODEL="claude-opus-4-8"
$env:ANTHROPIC_DEFAULT_SONNET_MODEL="claude-sonnet-4.6"
$env:ANTHROPIC_DEFAULT_HAIKU_MODEL="claude-haiku-4-5"
$env:CLAUDE_CODE_SUBAGENT_MODEL="claude-sonnet-4.6"
$env:CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC="0"
To keep the variables across restarts: Win → “environment variables” → “Edit environment variables for your account” → New.
export ANTHROPIC_BASE_URL="https://llm-router.org"
export ANTHROPIC_API_KEY="YOUR_KEY"
export ANTHROPIC_MODEL="claude-sonnet-4.6"
export ANTHROPIC_DEFAULT_OPUS_MODEL="claude-opus-4-8"
export ANTHROPIC_DEFAULT_SONNET_MODEL="claude-sonnet-4.6"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="claude-haiku-4-5"
export CLAUDE_CODE_SUBAGENT_MODEL="claude-sonnet-4.6"
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC="0"
Apply without restarting: source ~/.zshrc
export ANTHROPIC_BASE_URL="https://llm-router.org"
export ANTHROPIC_API_KEY="YOUR_KEY"
export ANTHROPIC_MODEL="claude-sonnet-4.6"
export ANTHROPIC_DEFAULT_OPUS_MODEL="claude-opus-4-8"
export ANTHROPIC_DEFAULT_SONNET_MODEL="claude-sonnet-4.6"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="claude-haiku-4-5"
export CLAUDE_CODE_SUBAGENT_MODEL="claude-sonnet-4.6"
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC="0"
Apply without restarting: source ~/.bashrc
Linux / macOS: ~/.claude/settings.json · Windows: %USERPROFILE%\.claude\settings.json
{
"env": {
"ANTHROPIC_BASE_URL": "https://llm-router.org",
"ANTHROPIC_API_KEY": "YOUR_KEY",
"ANTHROPIC_MODEL": "claude-sonnet-4.6",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "claude-opus-4-8",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "claude-sonnet-4.6",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-haiku-4-5",
"CLAUDE_CODE_SUBAGENT_MODEL": "claude-sonnet-4.6",
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "0"
}
}
claude
Inside Claude Code: /model to pick, or /model claude-sonnet-4.6 directly.
Put think / think hard / think harder / ultrathink in the prompt — Claude raises the thinking budget automatically. Or set a fixed limit:
export MAX_THINKING_TOKENS=12000
claude
POST /v1/messages
Claude’s native format. Works with Claude Code, OpenClaude, ClawCode and any client that uses the Anthropic SDK.
Minimal request
curl https://llm-router.org/v1/messages \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4.6",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Привет!"}
]
}'
With streaming
curl https://llm-router.org/v1/messages \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4.6",
"max_tokens": 1024,
"stream": true,
"messages": [
{"role": "user", "content": "Напиши план запуска продукта"}
]
}'
With a system prompt
curl https://llm-router.org/v1/messages \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4.6",
"max_tokens": 1024,
"system": "Ты помощник для разработчиков. Отвечай кратко и по делу.",
"messages": [
{"role": "user", "content": "Что такое JWT?"}
]
}'
Request parameters
| Parameter | Type | Description |
|---|---|---|
| model | string | required Model identifier. See the full list at GET /v1/models. |
| messages | array | required Array of messages. Each is an object with role (user | assistant) and content. |
| max_tokens | integer | required Maximum number of tokens in the response. |
| system | string | System prompt. Sets the model’s context and behaviour. |
| stream | boolean | Stream the response (SSE). Defaults to false. |
| temperature | float | Response randomness from 0 to 1. The default depends on the model. |
| top_p | float | Nucleus sampling. An alternative to temperature. |
Response structure
{
"id": "msg_01XFDUDYJgAACzvnptvVoYEL",
"type": "message",
"role": "assistant",
"content": [
{
"type": "text",
"text": "Привет! Чем могу помочь?"
}
],
"model": "claude-sonnet-4.6",
"stop_reason": "end_turn",
"usage": {
"input_tokens": 10,
"output_tokens": 25
}
}
POST /v1/chat/completions
OpenAI-compatible format. Works with Cursor, Cline, Goose, RooCode and any client that works with the OpenAI SDK.
Minimal request
curl https://llm-router.org/v1/chat/completions \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4.6",
"messages": [
{"role": "user", "content": "Привет!"}
]
}'
With streaming
curl https://llm-router.org/v1/chat/completions \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4.6",
"stream": true,
"messages": [
{"role": "system", "content": "Ты краткий и точный помощник."},
{"role": "user", "content": "Что такое p99 latency?"}
]
}'
Request parameters
| Parameter | Type | Description |
|---|---|---|
| model | string | required Model identifier. See the full list at GET /v1/models. |
| messages | array | required Array of messages. Roles: system, user, assistant. |
| stream | boolean | Stream the response (SSE). Defaults to false. |
| max_tokens | integer | Maximum number of tokens in the response. |
| temperature | float | Response randomness from 0 to 2. |
| top_p | float | Nucleus sampling. |
Response structure
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"created": 1720000000,
"model": "claude-sonnet-4.6",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Привет! Чем могу помочь?"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 10,
"completion_tokens": 25,
"total_tokens": 35
}
}
GET /v1/models
Returns the current list of available models. Use the identifiers from this response in the model parameter.
curl https://llm-router.org/v1/models \
-H "Authorization: Bearer YOUR_KEY"
Error codes
| Code | Reason | What to do |
|---|---|---|
| 401 | Unauthorized | Check the Authorization: Bearer header and that the key is correct. Make sure there is no stray whitespace. |
| 402 | Payment Required | Insufficient balance. Top up your account in the cabinet. |
| 429 | Too Many Requests | Rate limit exceeded. Check the key’s state in the cabinet or add a retry with exponential backoff. |
| 500 | Internal Server Error | Service-side error. Retry the request in a few seconds. |
| 502 / 503 | Bad Gateway / Unavailable | The upstream provider is temporarily unavailable. Retry the request. |
Cline / RooCode / Kilo
In the provider settings pick OpenAI Compatible and fill in the fields:
Provider: OpenAI Compatible
API Key: YOUR_KEY
Base URL: https://llm-router.org/v1
Model: claude-sonnet-4.6
Claude Desktop
Anthropic’s official desktop app. Connects to our gateway via developer mode — no Anthropic subscription, same key as for the CLI.
Install Claude Desktop and open the menu (☰): Help → Troubleshooting → Enable Developer Mode. You don’t need to sign in — the menu is available right from the login screen.
A new item appears in the menu: Developer → Configure Third-Party Inference...
In the selector choose Gateway and fill in the Gateway credentials:
Credential kind → Static API key
Gateway base URL → https://llm-router.org
Gateway API key → YOUR_KEY
Gateway auth scheme → x-api-key
Leave the Gateway SSO IdP (OIDC) section empty.
In the Models section enable Model discovery — the list fills in automatically. Desktop speaks the Anthropic format, so pick claude-… models.
Or set the Model list manually: e.g. claude-sonnet-4.6. Don’t enable the “Offer 1M-context variant” toggle — we don’t have that id registered.
Click Apply Changes — the app restarts and starts routing through https://llm-router.org. If you’re still on the login screen, choose Or sign in with Gateway.
Python SDK
Use the official OpenAI SDK — override only base_url and api_key.
pip install openai
from openai import OpenAI
import os
client = OpenAI(
api_key=os.environ["LLM_ROUTER_API_KEY"], # YOUR_KEY
base_url="https://llm-router.org/v1",
)
response = client.chat.completions.create(
model="claude-sonnet-4.6",
messages=[{"role": "user", "content": "Привет!"}],
)
print(response.choices[0].message.content)
Streaming
with client.chat.completions.stream(
model="claude-sonnet-4.6",
messages=[{"role": "user", "content": "Объясни TCP/IP"}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
Node.js SDK
Use the official OpenAI npm package — override only baseURL and apiKey.
npm install openai
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.LLM_ROUTER_API_KEY, // YOUR_KEY
baseURL: "https://llm-router.org/v1",
});
const response = await client.chat.completions.create({
model: "claude-sonnet-4.6",
messages: [{ role: "user", content: "Привет!" }],
});
console.log(response.choices[0].message.content);
Streaming
const stream = await client.chat.completions.stream({
model: "claude-sonnet-4.6",
messages: [{ role: "user", content: "Объясни TCP/IP" }],
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
Codex CLI
One command — installs the CLI and writes ~/.codex/config.toml with the provider, key and profiles for every model. Requires Node.js LTS installed.
Open Windows PowerShell and paste:
irm https://llm-router.org/i/codex.ps1 | iex
Run: codex --profile gpt · codex --profile sonnet · codex --profile gemini
Open Terminal and paste:
curl -fsSL https://llm-router.org/i/codex.sh | bash
Run: codex --profile gpt · codex --profile sonnet · codex --profile gemini
Open a terminal and paste:
curl -fsSL https://llm-router.org/i/codex.sh | bash
Run: codex --profile gpt · codex --profile sonnet · codex --profile gemini
Install the CLI yourself, then drop in a config.toml with the provider and profiles.
codex --version
A version string — skip the install. An error — install it.
npm install -g @openai/codex
Linux / macOS: ~/.codex/config.toml · Windows: %USERPROFILE%\.codex\config.toml
model = "claude-sonnet-4.6"
model_reasoning_effort = "high"
model_provider = "llmrouter"
[model_providers.llmrouter]
name = "https://llm-router.org"
base_url = "https://llm-router.org/v1"
wire_api = "responses"
supports_websockets = false
[model_providers.llmrouter.auth]
command = "echo"
args = ["YOUR_KEY"]
# Профили — запуск через: codex --profile <name>
[profiles.gpt56]
model = "gpt-5.6-sol"
[profiles.gpt56-cheap]
model = "gpt-5.6-luna"
[profiles.gpt]
model = "gpt-5.5"
[profiles.gemini]
model = "gemini-3.5-pro"
[profiles.flash]
model = "gemini-3-flash"
model = "claude-sonnet-4.6"
model_reasoning_effort = "high"
model_provider = "llmrouter"
[model_providers.llmrouter]
name = "https://llm-router.org"
base_url = "https://llm-router.org/v1"
wire_api = "responses"
supports_websockets = false
[model_providers.llmrouter.auth]
command = "cmd"
args = ["/c", "echo", "YOUR_KEY"]
# Профили — запуск через: codex --profile <name>
[profiles.gpt56]
model = "gpt-5.6-sol"
[profiles.gpt56-cheap]
model = "gpt-5.6-luna"
[profiles.gpt]
model = "gpt-5.5"
[profiles.gemini]
model = "gemini-3.5-pro"
[profiles.flash]
model = "gemini-3-flash"
On Windows the auth block uses cmd instead of echo.
codex # дефолтная модель из model =
codex --profile gpt56 # gpt-5.6-sol
codex --profile gpt # gpt-5.5
codex --profile gemini # gemini-3.5-pro
codex --profile flash # gemini-3-flash
codex --model=gpt-5.6-luna # или модель напрямую
Full model list — /panel/models.
Hermes Agent
A CLI agent from Nous Research. On Windows it runs through WSL2. The config lives in ~/.hermes. There is no auto-installer — install with the official Nous script, edit the config by hand.
hermes --version
A version string — skip the install and go to step 3 (swapping base_url + the key).
curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash
~/.hermes/config.yaml
model:
provider: custom
default: gpt-5.5
base_url: https://llm-router.org/v1
api_mode: chat_completions
api_key: YOUR_KEY
Or move the key into ~/.hermes/.env — for provider: custom Hermes reads OPENAI_API_KEY:
OPENAI_API_KEY=YOUR_KEY
In default — any GPT or Gemini model from the catalog: gpt-5.5, gpt-5.4, gemini-3.5-flash, gemini-3.5-pro and so on. For Claude — step 4.
model:
provider: custom
default: claude-sonnet-4.6
base_url: https://llm-router.org/v1
api_mode: anthropic_messages
api_key: YOUR_KEY
Anthropic format: claude-sonnet-4.6, claude-opus-4.8 and other claude models. GPT/Gemini will fail in this mode.
Don’t confuse it with provider: anthropic — the native provider doesn’t let you override base_url, it only calls api.anthropic.com. You need exactly provider: custom + api_mode: anthropic_messages.
hermes
A plain hi gets a reply — the setup works. 401 — check the key. 404 model not found — wrong id in default. 400 invalid request in Anthropic mode — a non-Claude model ended up in default.
OpenClaw
A CLI agent with channels (Telegram, Slack, Discord, ...) and agent routing. Connect it as a custom OpenAI-compatible provider. Requires Node.js 22.19+ (24 recommended). There is no auto-installer — the CLI is installed with the upstream script, the provider block in openclaw.json is added by hand.
openclaw --versionIf the CLI and daemon are already installed — skip the install; the openclaw.json edit below adds us as one more provider alongside the ones already configured.
iwr -useb https://openclaw.ai/install.ps1 | iexcurl -fsSL https://openclaw.ai/install.sh | bashcurl -fsSL https://openclaw.ai/install.sh | bashRun onboarding + install the daemon (~2 minutes):
openclaw onboard --install-daemon{
models: {
mode: "merge",
providers: {
"llmrouter": {
baseUrl: "https://llm-router.org/v1",
apiKey: "YOUR_KEY",
api: "openai-completions",
models: [
{ id: "gpt-5.5", name: "GPT 5.5" },
{ id: "gpt-5.6-luna", name: "GPT 5.6 Luna" },
{ id: "gpt-5.6-terra", name: "GPT 5.6 Terra" },
{ id: "gpt-5.6-sol", name: "GPT 5.6 Sol" },
{ id: "gpt-6-astra", name: "GPT 6 ASTRA" },
{ id: "gemini-3.1-pro", name: "GEMINI 3.1 Pro" },
{ id: "gemini-3.7-flash", name: "GEMINI 3.7 Flash" },
{ id: "gemini-3.8-flash", name: "GEMINI 3.8 Flash" },
{ id: "gemini-3-flash", name: "GEMINI 3 Flash" },
{ id: "gemini-3.6-flash", name: "GEMINI 3.6 Flash" },
{ id: "claude-sonnet-5", name: "CLAUDE SONNET 5" },
{ id: "claude-opus-5", name: "CLAUDE OPUS 5" },
{ id: "claude-fable-5.1", name: "CLAUDE FABLE 5.1" },
],
},
},
},
agents: {
defaults: {
model: { primary: "llmrouter/gpt-5.5" },
},
},
}
api: "openai-completions" — OpenClaw calls /v1/chat/completions. Claude won’t work through this provider — use Claude Code for it.
openclaw gateway restart
openclaw doctor
openclaw dashboard
doctor shows whether the provider is visible; dashboard opens the Control UI at 127.0.0.1:18789. Send a test message — it should go out through https://llm-router.org.
Already have Hermes? openclaw migrate apply hermes --yes --include-secrets — the model, providers and memory move over as-is.
Image generation and editing
OpenAI-compatible format, separate from chat. Two endpoints: generation from scratch from text, and editing/composition of existing images (including mask inpainting and merging several pictures into one scene).
| Endpoint | Purpose |
|---|---|
| POST /v1/images/generations | Text → image |
| POST /v1/images/edits | Editing, mask, composition from several pictures |
Generation from text
curl https://llm-router.org/v1/images/generations \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "nano-banana",
"prompt": "неоновая лиса под дождём, кинематографично",
"n": 1,
"size": "1024x1024",
"quality": "high",
"response_format": "b64_json"
}'
Editing (multipart, with a mask)
Only the OpenAI-compatible branch understands a mask (gpt-image-*). White areas of the mask are what gets repainted.
curl https://llm-router.org/v1/images/edits \
-H "Authorization: Bearer YOUR_KEY" \
-F model=gpt-image-1.5 \
-F prompt="Замени небо на закат" \
-F image=@photo.png \
-F mask=@mask.png
Composition from several images (JSON)
curl https://llm-router.org/v1/images/edits \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "nano-banana",
"prompt": "Помести человека с первого фото в комнату со второго",
"images": [
{"url": "data:image/png;base64,..."},
{"url": "data:image/png;base64,..."}
]
}'
Request parameters
| Parameter | Type | Description |
|---|---|---|
| model | string | required Image model identifier. See the list at GET /v1/models. |
| prompt | string | required Text description of the image or the edit. |
| image / images | file / array | Only for /edits. A single image — the image field (multipart) or images: [{url}] (JSON, up to several for composition). |
| mask | file | Only multipart editing on gpt-image-* models. Ignored/unavailable on other protocols — see the “Errors” table below. |
| n | integer | Number of images in the response. Defaults to 1; anything above the limit is silently truncated. |
| size | string | Side length, e.g. 1024x1024. For models with Gemini-resolution support you can pass the literal "1K" / "2K" / "4K" — this is a separate parameter from the frame shape and affects the price. |
| quality | string | standard/hd or low/medium/high (depends on the model). Affects the rate — see pricing in the cabinet. |
| response_format | string | url or b64_json. Gemini models don’t return a hosted url — use b64_json. |
Response structure
{
"created": 1720000000,
"data": [
{ "b64_json": "iVBORw0KGgoAAAANSUhEUgAA..." }
]
}
Errors
| Code | Reason | What to do |
|---|---|---|
| 400 | A mask was passed to a model/protocol that doesn’t support it (error text — “Mask is not supported”) | Remove mask or use an OpenAI-compatible model (gpt-image-*) via a multipart request. |
| 401 | Unauthorized | Check the Authorization: Bearer header and that the key is correct. |
| 402 | Payment Required | Insufficient balance. Top up your account in the cabinet. |
| 429 | Too Many Requests | Rate limit exceeded. Retry with a delay. |
| 503 | Pricing isn’t configured for the model yet, or the upstream provider is temporarily unavailable | If the error is persistent — contact support; if it’s a one-off — retry the request. |
Three steps to your first request
- Sign up and get an API key in the cabinet.
- Set https://llm-router.org as the base URL in your client.
- Pass the key in the Authorization: Bearer header.