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

StatusMeaning
400Missing model / malformed body / no API key configured.
401Bearer missing, invalid, or revoked.
403Scope missing on the bearer.
404Resource not found (provider, model, key).
429Quota or daily budget exceeded.
5xxUpstream 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.