# Tokun — Full Integration Guide > Tokun is a metered, multi-protocol LLM gateway. Any client that speaks the OpenAI Chat Completions API — or the Anthropic Messages API (including Claude Code) — can integrate by changing two things: the base URL and the API key. ## TL;DR - Base URL (OpenAI clients): `https://api.tokun.sh/v1` - Base URL (Anthropic SDK / Claude Code): `https://api.tokun.sh` (no `/v1` — the SDK adds the path) - Auth: `Authorization: Bearer sk-...` (OpenAI surface) or `x-api-key: sk-...` (Anthropic surface; Bearer also accepted) - Formats: OpenAI Chat Completions (`POST /v1/chat/completions`), OpenAI Responses (`POST /v1/responses`), Anthropic Messages (`POST /v1/messages`) — buffered or streaming - Model ids: `anthropic/claude-opus-4-8`, `openai/gpt-5.5` (lab/model convention: the lab that made the model, then the model name). Protocol and model are independent. - Billing: prepaid USD balance, metered per token — identical across all three surfaces (one metering pipeline) ## Integrate with one line Working inside a coding agent (Claude Code, Codex, Cursor, …)? You don't have to read this guide yourself — hand your agent this single prompt and it will fetch this file and do the setup: ```text Read https://tokun.sh/llms.txt and integrate Tokun into this project. ``` You supply only your `sk-` key. The rest of this document is the manual reference the agent (or you) follows. ## Getting an API key 1. Sign in to the Tokun console at https://tokun.sh. 2. Open **API Keys** (https://tokun.sh/api-keys) and click **Create key**. 3. The full secret (`sk-`) is shown **once** — copy it immediately. Only a short prefix is stored/displayed afterward. 4. Add a prepaid balance under **Billing** (https://tokun.sh/billing). Top-ups are USD, $5–$1,000 each, via Stripe. With no balance, requests return `402 Payment Required`. Treat keys like passwords: each key draws down your balance and can be revoked from the console. ## Base URL and authentication | Field | Value | | --- | --- | | Base URL | `https://api.tokun.sh/v1` | | Auth header | `Authorization: Bearer sk-...` | | Console (keys, billing) | `https://tokun.sh` | | Format | OpenAI Chat Completions | Authentication is the Tokun credential itself — there is no separate session/OAuth for the gateway. The key may be supplied either as a bearer header (standard) or embedded as a URL path segment: `POST /v1/{token}/chat/completions`. Prefer the header. ## Endpoints - `POST /v1/chat/completions` — OpenAI Chat Completions. Buffered, or streaming with `"stream": true` (Server-Sent Events). Reasoning passes through: `reasoning_effort` and the gateway-native `reasoning: {effort, max_tokens}` object forward to the upstream untouched, and the response's `reasoning` / `reasoning_details` fields (including per-block signatures) relay verbatim. - `POST /v1/responses` — OpenAI Responses API (what Codex CLI / the Agents SDK default to). Stateless: `store` is always false, `previous_response_id` is rejected, `GET /v1/responses/{id}` is a 404. `reasoning: {"effort": ...}` is supported (none/minimal/low/medium/high/xhigh); reasoning output comes back as a `reasoning` output item whose summary carries the actual reasoning text (buffered and streaming via the `reasoning_summary_*` events). Replayed `reasoning` input items are dropped (responses are stateless; use `/v1/messages` when signed thinking must round-trip). - `POST /v1/messages` — Anthropic Messages API (what the `anthropic` SDKs and Claude Code speak). Buffered or streaming with the official Anthropic event protocol. Auth: `x-api-key: sk-...` (or `Authorization: Bearer`). - `POST /v1/messages/count_tokens` — free conservative token estimate (`{"input_tokens": N}`); auth-gated like `/v1/messages`, no billing. - `GET /v1/models` — lists the available model ids and per-model context windows. The response dialect is chosen by request headers: an Anthropic-native caller (sends `x-api-key` or `anthropic-version`, as the `anthropic` SDKs and Claude Code do) gets the Anthropic list shape (`max_input_tokens`) authenticated by the `x-api-key` key; every other caller gets the OpenAI list format (`context_length`) authenticated by the same `Authorization: Bearer` key as chat. Listing is free (no charge, no hold). - `GET /healthz`, `GET /readyz` — liveness/readiness only. All three inference endpoints translate at the edge onto ONE metering pipeline — identical billing, identical model catalog. Not available: `/v1/embeddings`, `/v1/completions`. ## Minimal working example curl: ```bash curl https://api.tokun.sh/v1/chat/completions \ -H "Authorization: Bearer $TOKUN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "anthropic/claude-opus-4-8", "messages": [{"role": "user", "content": "Say hello in one word."}] }' ``` Python (OpenAI SDK): ```python from openai import OpenAI client = OpenAI( base_url="https://api.tokun.sh/v1", api_key="sk-...", ) resp = client.chat.completions.create( model="anthropic/claude-opus-4-8", # or "openai/gpt-5.5" messages=[{"role": "user", "content": "Say hello in one word."}], ) print(resp.choices[0].message.content) ``` Node (OpenAI SDK): ```js import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://api.tokun.sh/v1", apiKey: process.env.TOKUN_API_KEY, }); const resp = await client.chat.completions.create({ model: "anthropic/claude-opus-4-8", // or "openai/gpt-5.5" messages: [{ role: "user", content: "Say hello in one word." }], }); console.log(resp.choices[0].message.content); ``` Streaming: add `"stream": true` to the request body; tokens arrive as OpenAI-style SSE chunks. `max_tokens` is honored but capped: Tokun enforces an output ceiling (default 4096, hard cap 32768) into the forwarded request so a completion can never exceed what your balance hold reserved. ## Models Pass a Tokun model id in the `model` field. Tokun resolves it to the upstream and routes the request; you never send the upstream id directly. | model id | Served by | Input $/1M | Output $/1M | | --- | --- | --- | --- | | `anthropic/claude-opus-4-8` | Anthropic Claude Opus 4.8 | $5.00 | $25.00 | | `anthropic/claude-opus-4-7` | Anthropic Claude Opus 4.7 | $5.00 | $25.00 | | `anthropic/claude-sonnet-5` | Anthropic Claude Sonnet 5 | $2.00 | $10.00 | | `anthropic/claude-sonnet-4-6` | Anthropic Claude Sonnet 4.6 | $3.00 | $15.00 | | `anthropic/claude-haiku-4-5` | Anthropic Claude Haiku 4.5 | $1.00 | $5.00 | | `anthropic/claude-fable-5` | Anthropic Claude Fable 5 | $10.00 | $50.00 | | `openai/gpt-5.5` | OpenAI GPT-5.5 | $5.00 | $30.00 | | `openai/gpt-5.4` | OpenAI GPT-5.4 | $2.50 | $15.00 | | `openai/gpt-5.4-mini` | OpenAI GPT-5.4 mini | $0.75 | $4.50 | | `openai/gpt-5.4-nano` | OpenAI GPT-5.4 nano | $0.20 | $1.25 | | `openai/gpt-5.3-codex` | OpenAI GPT-5.3 Codex | $1.75 | $14.00 | | `gemini/gemini-3.1-pro-preview` | Google Gemini 3.1 Pro (preview) | $2.00 | $12.00 | | `gemini/gemini-3.1-flash-lite-preview` | Google Gemini 3.1 Flash Lite (preview) | $0.25 | $1.50 | | `xai/grok-4.5` | xAI Grok 4.5 | $2.00 | $6.00 | | `xai/grok-4.3` | xAI Grok 4.3 | $1.25 | $2.50 | | `deepseek/deepseek-v4-pro` | DeepSeek V4 Pro | $0.435 | $0.87 | | `deepseek/deepseek-v4-flash` | DeepSeek V4 Flash | $0.14 | $0.28 | | `moonshot/kimi-k2.7-code` | Moonshot Kimi K2.7 Code | $0.95 | $4.00 | | `moonshot/kimi-k2.6` | Moonshot Kimi K2.6 | $0.60 | $3.00 | | `glm/glm-5.2` | Z.ai GLM-5.2 | $1.40 | $4.40 | | `glm/glm-4.6` | Z.ai GLM-4.6 | $0.60 | $2.20 | | `minimax/MiniMax-M3` | MiniMax M3 | $0.30 | $1.20 | | `qwen/qwen3-max` | Qwen3 Max | $1.20 | $6.00 | | `qwen/qwen3.7-plus` | Qwen3.7 Plus | $0.40 | $1.60 | Accepted id forms: send the `lab/model` id or the bare model name (`claude-haiku-4-5`, `gpt-5.4-mini`) — Claude Code and Codex send bare ids, both resolve to the same offering. A trailing `[1m]`, a provider/region prefix (`anthropic/`, `us.anthropic.`), and a date stamp are tolerated. Unsupported ids (`gpt-5.5-codex`, `gpt-5.2`) return `unknown model`; Tokun never substitutes a different model. ## Integration recipes Any agent runner with an OpenAI base URL works. Set `OPENAI_BASE_URL` to the Tokun gateway and `OPENAI_API_KEY` to your `sk-...` key, and choose a Tokun model id. Codex: ```bash export OPENAI_BASE_URL="https://api.tokun.sh/v1" export OPENAI_API_KEY="sk-..." codex --model openai/gpt-5.5 # or: anthropic/claude-opus-4-8 ``` OpenCLAW: ```bash OPENAI_BASE_URL=https://api.tokun.sh/v1 OPENAI_API_KEY=sk-... OPENAI_MODEL=openai/gpt-5.5 ``` Hermes: ```bash OPENAI_BASE_URL=https://api.tokun.sh/v1 OPENAI_API_KEY=sk-... # model: anthropic/claude-opus-4-8 ``` ## Anthropic SDK / Claude Code The gateway serves the Anthropic Messages API at `POST /v1/messages`, so Anthropic SDK clients — including Claude Code — work against Tokun. The base URL has NO `/v1` suffix (the Anthropic SDK appends the path itself). Auth is the Anthropic-native `x-api-key` header; `Authorization: Bearer` also works. The `anthropic-version` and `anthropic-beta` headers are accepted and ignored. Claude Code: ```bash export ANTHROPIC_BASE_URL="https://api.tokun.sh" export ANTHROPIC_API_KEY="sk-..." export ANTHROPIC_MODEL="anthropic/claude-opus-4-8" claude ``` Anthropic SDK (Python): ```python import anthropic client = anthropic.Anthropic( base_url="https://api.tokun.sh", api_key="sk-...", ) msg = client.messages.create( model="anthropic/claude-opus-4-8", # or "openai/gpt-5.5" — protocol ≠ model max_tokens=1024, messages=[{"role": "user", "content": "Say hello in one word."}], ) print(msg.content[0].text) ``` Use a Tokun model id (`anthropic/claude-opus-4-8`, `anthropic/claude-sonnet-4-6`, `claude-haiku-4-5`) — or the bare Anthropic-native id on its own (`claude-opus-4-8`, `claude-haiku-4-5`), which Tokun normalizes to the same offering, so Claude Code's default and `/model` picker work without pinning `ANTHROPIC_MODEL`. A trailing `[1m]`, a `*.anthropic.` Bedrock prefix, and a date stamp are tolerated. An id with no served match returns a clear `invalid_request_error` (never a silent substitution). Supported: text conversations (buffered + streaming with the official Anthropic SSE event protocol), system prompts (string or text blocks), client tools (tools / tool_use / tool_result) and tool_choice (auto/any/tool/none), stop_sequences, temperature / top_p, max_tokens (required, as in the official API), `/v1/messages/count_tokens` (free conservative estimate), and prompt caching (`cache_control`) — honored and billed at cache rates on native Anthropic-dialect routes (cache-read 0.1×, cache-write 1.25×/2.0× by TTL tier), accepted and ignored on OpenAI chat-bridge routes. Extended `thinking`: supported. `thinking: {"type":"enabled","budget_tokens":N}` enables extended thinking (validated like the official API: `budget_tokens` ≥ 1024 and < `max_tokens`); the `output_config.effort` dial (low/medium/high/xhigh/max) also enables it, with or without the `thinking` param (an explicit budget wins when both are present; `thinking: {"type":"disabled"}` wins over effort). Responses carry signed `thinking` blocks before the text; streaming emits the official thinking_delta / signature_delta events; `redacted_thinking` blocks pass through. Replayed `thinking` / `redacted_thinking` blocks in message history round-trip upstream intact (signatures preserved — required for multi-turn tool use). Thinking tokens bill as ordinary output tokens. Extended thinking is forwarded verbatim across ALL channels — automatic, official, reseller, and discount: nothing strips reasoning at runtime — a credential pinned to the discount channel forwards it too (TXE-670 reversed the earlier pinned-discount degrade). Anthropic web search (`web_search`) is supported and billed per search on Anthropic-dialect routes (a web-search request that can't be served natively fails closed rather than downgrading). Not supported — rejected with a clear `invalid_request_error` rather than silently ignored: image / document blocks, server tools other than Anthropic web search (e.g. code execution), mcp_servers, structured outputs via the deprecated top-level output_format (use output_config.format, which IS supported). Errors use the Anthropic envelope (`{"type":"error","error":{"type":...,"message":...}}`) with the same statuses as the OpenAI surface: 401 `authentication_error`, 400 `invalid_request_error` (incl. unknown model), 402 `billing_error` (insufficient balance), 403 `permission_error` (key budget), 429 `rate_limit_error`, 503 `overloaded_error`, 5xx `api_error`. ## The three channels Tokun can serve a model from one of three channel types. They serve the *same model*; they differ in who you ultimately buy capacity from and the price. - **Direct / official** — the model owner or a first-party cloud (Anthropic direct, or clouds like Google Vertex, Azure OpenAI, AWS Bedrock). The canonical source. - **Resellers** — aggregators that resell official capacity (e.g. OpenRouter, GMI), priced at or slightly above official. - **Discount providers** — independent hosts serving the same model below reseller/official pricing. The cheapest channel; how Tokun lowers your bill. You choose the model; Tokun chooses the channel that serves it. In V0, `anthropic/claude-opus-4-8` and `openai/gpt-5.5` route to their direct/official providers (Anthropic, OpenAI); reseller and discount channels roll in over time, and Tokun then picks among them to lower cost. The upstream that actually served a request is recorded as the `served_vendor` usage dimension (e.g. `anthropic`, `openai`); a fan-out request whose upstream can't be determined is recorded as `unattributed`, never blank. ## Key FAQ **Is it really the same model?** Yes — a model id maps to one logical model (`anthropic/claude-opus-4-8` → Anthropic Claude Opus 4.8). Whichever channel serves it, the weights are the same; only the billing surface and price differ. **How does billing work?** Prepaid and per-token. Each request: input_tokens × input_rate + output_tokens × output_rate, times any account multiplier. Tokun places a balance hold for the estimated max cost before forwarding, then settles the exact charge from the upstream's reported token usage. A request that fails before the upstream responds releases the hold (no charge). **Is my data private?** Prompts/completions pass through in transit to the serving upstream and are processed transiently to operate and meter the service. Tokun logs request *metadata* (timestamps, model, token counts, latency, status, key) for billing/security, not bodies as a product feature. The serving upstream handles content under its own policy. See https://tokun.sh/privacy. **Why is it cheaper?** Tokun can route the same model to a lower-cost channel (discount provider or reseller) instead of always paying official list price, behind one endpoint and one balance. **Does extended thinking work?** Yes — Extended thinking is supported and forwarded verbatim on ALL channels — automatic, official, reseller, and discount, INCLUDING a credential explicitly pinned to the discount channel; nothing is stripped at runtime (TXE-670 reversed the earlier pinned-discount degrade). Enable via thinking: {"type":"enabled","budget_tokens":N} (budget ≥ 1024 and < max_tokens) or the output_config.effort dial; signed thinking blocks round-trip on multi-turn tool use (streaming thinking_delta / signature_delta). **Rate limits?** No fixed RPS quota in beta. Effective limits are economic: prepaid balance and per-key budget caps. `402` = insufficient balance; `403` = key budget exhausted; `429` = an upstream provider limit. Beta service, no uptime SLA. **How do I pick a channel?** You pick the model; Tokun picks the channel. There is no per-request channel selector in the request body today; `served_vendor` on usage records shows which channel served each call after the fact. ## Error codes | Status | Meaning | | --- | --- | | `400` | Malformed request, or unknown model id | | `401` | Missing or invalid credential | | `402` | Insufficient prepaid balance | | `403` | Per-key budget exceeded | | `429` | Upstream provider rate limit (passed through) | | `500` | Gateway error (model resolution / pricing / reserve / internal) | | `502` | Upstream error | | `503` | No execution pool available / model temporarily unavailable | | `504` | Upstream timeout (passed through) | `429` and `5xx` may be passed through verbatim from the upstream, or originate at the gateway (e.g. `500` for an internal failure, `503` when no pool can serve the model). ## Links - Console: https://tokun.sh - API keys: https://tokun.sh/api-keys - Billing: https://tokun.sh/billing - Human docs: https://tokun.sh/docs - Claude Code integration guide: https://tokun.sh/docs/integrations/claude-code - Privacy: https://tokun.sh/privacy - Terms: https://tokun.sh/terms - Support: support@tokun.sh