Use ZergRouter
Connect coding agents, apps, and OpenAI-compatible clients to the models in your personal Router through one authenticated endpoint.
Quickstart
Sign in with ZergAI. ZergAI verifies your identity; ZergRouter creates and owns your personal Router account automatically. Open Credentials, add a provider credential, and create a Router API key. The full key is displayed once; keep it in a password manager or secret store.
export ZERGROUTER_API_KEY="paste-your-router-key"# cURL — non-streaming
curl https://zergrouter.com/v1/chat/completions \
-H "Authorization: Bearer $ZERGROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-20250514",
"messages": [{"role": "user", "content": "Say hi"}]
}'# cURL — streaming
curl https://zergrouter.com/v1/chat/completions \
-H "Authorization: Bearer $ZERGROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Say hi"}],
"stream": true
}'# Python — openai SDK (point at zergrouter)
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["ZERGROUTER_API_KEY"],
base_url="https://zergrouter.com/v1",
)
resp = client.chat.completions.create(
model="claude-sonnet-4-20250514",
messages=[{"role": "user", "content": "Say hi"}],
)
print(resp.choices[0].message.content)// npm install ai @ai-sdk/openai-compatible
// JS — Vercel AI SDK
import { createOpenAICompatible } from '@ai-sdk/openai-compatible'
import { generateText } from 'ai'
const zergrouter = createOpenAICompatible({
name: 'zergrouter',
apiKey: process.env.ZERGROUTER_API_KEY,
baseURL: 'https://zergrouter.com/v1',
})
const { text } = await generateText({ model: zergrouter('claude-sonnet-4-20250514'), 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.
Router API keys are bound to your personal Router. ZergAI JWTs remain available for trusted internal integrations. 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.
ZTC
Hosted ZTC
Sign in and open ZTC in the dashboard to create a durable private coding thread. ZergRouter creates and manages your personal routing scope automatically; you do not need to choose or create a ZergAI workspace. Each thread keeps its conversation, settings, and isolated filesystem together across browser sessions. The primary provider and model are immutable; choosing another route creates a fork with copied history and filesystem state.
Threads start with ask-before-mutation permissions. You can change the reasoning effort, output limit, permission profile, and thread instructions in the settings rail. Idle sandboxes suspend automatically, archived threads retain their workspace, and trashed threads remain recoverable for seven days.
When you choose Codex subscription, the picker shows only models for which your connected accounts have fresh usable quota. ZergRouter selects an account before the turn using the model's quota window, remaining capacity, next reset, and least-recent routing. Credentials stay in the outbound broker; filesystem and command tools run in the private thread sandbox through the normal ZTC approval path.
Local ZTC
Zerg Terminal Code can use ZergRouter through its OpenAI-compatible direct mode. Install ZTC, choose a model available to your personal Router, and pass the Router key only to the launched process.
npm install --global zerg-ztc@latest
ZTC_LLM_AUTH_MODE=direct \
ZTC_PROVIDER=openai_compatible \
ZTC_MODEL=gpt-5.6 \
OPENAI_COMPAT_BASE_URL=https://zergrouter.com/v1 \
OPENAI_COMPAT_API_KEY="$ZERGROUTER_API_KEY" \
ztcUse the authenticated GET /v1/models endpoint to choose a model from your personal Router. This direct setup uses standard OpenAI-compatible streaming and does not require a separate ZTC login.
Codex CLI
Codex custom providers use the Responses API. Install Codex, then add this provider to ~/.codex/config.toml:
curl -fsSL https://chatgpt.com/codex/install.sh | sh
# ~/.codex/config.toml
model = "gpt-5.6"
model_provider = "zergrouter"
[model_providers.zergrouter]
name = "ZergRouter"
base_url = "https://zergrouter.com/v1"
env_key = "ZERGROUTER_API_KEY"
wire_api = "responses"codexChoose a model returned by authenticated GET /v1/models?capability=codex_responses. ZergRouter currently advertises only compatible OpenAI Responses models to this client.
Pi
Install Pi, then merge a ZergRouter provider into ~/.pi/agent/models.json rather than replacing your existing providers:
npm install --global --ignore-scripts @earendil-works/pi-coding-agent{
"providers": {
"zergrouter": {
"baseUrl": "https://zergrouter.com/v1",
"api": "openai-completions",
"apiKey": "$ZERGROUTER_API_KEY",
"authHeader": true,
"compat": { "supportsDeveloperRole": false },
"models": [
{ "id": "gpt-5.6", "name": "GPT-5.6" }
]
}
}
}Launch pi and select zergrouter/gpt-5.6. Add only models listed for your personal Router.
OpenCode
Install OpenCode, then add a custom OpenAI-compatible provider to ~/.config/opencode/opencode.json (or a project-local opencode.json):
curl -fsSL https://opencode.ai/install | bash{
"$schema": "https://opencode.ai/config.json",
"model": "zergrouter/gpt-5.6",
"provider": {
"zergrouter": {
"npm": "@ai-sdk/openai-compatible",
"name": "ZergRouter",
"options": {
"baseURL": "https://zergrouter.com/v1",
"apiKey": "{env:ZERGROUTER_API_KEY}"
},
"models": {
"gpt-5.6": { "name": "GPT-5.6" }
}
}
}
}ZERGROUTER_API_KEY="$ZERGROUTER_API_KEY" opencodeOther OpenAI-compatible clients
Set the client's base URL to https://zergrouter.com/v1, provide your Router key as a bearer token, and select a model from authenticated GET /v1/models. Use /v1/chat/completions for compatible chat clients and /v1/responses only when the client and selected model support Responses.
Model access is personal-Router-specific. Do not hard-code a provider key into client configuration; clients receive only the revocable Router key.
Codex accounts and routing
ZergRouter deliberately separates three Codex workflows:
- Hosted personal subscription: OpenAI device-code sign-in runs in an isolated outbound broker. Credentials are encrypted with a broker-only key and remain unactivated until the same Zerg identity confirms them. Hosted ZTC can route turns through eligible accounts without sending credentials into the thread sandbox.
- Local personal subscription: credentials remain inside an isolated
CODEX_HOMEon your machine. The local worker sends only availability snapshots. - Personal Router API routing: Codex uses ZergRouter's Responses endpoint and your encrypted, explicitly ordered API credential pool.
Add a hosted personal account
Open My Codex and choose Add Codex account (or Add another Codex account when one is already connected). Open the exact https://auth.openai.com/codex/device page in a private window or a different browser profile, sign in to the account you intend to add, and enter the displayed one-time code. Opening it in your current browser can reuse the OpenAI account already signed in there. Return to ZergRouter and explicitly add the verified identity. If that identity is already connected, ZergRouter changes nothing and asks you to try a different account. Use Reconnect account on an existing account card when you intend to refresh that account’s credentials instead. For hosted accounts, the owning signed-in Zerg identity sees the exact OpenAI email so multiple accounts remain distinguishable; it is encrypted at rest and never exposed to Router keys or other identities. Local-device snapshots continue to upload only a masked identity. The dashboard also shows plan, rate-limit windows, aggregate usage, reset times, and snapshot freshness. Manual selection remains a dashboard preference; Hosted ZTC routing independently chooses an eligible owner account for each new turn and fails over only before any output or tool execution begins.
Router CLI preview
The separate zrouter management CLI is not publicly distributed yet. The public Codex setup above uses a personal Router API key and does not depend on that preview CLI. Existing internal users can continue to pair an approved build with zrouter login and zrouter agent install.
Use a personal account locally
zrouter codex account add --label "Company Business"
zrouter codex account list
zrouter codex account use <account-label>
zrouter codex -- --model gpt-5.6The selected account is explicit. If it is unavailable, the command reports the other account states but does not switch or replay the session.
Use your personal Router API pool
zrouter codex configure --model gpt-5.6
codex --profile zergrouterThe generated Codex 0.146+ layer lives at $CODEX_HOME/zergrouter.config.toml and leaves the base config.toml under user control. It uses https://zergrouter.com/v1, the Responses wire API, and zrouter auth token as command-backed bearer authentication. GET /v1/models?capability=codex_responses lists the models advertised to Codex.
Custody and availability
Local personal-account credentials never leave their device. Hosted personal-account credentials are stored only as a versioned AES-256-GCM envelope bound to the Zerg identity, account, and credential record; the web process has no vault key. Each broker operation uses a fresh private CODEX_HOME and removes it afterward. Revocation immediately disables and deselects the account, requests logout, and removes the ciphertext from the live database through a bounded reaper. This is logical deletion rather than per-account cryptographic erasure: encrypted copies can remain in database WAL or backups until their configured retention expires because accounts share the deployment vault key. Account state is fresh for 15 minutes and then shown as stale. Identity-bound CLI sessions expire after 90 days; inspect them with zrouter auth status, pair again with zrouter login, or revoke a lost device from My Codex. Router keys cannot access personal subscription accounts, and no superuser bypass exists. Personal Router credentials report whether availability was supplied by the provider or inferred from observed traffic; no exact balance is invented when the provider exposes none.
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": "claude-sonnet-4-20250514",
"messages": [...],
"route": {
"fallbacks": ["gpt-4o", "gemini-2.0-flash"],
"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
Public catalog preview. The entries below come from /api/public/models and show the active platform registry, not credential availability for your personal Router.
Loading catalog…
After signing in, retrieve the exact models available to your personal Router with an authenticated request:
curl https://zergrouter.com/v1/models \
-H "Authorization: Bearer $ZERGROUTER_API_KEY"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.POST /v1/images/generations— OpenAI-compatible image generation.POST /v1/audio/speech— OpenAI-compatible text-to-speech.POST /v1/audio/transcriptions— OpenAI-compatible multipart transcription.POST /llm/chat/POST /llm/embed— compact ZergRouter aliases.GET /v1/models— authenticated list of models available to your personal Router.GET /api/dashboard/usage— your personal Router'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.GET /api/dashboard/codex-devices— list active CLI devices paired to your personal Router.DELETE /api/dashboard/codex-devices/[id]— revoke a managed CLI device, its sessions, and its telemetry.