# ZRouter documentation > ZRouter is a Super Intelligence Router: one OpenAI- and Anthropic-compatible endpoint that scores each AI request by difficulty and routes it to the right model and provider. This site is the machine-readable index of ZRouter's public product and API documentation. Model requests need an account API key and account management needs an MCP token or OAuth sign-in. A person creates the account, buys credit, and issues keys. This site grants no access to accounts or data. --- Source: https://agents.zrouter.si/docs/quickstart.md # Quick start A person completes steps 1 to 3. An agent can do steps 4 to 6 once it has an API key. 1. **Create an account** at https://zrouter.si/login?mode=signup with email and password (12 to 72 bytes), Google, or GitHub. Email sign-ups confirm their address first. New accounts start with $0 credit. 2. **Fund requests.** Buy $5 or more of prepaid USD credit under **Billing & credits** (Stripe Checkout), or save a provider key under **Bring your own keys** (see [BYOK](/docs/byok.md)). 3. **Create an account API key** under **API keys**. The secret is shown once. Give it to the agent through an environment variable such as `ZROUTER_API_KEY`. 4. **Pick a model.** Call `GET https://zrouter.si/v1/models` and use an `id` from the response, such as `PROVIDER_INSTANCE/MODEL_ID` or a virtual model name. 5. **Send a request:** ```bash curl https://zrouter.si/v1/chat/completions \ -H "Authorization: Bearer $ZROUTER_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "PROVIDER_INSTANCE/MODEL_ID", "messages": [{"role": "user", "content": "Hello"}], "max_tokens": 256}' ``` 6. **Check usage** with `GET https://zrouter.si/v1/usage`, or in the dashboard. The credit ledger is the source of truth for charges. Next: [Authentication](/docs/authentication.md) --- Source: https://agents.zrouter.si/docs/authentication.md # Authentication ZRouter has three credentials. Each does one job. | Credential | Used for | Created in | Header | | --- | --- | --- | --- | | Account API key | Model requests on `/v1/*` | Dashboard **API keys**, `zctl`, or MCP `api_keys_create` | `Authorization: Bearer ` (Anthropic SDKs may send `x-api-key`) | | MCP token, or MCP OAuth sign-in | Account management through `https://zrouter.si/mcp` | Dashboard **CLI and MCP access** | `Authorization: Bearer ` | | Provider key (BYOK) | Paying a provider directly | Dashboard **Bring your own keys** | Never sent by the client. Add `X-ZRouter-BYOK: true` to use it | Rules for agents: - An account API key cannot manage the account, open the dashboard, or act as an operator. An MCP token cannot send model requests. - MCP tokens expire after 30 days. MCP clients that support OAuth need only the server URL. - Agents cannot create accounts or buy credit. Both need a person. - Never print, log, or commit any of these secrets. A key created through MCP appears in the tool result, so treat the conversation history as sensitive. Next: [API reference](/docs/api.md) --- Source: https://agents.zrouter.si/docs/api.md # API reference Base URL for OpenAI SDKs and raw HTTP: `https://zrouter.si/v1`. Base URL for Anthropic SDKs: `https://zrouter.si` (the SDK appends `/v1/messages`). Machine-readable spec: [/openapi.json](/openapi.json). | Method | Path | Purpose | | --- | --- | --- | | GET | `/v1/models` | Models available to this account, including its virtual models | | GET | `/v1/usage` | Usage aggregates for this account | | POST | `/v1/chat/completions` | OpenAI Chat Completions (text) | | POST | `/v1/responses` | OpenAI Responses (text) | | POST | `/v1/messages` | Anthropic Messages (text) | | POST | `/v1/messages/count_tokens` | Count input tokens, no credit charge | | POST | `/v1/embeddings` | Text embeddings | | POST | `/v1/images/generations`, `/v1/images/edits` | Images, charged per image or image token | | POST | `/v1/audio/speech` | Text to speech, charged per character or second | | POST | `/v1/audio/transcriptions`, `/v1/audio/translations` | Speech to text, charged per second of audio | | POST, GET, DELETE | `/v1/videos`, `/v1/videos/{id}`, `/v1/videos/{id}/content`, `/v1/videos/{id}/remix` | Video jobs on Veo or Sora, charged per second of finished video. Failed jobs are free | ## Supported - Client-executed function tools with inline text tool results on chat, Responses, and Messages. Send the complete history every turn. - Streaming with `"stream": true`. - A model needs a published price for image, audio, or video use. ## Not supported with account keys Media inputs to chat, provider-hosted tools (web search, code execution), opaque reasoning replay, stored or encrypted conversation state, background operations, response lifecycle routes, passthrough routes, and the inference MCP proxy. ## Response headers Virtual models using the Super Intelligence Router add `X-ZRouter-Route`, for example `super_intelligence; tier=complex; score=63; reasons=code,reasoning-cues`. Next: [Errors and limits](/docs/errors.md) --- Source: https://agents.zrouter.si/docs/errors.md # Errors and limits | Status | Meaning | What an agent should do | | --- | --- | --- | | 400 | Invalid request or BYOK setup | Check the model ID, parameters, and that a provider key is saved for BYOK | | 401 | Invalid account API key | Stop. Ask the account owner for an active key | | 402 | Not enough credit for the reservation | Lower `max_tokens`, or ask the owner to add credit | | 403 | Endpoint or model not allowed | Use a supported endpoint and a model from `/v1/models` | | 429 | Rate limit (`rate_limit_exceeded`) or budget (`budget_exceeded`) | Rate limit: wait and retry with backoff. Budget: stop and tell the owner | | 503 | Account or billing service unavailable | Retry later. Do not blindly retry paid work | Providers can return other errors. Read the status and message together. ## Reservations Before dispatch, ZRouter reserves credit for the workspace input allowance plus the requested `max_tokens`. After usage is reported it settles the real charge and releases the rest. So: - Set `max_tokens` to what the task needs. It lowers the hold and avoids 402s. - If a stream disconnects before final usage, credit can stay held until reconciled. Do not assume a disconnected request was free. Workspace limits and live per-model prices: https://zrouter.si/pricing and [/capabilities.json](/capabilities.json). Next: [Virtual models](/docs/virtual-models.md) --- Source: https://agents.zrouter.si/docs/virtual-models.md # Virtual models A virtual model is a private, named routing configuration. The app sends its name in `model`, and ZRouter routes to the provider models it lists. It does not host a new model. - Names are private to the account, so two accounts can both use `auto`. - Virtual models appear in `/v1/models` for the account's keys. - Strategies: `round_robin`, `failover`, `cost`, `adaptive`, [`super_intelligence`](/docs/super-intelligence-routing.md), and [`schedule`](/docs/scheduled-routing.md). Which ones appear depends on workspace settings. Targets can also use weights and session keeping. - The initial credit reservation covers all possible targets, so it can be higher than the final charge. Create one: ```bash zctl models list zctl routers create support-bot --target PROVIDER/MODEL --strategy round_robin ``` Or with MCP: `virtual_models_upsert`. The dashboard calls them **Virtual models**; `zctl` calls them **routers**. Agent guidance: if the account owner gives you a virtual model name, use it instead of a concrete model. The owner can then change providers without changing your configuration. --- Source: https://agents.zrouter.si/docs/super-intelligence-routing.md # Super Intelligence Router A virtual-model strategy. Each request gets a difficulty score from 0 to 100, computed in well under a millisecond from the request itself. | Signal | Effect | | --- | --- | | Prompt and conversation length | Up | | Code blocks and source code | Up | | Words like debug, prove, design, refactor, analyze | Up | | Math notation | Up | | Images | Up | | High reasoning effort or extended thinking | Strongly up | | Low reasoning effort, greetings, translations, short rewrites | Down | Below 25 is **simple**, 25 to 54 is **standard**, 55 and up is **complex**. If a tier has no available target, the request moves up to a stronger tier, never down. Every response carries the decision: ```text X-ZRouter-Route: super_intelligence; tier=complex; score=63; reasons=code,reasoning-cues ``` Setup: create a virtual model, add targets, choose **Super Intelligence Router**, and assign targets to at least one tier. Then send `"model": ""`. --- Source: https://agents.zrouter.si/docs/scheduled-routing.md # Scheduled routing A virtual-model strategy that picks targets by time of day. | Setting | Default | Meaning | | --- | --- | --- | | Timezone | UTC | Timezone for the peak window | | Peak starts | 09:00 | Inclusive | | Peak ends | 17:00 | Exclusive. A window can cross midnight | | Peak targets | None | Used during the window, in priority order | | Off-peak targets | None | Used outside the window, in priority order | At least one target list is required. If no target for the current period is available, the first available target of the virtual model serves the request, and fallback still applies. Requests are billed at the rate of the model that served them. --- Source: https://agents.zrouter.si/docs/byok.md # Bring your own keys (BYOK) 1. A person saves a provider key under **Bring your own keys**. Supported connections: OpenAI, Anthropic, Gemini AI Studio, Groq, OpenRouter, DeepSeek, xAI, Cerebras, Hugging Face, Alibaba Bailian, Chutes, Cohere, Fireworks AI, Kilo AI, Kimi Code, Meta, MiniMax, OpenCode Go, Xiaomi, and Z.ai (only enabled ones appear). 2. Send requests with `X-ZRouter-BYOK: true` and a provider-qualified model or a virtual model: ```bash curl https://zrouter.si/v1/chat/completions \ -H "Authorization: Bearer $ZROUTER_API_KEY" \ -H "X-ZRouter-BYOK: true" \ -H "Content-Type: application/json" \ -d '{"model": "PROVIDER_INSTANCE/MODEL_ID", "messages": [{"role": "user", "content": "Hello"}], "max_tokens": 256}' ``` - With a virtual model, routing only uses targets on providers that have a saved key. If none do, the request fails instead of spending platform credit. - A BYOK request never uses platform keys or the shared response cache. - Keys are encrypted at rest (AES-256-GCM) and never returned by the API. - The provider bills the provider account. ZRouter routing fees still need prepaid credit, and budgets and rate limits still apply. - Custom base URLs, Azure credentials, and Vertex service accounts are not supported. --- Source: https://agents.zrouter.si/docs/credits.md # Credits and billing - Prepaid USD credit, $5 minimum per purchase, through Stripe Checkout. No subscription. Credit appears after payment confirmation. - All account API keys share one balance. - Rates depend on workspace configuration. Live per-model prices: https://zrouter.si/pricing and [/capabilities.json](/capabilities.json). - Each request reserves credit first, then settles the actual metered charge (see [Errors and limits](/docs/errors.md)). - The ledger (dashboard, or MCP `credit_ledger`) is the record of balance changes. Usage charts show estimates that can differ. - Resetting a budget or rate limit does not refund charges. There is no self-service refund flow. --- Source: https://agents.zrouter.si/docs/mcp.md # Account MCP server Endpoint: `https://zrouter.si/mcp` (streamable HTTP). Tool catalog: [/mcp/tools.json](/mcp/tools.json). Server card: [/.well-known/mcp.json](/.well-known/mcp.json). This server manages the account. It does not send model requests or change an assistant's inference provider. ## Connect - **OAuth clients** (Claude, ChatGPT, Grok, most others): add the URL as a custom connector and approve access on the ZRouter page. - **Token clients:** create an MCP token under **CLI and MCP access** (shown once, expires after 30 days). ```bash claude mcp add --transport http zrouter https://zrouter.si/mcp --header "Authorization: Bearer $ZROUTER_MCP_TOKEN" ``` ```json {"mcpServers": {"zrouter": {"url": "https://zrouter.si/mcp", "headers": {"Authorization": "Bearer YOUR_MCP_TOKEN"}}}} ``` ## Tools | Area | Tools | | --- | --- | | Account | `account_info`, `credit_ledger` | | Usage | `usage_summary`, `usage_daily`, `usage_by_model`, `usage_log` | | Logs | `logs_search`, `logs_get`, `logs_stats` | | Routers | `models_list`, `virtual_models_list`, `virtual_models_upsert`, `virtual_models_delete` | | API keys | `api_keys_list`, `api_keys_create`, `api_keys_delete` | | Budgets | `budgets_list`, `budgets_upsert`, `budgets_delete`, `budgets_reset` | | Rate limits | `rate_limits_list`, `rate_limits_upsert`, `rate_limits_delete`, `rate_limits_reset` | Deletes and resets are annotated as destructive. Every tool acts only on the authenticated account. --- Source: https://agents.zrouter.si/docs/cli.md # zctl CLI: Installation and Account Management > Learn who should use zctl, when to use the CLI, how to install it, and how to manage ZRouter routers, API keys, credits, usage, and limits from a terminal. `zctl` is a customer CLI client. It connects to the same account APIs as the dashboard, with the same account scope and feature availability. It does not start a gateway or need a repository checkout. ## Who should use zctl? `zctl` is for ZRouter account owners, developers, operations teams, and CI/CD maintainers who need terminal access to their own account. Each command has the same account permissions as the customer dashboard. The CLI does not grant operator access or permission to manage other customers. ## When should you use the CLI? Use `zctl` to create or update routers while coding, back up routing configuration, apply a JSON configuration from a script, rotate account API keys, inspect usage and request logs, or manage budgets and rate limits from a remote terminal. Output is readable by default; add `--json` for scripts. Nonzero exit codes on errors support automation. | Interface | Use it when | | --- | --- | | Customer dashboard | You want visual charts, forms, or an interactive playground. | | zctl CLI | You work in a terminal or need repeatable account-management scripts. | | [Account MCP tools](/docs/mcp) | You want a connected AI assistant to manage your account through supported tools. | ## What do you need before installing? - Access to the ZRouter service at `https://zrouter.si`. - A ZRouter account, or use `zctl register --email you@example.com` after installing. - Linux, macOS, or Windows on x64 or ARM64 and access to the gateway over the network. - For the macOS/Linux installer: `sh`, `curl`, and `sha256sum` or `shasum`. You do not need Go, Node.js, a provider API key, or a repository checkout to run an installed client. HTTP is allowed for a gateway on localhost during development. Keep any gateway base path in the URL. Installing the CLI and managing an account does not consume inference credit; requests to AI models use the platform's billing. ## Install ### npm With Node.js 20 or later, install the `zrouterctl` npm package. The terminal command is `zctl`: ```bash npm install -g zrouterctl zctl login ``` You can also use `npx --package=zrouterctl@latest zctl login` without a global installation. The npm package includes verified binaries for all six supported platforms. No Go compiler or separate binary download is required. Update with `npm install -g zrouterctl@latest`. To remove it, run `zctl logout`, then `npm uninstall -g zrouterctl`. ### Direct downloads (no Node.js required) Open [ZRouter CLI downloads](https://zrouter.si/cli) for Linux, macOS, and Windows. For macOS or Linux: ```bash curl -fsS https://zrouter.si/cli/install.sh -o install-zctl.sh sh install-zctl.sh --url https://zrouter.si export PATH="$HOME/.local/bin:$PATH" ``` The installer verifies SHA-256 and installs to `~/.local/bin` without sudo. Use `--dir /your/bin` to choose another directory. Run the installer again to update. ### Windows installation Download the x64 or ARM64 executable and `SHA256SUMS` from [CLI downloads](https://zrouter.si/cli). In PowerShell, verify the file before running it, replacing the filename for ARM64: ```powershell Get-FileHash .\zctl-windows-amd64.exe -Algorithm SHA256 Rename-Item .\zctl-windows-amd64.exe zctl.exe .\zctl.exe login ``` Compare the hash with the entry for that exact filename in `SHA256SUMS`. Move `zctl.exe` to a folder on your user PATH to run `zctl` from any terminal. ### Update or uninstall These instructions apply to direct downloads. For npm installations, use the npm update and uninstall commands above. Run the installer again using the same `--url` and `--dir` to update. Windows users can download and verify the replacement executable. To uninstall, first run `zctl logout` to revoke the current credential, then remove the installed `zctl` or `zctl.exe` file. Other authorized terminals remain signed in. ## Sign in ```bash zctl login ``` The CLI opens your account dashboard. Sign in with your password, Google, or GitHub if enabled. Verify the code displayed in your terminal, then explicitly approve that terminal. Use `--no-open` when the terminal has no browser and open the displayed URL on another device. The CLI defaults to the hosted ZRouter service, so a new user can run `zctl login` without a URL. After sign-in, it remembers the gateway. An explicit `--url` takes precedence over `ZROUTER_URL`, then the saved gateway, then the hosted default. To choose a gateway explicitly, including a separate self-hosted deployment: ```bash zctl login --url https://zrouter.si ``` Keep any configured base path in that URL. For local development, use `zctl login --url http://localhost:8080`. For password sign-in, use `zctl login --email you@example.com`. The password prompt is hidden. `zctl register --email you@example.com` creates an account and signs in. Scripts can supply a password via `--password-stdin`. Passwords and provider keys have no command-line value flags, to keep them out of shell history. Credentials expire after 30 days and are stored in a private credential file: | OS | Default location | | --- | --- | | Linux | `$XDG_CONFIG_HOME/zrouter/credentials.json` or `~/.config/zrouter/credentials.json` | | macOS | `~/Library/Application Support/zrouter/credentials.json` | | Windows | `%AppData%\zrouter\credentials.json` | The file stores the gateway URL and CLI token, with mode `0600` on Unix. A saved credential is used only for its original gateway. Override its location with `--config FILE` or `ZROUTER_CONFIG`. Revoke terminals in the dashboard's **CLI access** page or with `sessions revoke ID`. `logout` revokes the current credential and removes its matching local file. For CI, set `ZROUTER_URL` and `ZROUTER_TOKEN` using your secret manager. Use a CLI management token (`zr_cli_...`). Inference API keys (`zr_live_...`) cannot manage accounts. `login --token-stdin` imports an existing management credential after verifying it. Management credentials cannot make inference requests. Create an API key for those requests. ## Virtual routers ```bash zctl models list zctl routers list zctl routers create assistant \ --target openai/gpt-4.1 --target anthropic/claude-sonnet-4-5 \ --strategy round_robin zctl routers update assistant --description "Default assistant" zctl routers edit assistant zctl routers disable assistant zctl routers enable assistant zctl routers delete assistant ``` Use provider/model selectors returned by `models list`. `routers list` includes this deployment's available strategies. A bare `--target other-router` points to another router owned by your account. The server validates provider targets, routing strategies, account ownership, and cycles. `update` preserves every setting you omit, including disabled state, weights, schedule configuration, failover, and session affinity. Explicit Boolean changes use `--enabled=false`, `--failover=false`, or `--session-affinity=false`. `edit` opens private JSON in `$VISUAL`, then `$EDITOR`, or `vi`. No changes are sent until the editor exits successfully and JSON is valid. Router names cannot be changed by update or edit. Create a new router to use a different name. Use export/apply for backups, automation, and advanced routing settings: ```bash zctl routers export assistant > router.json zctl routers apply --file router.json zctl routers update assistant --file partial-update.json ``` An editable configuration looks like this: ```json { "name": "assistant", "strategy": "round_robin", "targets": [ { "provider": "openai", "model": "gpt-4.1", "weight": 3 }, { "provider": "anthropic", "model": "claude-sonnet-4-5", "weight": 1 } ], "description": "Default assistant", "enabled": true, "failover": true, "session_affinity": true } ``` `apply` upserts a complete configuration. `update --file` merges fields present in the file with the existing router. Advanced exports include `strategy_config`, `strategy_plugin`, and `slowdown`. The CLI uses deployment-supported strategies, including schedules and configured routing plugins. Namespaces come from the server, users cannot choose another account's namespace. Send the router's name as the model, for example `"model": "assistant"`, with an inference API key. The create response's `source`, such as `accounts/ACCOUNT_ID/assistant`, is the full selector and also works. ## Account management ```bash zctl account zctl balance zctl pricing zctl keys list zctl keys create --name production zctl keys revoke KEY_ID zctl byok list zctl byok set openai zctl byok remove openai zctl credits add --amount 25 --open zctl credits history zctl usage summary zctl usage daily zctl usage models zctl logs requests --query 'limit=20' zctl logs audit --query 'limit=20' zctl sessions list zctl sessions revoke SESSION_ID ``` Key creation shows the secret once. `byok set` prompts for the provider key, or reads it with `--key-stdin`. Credit purchases return a secure Stripe checkout URL, `--open` also opens it. Purchases start at $5 with no platform policy maximum, subject to payment-provider and numeric precision limits. Usage and audit queries accept the same filters as the account dashboard, with enforced account scoping. `balance` and `pricing` return the account response, including balance in microdollars (1 USD = 1,000,000) and transparent per-model rates. ## Budgets and rate limits ```bash zctl budgets list zctl budgets set --file budget.json zctl budgets delete --file budget.json zctl budgets reset --period 86400 zctl rate-limits list zctl rate-limits set --file limit.json zctl rate-limits delete --file limit.json zctl rate-limits reset --period 60 ``` A daily $20 budget: ```json { "budget_key": { "period_seconds": 86400 }, "amount": 20 } ``` A per-minute rate limit: ```json { "limit_key": { "period_seconds": 60 }, "max_requests": 100, "max_tokens": 50000 } ``` The CLI derives `scope`, `subject`, and `user_path` from your authenticated account. Budgets and rate limits must be enabled in your workspace. ## Output Commands print readable output: lists as tables (`zctl keys list`, `zctl routers list`) and single records as labelled lines (`zctl account`). Amounts show as dollars and timestamps as local dates. | Option | Default | Use it to | | --- | --- | --- | | `--json` | off | Print the raw JSON response, for scripts and `jq`. Works anywhere on the command line. | | `ZROUTER_OUTPUT=json` | unset | Make JSON the default, for CI and scripts written for earlier versions. | ```sh zctl keys list # table zctl keys list --json | jq -r '.[].name' # JSON for scripts ``` `zctl routers export` always prints JSON, so its output can be edited and passed to `zctl routers apply`. Wide tables show the first eight fields; use `--json` to see every field. Commands exit nonzero on errors. Run `zctl help` for the command reference. ## Troubleshooting | Problem | What to do | | --- | --- | | `zctl: command not found` | Add the installation directory to PATH or run the executable by its full path. | | Sign-in expired or a terminal code is invalid | Run `zctl login` again and approve the new code within ten minutes. | | No browser on the machine | Use `zctl login --no-open` and open the displayed URL on another device. | | The saved sign-in does not work for another URL | Sign in to that gateway separately; credentials are bound to one gateway URL. | | A router target or strategy is rejected | Run `zctl models list` and `zctl routers list` to check deployment availability. | | Budgets, rate limits, or downloads are unavailable | Check feature availability in your workspace. If a download is unavailable, try again later or contact the team. | | Checkout is unavailable | Credit purchases are not currently available. Try again later; account management remains available. | ## Frequently asked questions ### What is zctl? zctl is ZRouter's customer CLI for managing virtual routers, API keys, provider connections, credits, usage, request logs, budgets, and rate limits. ### Do I need to clone the repository to install zctl? No. Install from the `/cli` page on your gateway. The macOS/Linux installer verifies a prebuilt binary, and Windows users can download an executable directly. ### Can I create and edit a virtual router from the CLI? Yes. Use `zctl routers create NAME --target PROVIDER/MODEL`, `zctl routers update NAME`, or `zctl routers edit NAME`. Updates preserve settings you omit, and edit validates JSON before saving. ### Can I use zctl in CI or on a remote server? Yes. Set `ZROUTER_URL` and `ZROUTER_TOKEN` through your CI secret manager. The token must be an active CLI management credential. Browser sign-in can also use `--no-open` on a machine without a browser. ### Can an inference API key sign in to the CLI? No. A `zr_live_...` API key authenticates model requests. Account management requires a CLI credential beginning with `zr_cli_...`, obtained through sign-in. ### How do I revoke a terminal's access? Open CLI access in the customer dashboard, or use `zctl sessions list` and `zctl sessions revoke SESSION_ID`. `zctl logout` revokes the current terminal. CLI credentials expire after 30 days. --- Source: https://agents.zrouter.si/docs/integrations/claude-code.md # Claude Code Setup: Connect to ZRouter > Connect Claude Code to ZRouter with an account API key for text-file coding and client-executed tools, then pick models and check what billing covers. ## What works ZRouter account keys support client-executed tools and inline text tool results through `/v1/messages`, including streaming. Each model turn reserves credit and settles against reported token usage. Customer BYOK supports the same request shapes with its configured routing fees. Start with a text-file coding task using a tool-capable Claude model. Provider-hosted search and code execution, media, server-side compaction, stored conversation references, and opaque reasoning replay remain unsupported. These limits also apply to BYOK. The setup below keeps the initial workflow inside this supported subset; it does not enable every Claude Code feature. The gateway's automated integration tests cover a two-turn file-reading exchange through the Anthropic adapter, streaming and non-streaming responses, and fixed and provider-priced credit settlement. They use a local simulated provider. A live Claude Code session against a paid provider has not yet been certified. ## Connect your account 1. Create a dedicated account API key under **API Keys**. 2. Add credit, or save a supported Anthropic provider key under **Bring your own keys**. 3. Copy an enabled Claude model ID from **Models**, including its provider prefix. 4. Install Claude Code using [Anthropic's instructions](https://code.claude.com/docs/en/setup). Set these variables in the terminal where you launch Claude Code. Replace the key and model placeholders. The base URL is the gateway root, without `/v1`. ```bash export ANTHROPIC_BASE_URL="https://zrouter.si" export ANTHROPIC_AUTH_TOKEN="YOUR_ZROUTER_ACCOUNT_KEY" export ANTHROPIC_MODEL="ANTHROPIC_INSTANCE/CLAUDE_MODEL_ID" export ANTHROPIC_DEFAULT_HAIKU_MODEL="$ANTHROPIC_MODEL" export ANTHROPIC_DEFAULT_SONNET_MODEL="$ANTHROPIC_MODEL" export ANTHROPIC_DEFAULT_OPUS_MODEL="$ANTHROPIC_MODEL" export CLAUDE_CODE_MAX_OUTPUT_TOKENS=8192 export MAX_THINKING_TOKENS=0 export ENABLE_TOOL_SEARCH=false claude --model "$ANTHROPIC_MODEL" --tools "Read,Glob,Grep,Bash,Edit,Write" ``` The output cap matches ZRouter's default. Use your workspace's limit if the operator changed it. Use a Claude model that permits thinking to be disabled for this initial workflow. The explicit tool list keeps provider-hosted web tools out of the session. Tool execution remains subject to Claude Code's normal permissions. The helper-model variables keep auxiliary calls on an available model. Choose separate enabled models later if needed. Avoid setting `ANTHROPIC_API_KEY` and `ANTHROPIC_AUTH_TOKEN` to different credentials. See [gateway configuration](https://code.claude.com/docs/en/llm-gateway-connect) and [environment variables](https://code.claude.com/docs/en/env-vars). For customer BYOK, add this before launching the client: ```bash export ANTHROPIC_CUSTOM_HEADERS="X-ZRouter-BYOK: true" ``` Your ZRouter account key still authenticates the request. The saved provider key stays on ZRouter. Without the BYOK header, requests use platform credit. Provider API charges are separate from Claude subscription usage. ## Verify the connection First check model access without generating tokens: ```bash curl "$ANTHROPIC_BASE_URL/v1/models" \ -H "Authorization: Bearer $ANTHROPIC_AUTH_TOKEN" ``` Then launch Claude Code in a small test project and ask it to read one text file and explain it. Approve the read through the client's normal permission prompt. Check **Audit Logs** for the requests and **Billing & credits** for settled charges. This task consumes model tokens. `POST /v1/messages/count_tokens` is available with account keys and does not deduct ZRouter credit. It uses the provider's counter when available, otherwise an estimate. Counting is advisory; request-size and output limits still apply. ## Editor extension The Claude Code extension can use the same variables in user-level editor settings under `claudeCode.environmentVariables`. Keep credentials out of shared repository settings. An editor launched from the desktop may not inherit terminal variables. Restart the extension and select the configured model after changing its environment. ## Troubleshooting - A `/v1/v1/messages` error means the base URL includes `/v1` twice. - A model error requires an enabled Claude model, including any helper models. - A hosted-tool rejection means the request includes a provider-executed tool. Start with the local tools listed above. - An opaque-reasoning or media rejection requires a fresh text-only session with thinking disabled on a model that supports it. - A large conversation can exceed the conservative input allowance, including tool definitions and results. Shorten the history or start a fresh session. - A 402 response means the available balance cannot cover the reservation. The hold can exceed the final charge. Use the supported text-file workflow and disable provider features outside account metering. Adding credit or switching to BYOK does not bypass these limits. ## Manage your account with MCP The [account MCP server](/docs/mcp) lets an assistant inspect usage and manage routers, keys, and enabled limits. That connection is separate from the model-request configuration above. --- Source: https://agents.zrouter.si/docs/integrations/cline.md # Cline Setup: OpenAI Compatible Provider > Configure Cline's OpenAI Compatible provider for ZRouter with your account API key, model ID, and supported text-tool workflows. ## Compatibility first **Client-executed function tools are supported with account keys.** Use inline text tool results and explicit history. Full Cline sessions still need client-specific validation; media, hosted tools, and opaque state remain unsupported. Use a dedicated account API key for the supported subset. The example below connects to your ZRouter account at `https://zrouter.si/v1`. ## Configure the extension Open Cline's settings using its gear icon. Choose **OpenAI Compatible**, then enter: | Field | Value | | :--- | :--- | | Base URL | `https://zrouter.si/v1` | | API key | Your dedicated ZRouter account API key | | Model ID | Exact `PROVIDER_INSTANCE/MODEL_ID` returned by the gateway | | Max output tokens | A limit supported by the selected model | | Context window | The selected model's actual context limit | Use **OpenAI Compatible**, rather than assuming the native OpenAI provider offers the same custom URL settings. Keep this workflow text-only and use client-executed function tools supported by the selected model. See [Cline's official provider setup](https://docs.cline.bot/provider-config/openai-compatible). ## Verify Save the settings and use **Verify** if available. Start a small task, such as reading one file and explaining it. Check gateway logs for successful inference and tool exchanges. Tools run under Cline's permission controls; routing through ZRouter does not replace those controls. ## Troubleshooting - For authentication errors, use your account API key, not an upstream provider key or browser session token. - For 404, the base URL should end at `/v1`, not `/v1/chat/completions`. - For unknown models, copy the gateway's exact identifier instead of a display label. - For a hosted-tool or media rejection, disable that feature and use a supported text workflow. See [shared troubleshooting](/docs/integrations/troubleshooting). The settings in this guide apply to Cline's OpenAI-compatible extension configuration; other Cline interfaces may have separate settings. --- Source: https://agents.zrouter.si/docs/integrations/codex.md # Codex Setup: Connect the CLI and IDE > Configure the Codex CLI and IDE extension to use ZRouter as a custom Responses API provider, with your account key, a model choice, and the supported features. ## Compatibility first **Full Codex sessions still require compatibility validation.** Account keys accept Responses function tools and explicit text tool results, but stored response continuation, encrypted reasoning replay, and custom free-form tools remain unsupported. Codex can depend on those features, so this configuration does not guarantee full agent-session compatibility. Create a dedicated account API key, add credit, and choose an available tool-capable model that supports Responses requests. A successful text response alone does not establish full Codex compatibility. Review [account compatibility](/docs/integrations/troubleshooting) before using an agent workflow. ## Configure the provider Set the key in the environment used to launch Codex: ```bash export ZROUTER_API_KEY="YOUR_ZROUTER_KEY" ``` Merge this configuration into **`~/.codex/config.toml`**, preserving unrelated settings. Replace the model with an enabled identifier from your ZRouter dashboard: ```toml model = "PROVIDER_INSTANCE/MODEL_ID" model_provider = "zrouter" [model_providers.zrouter] name = "ZRouter" base_url = "https://zrouter.si/v1" env_key = "ZROUTER_API_KEY" wire_api = "responses" requires_openai_auth = false supports_websockets = false ``` Codex custom providers use the Responses protocol. The URL includes `/v1` once. WebSockets are disabled because this setup uses the gateway's HTTP/SSE endpoint. Custom provider selection belongs in user-level configuration; project-local provider settings are not applied. See [Codex advanced configuration](https://learn.chatgpt.com/docs/config-file/config-advanced) and the [configuration reference](https://learn.chatgpt.com/docs/config-file/config-reference). ## Launch and verify ```bash curl "https://zrouter.si/v1/responses" \ -H "Authorization: Bearer $ZROUTER_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"PROVIDER_INSTANCE/MODEL_ID","input":"Say hello","max_output_tokens":256,"store":false}' codex ``` The curl request consumes provider tokens. Check that Codex selects ZRouter, then try a small task and review gateway logs for Responses and tool compatibility. Some model/provider combinations cannot satisfy all agent features. ## IDE extension Use the same user-level provider configuration for the Codex IDE extension. Make the environment key available to the extension process, then restart the editor. Do not assume an editor opened from the desktop inherits your shell variables. Keep provider secrets out of project configuration and source control. ## Troubleshooting - A missing environment-key error means `ZROUTER_API_KEY` is unavailable to that process. - A `/v1/v1/responses` error means the API version was appended twice. - A provider or model error requires an enabled gateway model that supports the requested behavior. - A prepaid custom-tool, encrypted-reasoning, or continuation rejection identifies a feature outside the supported function-tool subset. See [shared troubleshooting](/docs/integrations/troubleshooting). A ChatGPT subscription does not supply ZRouter credits or transfer subscription usage to this custom provider. --- Source: https://agents.zrouter.si/docs/integrations/cursor.md # Cursor Setup: Custom OpenAI Base URL > Point Cursor's custom OpenAI base URL at ZRouter, add your account key, choose models, and learn which Cursor features work through a custom endpoint. ## Manage your account with MCP To inspect usage or manage ZRouter routers, keys, and enabled limits from your assistant, connect the [account MCP server](/docs/mcp). This manages your ZRouter account without changing the assistant's model provider. The instructions below cover routing model requests instead. ## Compatibility first **Account keys support text and client-executed function tools.** Cursor compatibility depends on the actual request shape and model. Media in agent requests, provider-hosted tools, and stored or encrypted state remain unsupported. Full Cursor Agent sessions have not been validated; check [account compatibility](/docs/integrations/troubleshooting) before using an agent workflow. Cursor's custom API keys apply to supported chat models. Tab completion uses Cursor's built-in models. Cursor's own plan and usage rules also apply. See [Cursor API key documentation](https://cursor.com/help/models-and-usage/api-keys). ## Connection requirements Use a public HTTPS gateway endpoint reachable from Cursor's servers. `localhost`, a LAN address, or a private development server is not sufficient for Cursor's hosted request path. See the [Cursor support team's explanation](https://forum.cursor.com/t/dgx-spark-owners-anyone-successfully-connected-ollama-to-cursor/161258/5). Create an account API key and fund the balance. Use an exact model ID returned by `/v1/models`; do not assume an example model is enabled. ## Configure Cursor 1. Open **Cursor Settings → Models**. 2. Enter the ZRouter key in the OpenAI API key field. 3. Enable **Override OpenAI Base URL** and set `https://zrouter.si/v1` for supported account requests. 4. Save the configuration. Add or select the gateway model ID in the model list if your installed version permits custom models. 5. Start a new text chat with that model. Inspect ZRouter usage and available request logs after a completed request. The API key is sent through Cursor's backend to the configured gateway. Avoid putting a provider BYOK secret in this field: it needs the ZRouter gateway credential. ## BYOK and feature boundaries Customer BYOK requires `X-ZRouter-BYOK: true` and a saved key for the selected provider-qualified model. The basic Cursor override does not provide a documented arbitrary-header setting, so these instructions use gateway-funded credits. Merely saving a BYOK key in ZRouter does not make Cursor requests use it. Tab, cloud features, and other Cursor services are not redirected simply by changing this base URL. Do not assume every model or Cursor feature can use a custom gateway. ## Troubleshooting - For 401, check the override is still enabled and the key belongs to ZRouter, not OpenAI. - For connection failure, confirm public HTTPS reachability from outside your machine. - For model validation errors, check the exact identifier and your version's custom-model support. Do not rename a model to claim capabilities it lacks. - For a prepaid hosted-tool or media rejection, disable the unsupported feature and use a supported text workflow. See [shared troubleshooting](/docs/integrations/troubleshooting). Local ZRouter development is better checked with curl or an SDK until a public HTTPS endpoint is available. --- Source: https://agents.zrouter.si/docs/integrations/librechat.md # LibreChat Setup: Custom ZRouter Endpoint > Add ZRouter to LibreChat as a custom endpoint, let each user supply their own account key, list models, and understand which LibreChat features are supported. ## Before you connect Use the custom Chat Completions endpoint for plain text chats. Account keys support client-executed function tools with text results. Image/audio inputs, hosted tools, Assistants, and stored response lifecycle operations remain unsupported. Each user needs a ZRouter account, credit or supported BYOK, and an account API key. ## Configure the custom endpoint Merge this `endpoints` section into your existing `librechat.yaml`, retaining the configuration version required by your installed LibreChat release. Replace the URL and model ID: ```yaml endpoints: custom: - name: "ZRouter" apiKey: "user_provided" baseURL: "https://zrouter.si/v1" models: default: ["PROVIDER_INSTANCE/MODEL_ID"] fetch: false titleConvo: false modelDisplayLabel: "ZRouter" addParams: max_tokens: 256 ``` Restart LibreChat according to its deployment instructions. Select ZRouter, provide your own ZRouter account key when prompted, and start a text chat. `user_provided` lets each person supply a separate credential; static server credentials instead charge the one ZRouter account that owns the key. See [LibreChat's custom endpoint configuration](https://www.librechat.ai/docs/configuration/librechat_yaml/object_structure/custom_endpoint). The example disables model fetching and automatic titles to keep the initial setup predictable. Copy an exact model ID from ZRouter. Increase `max_tokens` only within the selected model and workspace limits. ## Optional BYOK After each user saves a provider key in their ZRouter dashboard, a BYOK-only custom endpoint can include: ```yaml headers: X-ZRouter-BYOK: "true" ``` Place `headers` alongside `baseURL`, not inside `models`. Each user must have a saved key for the selected provider instance. This header changes all requests through that endpoint to BYOK; create a separately named gateway-funded endpoint if both modes are needed. Provider charges are separate from ZRouter routing fees. ## Verify and troubleshoot Send one short message and check the correct user's ZRouter usage and ledger. Do not use LibreChat display labels or forwarded user headers as evidence of billing isolation. The authenticated account key determines the billed account. Enable only client-executed function tools with text results; keep media and provider-hosted tools off. Connection or parameter failures should be checked against [shared troubleshooting](/docs/integrations/troubleshooting) and the selected provider's capabilities. --- Source: https://agents.zrouter.si/docs/integrations/n8n.md # n8n Setup: Call ZRouter From Workflows > Call ZRouter from an n8n HTTP Request node: account authentication, an OpenAI-compatible request body, BYOK headers, and handling responses in your workflow. ## Choose a supported workflow Use text generation or text embeddings with an account API key. Client-executed function tools with inline text results are supported; provider-hosted tools and opaque state remain blocked. Images, audio, file uploads, and response lifecycle requests are also outside the prepaid API. The HTTP Request node exposes the URL, headers, and JSON directly, so it works without depending on whether your installed OpenAI node exposes a custom base URL. ## Create the credential Create a ZRouter account key dedicated to this workflow. In n8n, create a **Header Auth** credential with header name `Authorization` and value `Bearer YOUR_ZROUTER_ACCOUNT_KEY`. Store the secret in credentials rather than a hard-coded workflow field. ## Configure the HTTP Request node | Setting | Value | | :--- | :--- | | Method | `POST` | | URL | `https://zrouter.si/v1/chat/completions` | | Authentication | Generic Credential Type → Header Auth | | Credential | Your ZRouter credential | | Send body | Enabled, JSON | | Response format | JSON | Use this JSON body and replace the model ID: ```json { "model": "PROVIDER_INSTANCE/MODEL_ID", "messages": [{ "role": "user", "content": "Summarize: the deployment completed successfully." }], "max_tokens": 256, "stream": false } ``` Read the text from `choices[0].message.content`. Once the fixed example succeeds, substitute workflow data using n8n's expression editor. Keep inputs within the gateway limits. See [n8n's HTTP Request node documentation](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/). ## Optional BYOK Save a provider key in your ZRouter dashboard. Add a request header named `X-ZRouter-BYOK` with value `true` and use a model belonging to that provider instance. Keep Header Auth enabled: the account key authenticates to ZRouter while the saved provider key authenticates upstream. ## Operations and errors Execute once and inspect the status, JSON response, and ZRouter usage and ledger. Each successful model request consumes tokens. Repeating nodes or retrying completed requests can create additional charges; the inference API does not provide a general retry deduplication guarantee. The n8n server or container must reach the gateway. For local Docker on macOS/Windows, the gateway URL may need `host.docker.internal` rather than `localhost`. Use HTTPS in production. For 402, reduce the requested output or add credit. See [shared troubleshooting](/docs/integrations/troubleshooting). --- Source: https://agents.zrouter.si/docs/integrations/opencode.md # OpenCode Setup: Custom OpenAI Provider > Define a custom OpenAI-compatible ZRouter provider in OpenCode: the base URL, your account API key, model names, and a quick check that requests go through. ## Compatibility first **Client-executed function tools are supported with account keys.** Use inline text tool results and explicit history. Full OpenCode sessions still need client-specific validation; media, hosted tools, and opaque state remain unsupported. For the supported subset, use an enabled tool-capable model and a dedicated account API key. The example below connects to your ZRouter account at `https://zrouter.si/v1`. ## Add the provider Set `ZROUTER_API_KEY` in the environment where OpenCode runs. Merge this into your OpenCode configuration. Replace both occurrences of `PROVIDER_INSTANCE/MODEL_ID` with the same gateway model ID: ```bash export ZROUTER_API_KEY="YOUR_ZROUTER_KEY" ``` ```json { "$schema": "https://opencode.ai/config.json", "model": "zrouter/PROVIDER_INSTANCE/MODEL_ID", "provider": { "zrouter": { "npm": "@ai-sdk/openai-compatible", "name": "ZRouter", "options": { "baseURL": "https://zrouter.si/v1", "apiKey": "{env:ZROUTER_API_KEY}" }, "models": { "PROVIDER_INSTANCE/MODEL_ID": { "name": "ZRouter coding model" } } } } } ``` This adapter uses Chat Completions. OpenCode also documents `@ai-sdk/openai` for Responses models; choose the adapter that matches the model and gateway behavior you have tested. See [OpenCode's custom provider documentation](https://opencode.ai/docs/providers/). ## Verify Launch `opencode`, open `/models`, and select the ZRouter model. First send a short prompt, then try a small task that reads a file. Review logs for model, streaming, and tool errors. A connection test does not validate every agent feature. ## Troubleshooting Check that the provider ID is `zrouter`, the model map key is the exact gateway model ID, and the environment key reaches the process. Avoid claiming image or tool support in model metadata unless the actual provider supports it. Set context and output limits from the selected model's real limits. Customer BYOK supports the same client-tool subset when the client sends `X-ZRouter-BYOK: true`. Use the [shared troubleshooting guide](/docs/integrations/troubleshooting) for common errors. --- Source: https://agents.zrouter.si/docs/integrations/openwebui.md # Open WebUI Setup: Chat Through ZRouter > Use ZRouter for text chat in Open WebUI: add a connection with a scoped account key, list your models, and keep usage and spending under your account limits. ## Before you connect Create a ZRouter account, add credit, and generate a dedicated account API key. Copy an enabled model ID. The account API supports text chat and client-executed function tools with text results. Turn off provider-hosted search, images, audio, and remote file inputs for this connection. A shared Open WebUI connection key charges one ZRouter account for every person using it. Open WebUI user identities and forwarded headers do not create separate ZRouter billing accounts. For independent balances, each person needs their own ZRouter account and credential through a supported per-user connection setup. ## Add the connection 1. Open **Settings → Admin → Connections → Manage OpenAI API Connections**. 2. Add a connection with URL `https://zrouter.si/v1` and your ZRouter account API key. 3. Save, then click **Verify Connection** beside the URL. Verification calls `/models`; saving alone does not test the connection. 4. Choose an available gateway model. If needed, add its exact ID to the connection's model allowlist. 5. Start a short plain text chat and review the ZRouter dashboard. These fields and verification behavior are documented in [Open WebUI's OpenAI-compatible setup](https://docs.openwebui.com/getting-started/quick-start/connect-a-provider/starting-with-openai-compatible/). ## Local development The Open WebUI server must reach ZRouter. When Open WebUI runs in Docker on macOS or Windows and ZRouter runs on the host, use `http://host.docker.internal:8080/v1`. Container `localhost` points to that container, not your computer. Production connections should use HTTPS. ## BYOK Save a provider key in your ZRouter account. If your Open WebUI version offers custom connection headers, add `X-ZRouter-BYOK: true` and select a provider-qualified model for that saved connection. If headers are unavailable, use the SDK or HTTP Request guides to make BYOK requests. Saving a provider key alone does not enable BYOK on chat traffic. ## Verify usage and fix failures Set a modest maximum output where the client exposes it, within your workspace's limit. Extra title-generation requests can also consume tokens. Check the billing ledger for actual charges and usage for token totals. For prepaid tool or media errors, disable the feature that creates the unsupported payload. For 401 or model errors, verify the account key and exact model ID. See [shared troubleshooting](/docs/integrations/troubleshooting). --- Source: https://agents.zrouter.si/docs/integrations/sdks.md # Python, Node.js and HTTP: OpenAI SDK Setup > Use ZRouter from the OpenAI Python and Node.js SDKs, curl, and streaming clients: set the base URL and account key, pick a model, and send BYOK requests. ## Prepare your account Create an account, fund gateway requests with credit, and create a dedicated account API key. The hosted service is `https://zrouter.si`. Set these variables in your application environment, replacing the key and model placeholders: ```bash export ZROUTER_URL="https://zrouter.si" export ZROUTER_API_KEY="YOUR_ZROUTER_ACCOUNT_KEY" export ZROUTER_MODEL="PROVIDER_INSTANCE/MODEL_ID" ``` For a separate self-hosted deployment, set `ZROUTER_URL` to its public URL, including any configured path prefix. Copy the model ID from the dashboard or query the inventory without generating tokens: ```bash curl "$ZROUTER_URL/v1/models" \ -H "Authorization: Bearer $ZROUTER_API_KEY" ``` Keep these credentials on the server. Browser applications should call your own backend instead of embedding an account secret in public JavaScript. ## Python Install `openai` in your project's environment. The client's base URL includes `/v1` once: ```python import os from openai import OpenAI client = OpenAI( api_key=os.environ["ZROUTER_API_KEY"], base_url=os.environ["ZROUTER_URL"].rstrip("/") + "/v1", max_retries=0, ) response = client.chat.completions.create( model=os.environ["ZROUTER_MODEL"], messages=[{"role": "user", "content": "Say hello"}], max_tokens=256, ) print(response.choices[0].message.content) ``` Custom URLs, request options, and retry controls are documented by the [official Python SDK](https://github.com/openai/openai-python). ## Node.js / TypeScript Install `openai` in your project and run this in a server-side ES module: ```javascript import OpenAI from "openai"; const client = new OpenAI({ apiKey: process.env.ZROUTER_API_KEY, baseURL: process.env.ZROUTER_URL.replace(/\/$/, "") + "/v1", maxRetries: 0, }); const response = await client.chat.completions.create({ model: process.env.ZROUTER_MODEL, messages: [{ role: "user", content: "Say hello" }], max_tokens: 256, }); console.log(response.choices[0].message.content); ``` See the [official JavaScript SDK](https://github.com/openai/openai-node). These examples disable automatic retries so you can decide how to handle potentially billable retries. ## BYOK Save a supported provider key in your account. Use a provider-qualified model belonging to that connection. Add the header on the request: ```python response = client.chat.completions.create( model=os.environ["ZROUTER_MODEL"], messages=[{"role": "user", "content": "Say hello"}], max_tokens=256, extra_headers={"X-ZRouter-BYOK": "true"}, ) ``` ```javascript const response = await client.chat.completions.create({ model: process.env.ZROUTER_MODEL, messages: [{ role: "user", content: "Say hello" }], max_tokens: 256, }, { headers: { "X-ZRouter-BYOK": "true" } }); ``` The gateway account key remains required. The saved provider key stays in ZRouter's encrypted storage. Provider charges and any ZRouter routing fees are separate. ## Streaming over HTTP ```bash curl -N "$ZROUTER_URL/v1/chat/completions" \ -H "Authorization: Bearer $ZROUTER_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"PROVIDER_INSTANCE/MODEL_ID","messages":[{"role":"user","content":"Say hello"}],"max_tokens":256,"stream":true}' ``` SDK clients can also use `stream=True` in Python or `stream: true` in JavaScript and consume the returned stream. If the final usage is unavailable after a disconnect, reserved credit can remain held for reconciliation. ## Responses and embeddings Use `client.responses.create` with plain text `input`, `max_output_tokens`, and `store=false` in Python (`store: false` in JavaScript). Function tools and inline text `function_call_output` items are supported. Send the full tool-call and text history explicitly on each turn. Do not pass provider-hosted tools, encrypted reasoning state, `previous_response_id`, a conversation ID, or background work. Text embeddings use `/v1/embeddings` with an enabled embedding model and text input. SDK methods are `client.embeddings.create(model=..., input=...)` in Python and `client.embeddings.create({model, input})` in JavaScript. Embedding availability depends on configured providers; the model inventory may contain no embedding models. ## Confirm usage Text generation and embeddings consume tokens. Check usage, available logs, and actual ledger charges after a request. Handle 401, 402, 400, and provider errors explicitly. See [shared troubleshooting](/docs/integrations/troubleshooting). --- Source: https://agents.zrouter.si/docs/integrations/troubleshooting.md # Connection checks & troubleshooting > Fix common ZRouter connection problems: the gateway URL, API keys, model names, credit, BYOK, streaming, and coding agent compatibility errors, step by step. ## Start with the right URL | Client or protocol | Base URL | | :--- | :--- | | Claude Code / Anthropic SDK | `https://zrouter.si` for supported text requests | | Codex / OpenAI SDK / compatible chat tools | `https://zrouter.si/v1` for hosted text requests | | n8n HTTP Request | `https://zrouter.si/v1/chat/completions` | Use `https://zrouter.si` for your account. Client-executed function tools with explicit text history can use account keys. Provider-hosted tools and opaque state are outside the supported account request shapes. Do not include `/dashboard`, `/docs`, or an inference endpoint in a client's base URL field. Do not append `/v1` twice. ## Verify authentication before inference ```bash curl "$ZROUTER_URL/v1/models" \ -H "Authorization: Bearer $ZROUTER_API_KEY" ``` For prepaid accounts, use an active account API key created in your dashboard. A browser session token, provider key, or operator master key is not an account inference credential. All account keys share the owning account's balance and access scope. ## Read the error | Status / symptom | Check | | :--- | :--- | | 401 | Correct deployment, active key, bearer header, and any client environment variables | | 402 | Sufficient available credit for the reservation; lower maximum output or buy credit | | 403 unsupported endpoint | Prepaid endpoint allowlist, key permissions, or account access | | 400 tools or content rejected | Use client-executed function tools and inline text results; hosted tools, opaque state, and media are unsupported | | Model missing / model not found | Exact enabled identifier, provider instance, and provider entitlement | | BYOK key missing | Saved key for the same provider instance, provider-qualified model, and BYOK header | | 429 | Workspace, key, or upstream provider rate limits | | 503 | Account/billing service or upstream availability; inspect the sanitized error | | Stream stops | Client/network disconnect, proxy buffering/timeouts, and final usage availability | Providers may use additional statuses and error messages. Record the status and request time, but never include API keys or authorization headers when sharing diagnostics. ## Credit and token limits Set a reasonable `max_tokens` for Chat Completions/Messages, or `max_output_tokens` for Responses. The live workspace limit appears in the API guide. Provider limits may be lower. The initial reservation can exceed the final actual charge, so a positive balance alone does not guarantee a request can start. Large agent histories can exceed the input allowance. Prepaid input validation also uses a conservative request-size bound. Shorten the text history and reduce output instead of repeatedly sending the same rejected payload. ## BYOK checklist 1. Save a supported provider credential under your own ZRouter account. 2. Use `PROVIDER_INSTANCE/MODEL_ID` for that connection. 3. Send your ZRouter account key for gateway authentication. 4. Send `X-ZRouter-BYOK: true` on the inference request. 5. Check provider quota and any ZRouter routing fee, including a negative account balance. Saving a provider key does not automatically enable BYOK. BYOK supports client-executed tools, but does not remove hosted-tool, media, endpoint, or token restrictions. A client without custom-header support should use gateway-funded credits or a different compatible client. ## Agent compatibility Account keys now accept client-executed function definitions, tool calls, and text tool results. Send complete history on each turn. The [Claude Code setup](/docs/integrations/claude-code) describes a supported text-file workflow. Server-hosted tools, opaque reasoning state, media, and stored response continuation remain blocked. Disable unsupported features or choose a client workflow that sends supported account requests. Adding credit or changing keys does not remove the restrictions. ## Networking and usage CLI clients run locally; container clients need an address reachable from their container. Cursor's backend needs public HTTPS. A successful `/models` request checks connectivity and credentials but not generation, streaming, or tool support. Check token totals in Usage, available requests in Logs, and actual balance changes in Billing. A shared client key charges one account even when external user headers differ. Completed retries can consume tokens again; disconnected streams can retain reservations for reconciliation.