Migrating from another router
Already talking to an OpenAI-compatible inference router?
Switching to IIG is a base-URL swap plus a fresh key. Everything on this
page names the live endpoint that backs it; the full reference is the
API reference, generated from the running wire at
GET /openapi.json.
1 · One prompt — hand the switch to your coding agent
Paste this into the coding agent working on your codebase. It repoints the base URL, moves the key into the environment, and keeps every existing call working:
Repoint this codebase's LLM calls at my IIG router. - OpenAI-wire SDKs: set the base URL to https://your-iig-host/v1 (the OPENAI_BASE_URL env var, or the SDK's base_url option). The chat wire is POST /v1/chat/completions (streaming included), the Responses dialect is POST /v1/responses, and embeddings are served at POST /v1/embeddings there. - Anthropic SDKs and Claude Code: set ANTHROPIC_BASE_URL to https://your-iig-host — the Messages dialect is POST /v1/messages on that base. - Read the API key from the IIG_API_KEY environment variable; never hardcode key material. Keys look like sk-iig-v1-... and ride the Authorization: Bearer header (the Messages door also accepts the Anthropic SDKs' x-api-key header). - Keep every existing call working: model ids, streaming, and tool use are unchanged on this wire. The live catalog is GET /v1/models; GET /coverage lists what is (and is not) served. Then verify with one small call and run the test suite.
Doing it by hand instead: it is exactly those two
exports — export OPENAI_BASE_URL="https://your-iig-host/v1"
(or export ANTHROPIC_BASE_URL="https://your-iig-host" for
Claude SDKs) plus your key in the environment. All four doors share one
routing and billing spine, so model ids, balances, and spend limits
behave identically whichever dialect you speak.
2 · Key format
Mint a key in the console. Keys look like
sk-iig-v1-… and ride the usual
Authorization: Bearer header; the Messages door also accepts
the Anthropic SDKs' x-api-key header. Key material is shown
once at mint and stored hashed — treat it like any provider secret.
Per-key spend caps and UTC day/week/month windows are set on the key
itself.
3 · Model ids: catalog, class, meta
The catalog is GET /v1/models (live effective prices,
retention tier with its policy citation, provider jurisdiction); machine
pickers fetch the compact GET /v1/models/chooser in one call.
Three id families route a request:
- Catalog ids — a concrete provider model, exactly as
listed. Append
:nitro(fastest measured route first) or:floor(cheapest first) to re-sort candidate routes. - Class mode —
class/<name>ids resolve per account to whatever model the account's class binds; the serving class comes back in thex-iig-classheader. - Meta ids —
iig/auto,iig/cheap,iig/fast,iig/free,iig/eu: curated ladders the router walks for you.iig/echo-standardis the built-in echo model, so a keyless router still answers.
A router-local min_privacy body field sets a retention
floor — the router refuses rather than serves below it; the auditable
zero-retention report is GET /v1/endpoints/zdr.
4 · The x-iig-* headers
Buffered inference responses settle billing into response headers; streams surface the generation id early and report usage in the stream's tail chunk instead.
x-iig-cost-microusd— what the call cost, micro-USD.x-iig-balance-microusd— the balance after settlement.x-iig-generation-id— resolve per-generation billing metadata atGET /v1/generation(?id=); content is never stored, only metadata.x-iig-privacy-tier— the serving route's cited retention tier.x-iig-provider-hq— the provider's sourced headquarters country, when known.x-iig-class— the resolved class on class-mode calls.x-iig-usage-type—byokwhen the call dispatched on your own stored provider key.
Request tagging for your own analytics: an
x-iig-tags request header (k=v pairs) or a
tags body object — router-local, stripped before dispatch,
never forwarded upstream.
Rate limits and admission: past a per-key/account rate
limit the router answers 429 rate_limited, at
capacity 503 server_busy, and at an account's
open-reservations bound 429 holds_exceeded —
the 429/503 replies carry a Retry-After header in whole
seconds; back off and retry rather than hammering.
5 · What is (and is not) served
GET /coverage is the honest wire map: every caller-facing
route, real or stub. Routes this router does not serve (audio, images,
files, batches, moderation, rerank) refuse with the stable code
not_supported instead of a mystery 404 — so a stock SDK
fails loudly and precisely, never silently.