API Documentation
One key, one base URL — every model. Set base_url to https://api.routeall.ai/v1, swap in your sk-ra- key, and your existing OpenAI SDK code runs against every supported model.
https://api.routeall.ai/v1·Keysk-ra-...Introduction
RouteAll exposes one unified, OpenAI-compatible API in front of many upstream providers (OpenAI, Anthropic, Gemini, DeepSeek and more). You never juggle per-provider keys or endpoints: pick any model from the marketplace, call it by its canonical name through the same base URL, and requests are routed by priority, weight and health with automatic failover. Prefer the Anthropic or Gemini SDKs? Native-format endpoints are built in too.
Authentication
Create an API key in Console → API Keys (shown once, prefixed sk-ra-). Send it as a Bearer token in the Authorization header. One key works for every model and every endpoint format. Keys are scoped to your account and user group; never embed them in client-side code.
Authorization: Bearer sk-ra-your-keyThree-line integration
Point your OpenAI SDK base_url at https://api.routeall.ai/v1 and set api_key to your key — that is the whole migration. Then call /v1/chat/completions exactly as you would with OpenAI, switching models by name only.
curl https://api.routeall.ai/v1/chat/completions \
-H "Authorization: Bearer sk-ra-..." \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-v4-pro",
"messages": [{"role": "user", "content": "Hello"}]
}'Connect your tools
Most AI tools let you point at a custom endpoint, and RouteAll fits two ways: an OpenAI-compatible base URL (works with the vast majority of clients, IDEs and CLIs) or an Anthropic-compatible endpoint (for Claude Code and other Claude-format CLIs). One sk-ra- key works for both — set the values below, then use the per-tool notes for where each app hides its endpoint setting. Any tool that accepts a custom OpenAI- or Anthropic-compatible API works, even if it is not listed.
OpenAI-compatible
Base URL https://api.routeall.ai/v1
API key sk-ra-...
Model deepseek-v4-pro (or any name from the marketplace)Anthropic · Claude Code & co.
export ANTHROPIC_BASE_URL="https://api.routeall.ai"
export ANTHROPIC_AUTH_TOKEN="sk-ra-..."
# then use a Claude model, e.g. claude-sonnet-4-6Set env ANTHROPIC_BASE_URL + ANTHROPIC_AUTH_TOKEN, then run claude — or manage it with CC-Switch.
Add a Custom provider (Base URL https://api.routeall.ai + key); it writes the config for Claude Code / Codex / OpenCode / Hermes.
Point it at the Anthropic endpoint (ANTHROPIC_BASE_URL / AUTH_TOKEN), or manage it via CC-Switch.
In ~/.openclaw/openclaw.json add a provider — OpenAI mode (baseUrl …/v1) or Claude-native (baseUrl without /v1).
API Provider → "OpenAI Compatible" → Base URL https://api.routeall.ai/v1, API Key, Model ID.
In opencode.json add a custom provider (@ai-sdk/openai-compatible) with options.baseURL = https://api.routeall.ai/v1.
Add a custom OpenAI-compatible provider (apiKey + baseURL https://api.routeall.ai/v1 + model) in its config.
Settings → Model Services → + Add → API Host https://api.routeall.ai, paste key, then add model IDs.
Settings → add a custom OpenAI-compatible backend → Base URL https://api.routeall.ai/v1 + key.
Add an "OpenAI Compatible" provider → Base URL https://api.routeall.ai/v1 + key + model.
Via an AI plugin (Copilot / Text Generator / Smart Composer) — set its custom OpenAI base URL to https://api.routeall.ai/v1 + key.
In .workbuddy/models.json add a model (vendor OpenAI) with url https://api.routeall.ai/v1/chat/completions + key.
Copilot CLI supports OpenAI-compatible BYOK endpoints; the VS Code extension has no arbitrary base URL — use Cline there.
TRAE restricts to a fixed provider list (no custom base URL) — use a proxy, or the trae-agent CLI which accepts base_url.
Closed product (Tencent ima) — no custom API endpoint; not connectable.
Endpoints by task
RouteAll is not one endpoint — capabilities are split into task-specific routes, and your single sk-ra- key works on all of them. Text (chat) and embeddings are synchronous, OpenAI-compatible calls. Image, video and audio generation are different: they run as asynchronous jobs — you submit a request, then poll for the result. Text-to-speech and speech-to-text have their own OpenAI-style audio endpoints. So no: generating an image, video or voice does not use the same endpoint as chat completions or embeddings. The table below maps each task to its endpoint.
| Task | Endpoint | Style |
|---|---|---|
| Chat / LLM | POST /v1/chat/completions | sync · stream |
| Embeddings | POST /v1/embeddings | sync |
| Image / Video / Audio | POST /v1/generations → GET /v1/generations/{id} | async · poll |
| Text-to-speech | POST /v1/audio/speech | sync · bytes |
| Speech-to-text | POST /v1/audio/transcriptions | sync · multipart |
| Web search | POST /v1/web-search | sync |
| Anthropic native | POST /v1/messages | sync · stream |
| Gemini native | POST /v1beta/models/{m}:generateContent | sync · stream |
| List models | GET /v1/models | sync |
Chat completions
/v1/chat/completionsPOST /v1/chat/completions is request-for-request identical to OpenAI. Pass a model name (a unified canonical name routed to whichever upstream can serve it) and a messages array.
curl https://api.routeall.ai/v1/chat/completions \
-H "Authorization: Bearer sk-ra-..." \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-v4-pro",
"messages": [{"role": "user", "content": "Hello"}]
}'Streaming
/v1/chat/completions (stream)Set stream: true to receive Server-Sent Events. Each event is an OpenAI-style chunk with a delta; the stream ends with data: [DONE]. Billing settles on the actually produced tokens.
stream = client.chat.completions.create(
model="deepseek-v4-pro",
messages=[{"role": "user", "content": "Hello"}],
stream=True,
)
for chunk in stream:
print(chunk.choices[0].delta.content or "", end="")Native Anthropic & Gemini
/v1/messages · /v1beta/...Already using the Anthropic or Gemini SDK? Call POST /v1/messages (Anthropic Messages) or POST /v1beta/models/{model}:generateContent (Gemini) and keep your existing code — the gateway converts to/from the internal format and bills the same way.
Anthropic · /v1/messages
from anthropic import Anthropic
client = Anthropic(base_url="https://api.routeall.ai", api_key="sk-ra-...")
msg = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=256,
messages=[{"role": "user", "content": "Hello"}],
)
print(msg.content[0].text)Gemini · /v1beta
curl "https://api.routeall.ai/v1beta/models/gemini-1.5-pro:generateContent" \
-H "x-goog-api-key: sk-ra-..." -H "Content-Type: application/json" \
-d '{"contents":[{"role":"user","parts":[{"text":"Hello"}]}]}'Embeddings
/v1/embeddingsPOST /v1/embeddings is OpenAI-compatible. Send a model and input (a string or an array of strings); the response is data:[{embedding:[...]}] plus usage. Billed per input token. Use it for search, RAG and clustering — it is a different endpoint from chat completions.
curl https://api.routeall.ai/v1/embeddings \
-H "Authorization: Bearer sk-ra-..." \
-H "Content-Type: application/json" \
-d '{
"model": "text-embedding-v3",
"input": ["The quick brown fox", "jumps over the lazy dog"]
}'Image, video & audio generation
/v1/generations → GET /v1/generations/{id}Generation models run as asynchronous jobs, so the flow differs from chat. POST /v1/generations with a model and prompt (plus modality fields like duration for video, size for image, or text + voice for speech) returns { id, status:"queued" } immediately. Poll GET /v1/generations/{id}: it returns "processing" while in-flight, then a terminal status — "succeeded" (read result_url, a permanent link on our own storage that does not expire), or "failed" / "timed_out" / "canceled". Cancel an in-flight job with POST /v1/generations/{id}/cancel (the hold is refunded). Generation is billed per call: per image, per second of video, or per character of speech (header X-RouteAll-Usage-Calls). The legacy path /v1/video/generations still works for every modality.
# 1) Submit a generation job (image / video / audio model)
curl https://api.routeall.ai/v1/generations \
-H "Authorization: Bearer sk-ra-..." -H "Content-Type: application/json" \
-d '{"model": "viduq2", "prompt": "A paper boat drifting down a stream", "duration": 4}'
# -> {"id": "1234", "status": "queued"}
# 2) Poll until done, then read the permanent result_url
curl https://api.routeall.ai/v1/generations/1234 -H "Authorization: Bearer sk-ra-..."
# -> {"id":"1234","status":"succeeded","result_url":"https://.../v.mp4","charge":"225000"}Text-to-speech & speech-to-text
/v1/audio/speech · /v1/audio/transcriptionsAudio has dedicated OpenAI-style endpoints. Text-to-speech: POST /v1/audio/speech with a model, input text and voice returns the audio bytes (wav or mp3) — audio-capable models also accept the OpenAI omni-audio shape on /v1/chat/completions. Speech-to-text: POST /v1/audio/transcriptions as multipart/form-data with a file and model returns { text }. TTS bills per character; ASR bills per token.
Text-to-speech · /v1/audio/speech
curl https://api.routeall.ai/v1/audio/speech \
-H "Authorization: Bearer sk-ra-..." -H "Content-Type: application/json" \
-d '{"model": "qwen3-tts-flash", "input": "Hello from RouteAll", "voice": "Cherry", "response_format": "mp3"}' \
--output speech.mp3Speech-to-text · /v1/audio/transcriptions
curl https://api.routeall.ai/v1/audio/transcriptions \
-H "Authorization: Bearer sk-ra-..." \
-F file=@audio.mp3 \
-F model=qwen3-asr-flash
# -> {"text": "transcribed text ..."}Parameters
Common parameters: temperature (0–2), top_p (0–1), max_tokens, stop. Support varies by model — reasoning models may ignore temperature; vision models accept image parts. Unknown parameters are passed through to the upstream where safe.
Pricing: per-token, cache & per-call
Most models bill per token. When an upstream serves cached input tokens, they are billed at the model’s cache-read rate (cache creation at the cache-write rate) — header X-RouteAll-Usage-Cached-Tokens reports the hit count. Reasoning models that emit thinking tokens bill those at the model’s reasoning rate (or the output rate when none is set); your usage page reports reasoningTokens. Some models also bill per call: image generation charges per image (POST /v1/images/generations, header X-RouteAll-Usage-Calls), and web_search-style tools add a per-search fee on top of tokens. Your price = official price × your user-group multiplier; cost is never exposed.
X-RouteAll-Usage-Prompt: 972
X-RouteAll-Usage-Cached-Tokens: 896
X-RouteAll-Charge-Credit: 74Errors
Errors use the OpenAI envelope: { "error": { "type", "message", "code" } }. 401 = bad/missing key, 402 = insufficient balance, 429 = rate limited, 503 = no available channel. Retryable upstream errors fail over silently.
{ "error": { "type": "insufficient_balance", "message": "Insufficient balance", "code": 402 } }Rate limits
Requests are rate-limited per API key (requests per minute). Exceeding the limit returns 429 in OpenAI style. Keep concurrency reasonable and back off on 429.