ZergRouter API
An OpenAI-compatible proxy across Anthropic, OpenAI, Gemini, DeepSeek, Kimi — with fallback chains, cost accounting, and a generations audit log.
Quickstart
Mint a key at /dashboard/keys. Use it as a standard OpenAI Authorization: Bearer ….
# cURL — non-streaming
curl https://zergrouter.fly.dev/v1/chat/completions \
-H "Authorization: Bearer sk-zr-…" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-5",
"messages": [{"role": "user", "content": "Say hi"}]
}'# cURL — streaming
curl https://zergrouter.fly.dev/v1/chat/completions \
-H "Authorization: Bearer sk-zr-…" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Say hi"}],
"stream": true
}'# Python — openai SDK (point at zergrouter)
from openai import OpenAI
client = OpenAI(api_key="sk-zr-…", base_url="https://zergrouter.fly.dev/v1")
resp = client.chat.completions.create(
model="claude-sonnet-4-5",
messages=[{"role": "user", "content": "Say hi"}],
)
print(resp.choices[0].message.content)// JS — Vercel AI SDK
import { openai } from '@ai-sdk/openai'
import { generateText } from 'ai'
const provider = openai({ apiKey: 'sk-zr-…', baseURL: 'https://zergrouter.fly.dev/v1' })
const { text } = await generateText({ model: provider('claude-sonnet-4-5'), prompt: 'Say hi' })Authentication
Two bearer formats are accepted:
sk-zr-…— Router API keys, minted from the dashboard. SHA-256 hashed in storage; the full secret is shown once at creation and again on rotate.eyJ…— JWTs from the ZergAI bridge. Used by web UIs and internal services.
Both keys carry a workspace context. Use Authorization: Bearer … or X-Api-Key: … on every request.
Scopes
Router keys default to ['chat:write', 'models:read', 'usage:read']. Configure per-key on mint.
Daily budgets
Set daily_budget_usd on a key to cap UTC-daily spend. Requests over budget return 429 with Daily budget exceeded.
Streaming
Pass "stream": true in the request body. Responses use Server-Sent Events; clients should parse data: lines and stop on data: [DONE].
Regardless of which upstream answers (Anthropic, Gemini, OpenAI), the proxy normalizes events to the OpenAI chat-completion-chunk shape:
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","model":"…","choices":[{"index":0,"delta":{"role":"assistant","content":"Hi"},"finish_reason":null}]}
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","model":"…","choices":[{"index":0,"delta":{"content":" there"},"finish_reason":null}]}
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","model":"…","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":12,"completion_tokens":2,"total_tokens":14}}
data: [DONE]Tool calls stream as OpenAI tool_calls deltas — Anthropic tool_use blocks and Gemini functionCall parts are translated automatically.
Smart routing
Attach a route field to enable fallback chains. The primary model is tried first; on 5xx / 429 / 408 / network error the next chain entry is tried. Caller-side 4xx (other than 429) short-circuits.
{
"model": "anthropic/claude-3-5-sonnet",
"messages": [...],
"route": {
"fallbacks": ["openai/gpt-4o", "openai/gpt-4o-mini"],
"allow_fallbacks": true
}
}Streaming requests do not retry once bytes have been sent. The activity feed at /admin/generations records the planned chain plus which attempt served.
Errors
| Status | Meaning |
|---|---|
400 | Missing model / malformed body / no API key configured. |
401 | Bearer missing, invalid, or revoked. |
403 | Scope missing on the bearer. |
404 | Resource not found (provider, model, key). |
429 | Quota or daily budget exceeded. |
5xx | Upstream error — triggers fallback retry if a chain is set. |
Error bodies follow Nuxt's {statusCode, statusMessage} shape. Upstream payloads pass through unchanged when the route reaches the provider.
Models
Loading catalog…
Endpoints
POST /v1/chat/completions— OpenAI chat completions. Supports streaming +route.POST /v1/messages— Anthropic Messages API (native passthrough).POST /v1/responses— OpenAI Responses API (passthrough).POST /v1/embeddings— OpenAI embeddings.GET /v1/models— list available models for the workspace.GET /api/dashboard/usage— your workspace's usage rollup.GET /api/dashboard/keys— list your router API keys.POST /api/dashboard/keys— mint a new key (one-time secret reveal).POST /api/dashboard/keys/[id]/rotate— rotate a key in place.DELETE /api/dashboard/keys/[id]— revoke a key.