OpenRouter: one API key for every model you actually use
I used to keep four separate API keys in my env file, Anthropic, OpenAI, Google, xAI, and four slightly different SDKs to match. OpenRouter replaced all of it with one key and one OpenAI-compatible endpoint, and the switch took about twenty minutes.
What it actually is
OpenRouter is a gateway: you send a normal chat-completions request, you pick the model with a vendor-prefixed string like anthropic/claude-fable-5 or google/gemini-3.1-pro, and OpenRouter routes it to whichever provider actually serves that model, normalizing the request and response format along the way. The benchmark page on this site pulls its live pricing straight from OpenRouter's model list, the same data your own requests get billed against.
Provider routing, not just model routing
The part that took me longest to understand: OpenRouter routes two separate decisions, which model answers, and which provider serves that model. Several providers can host the same open-weight model, Kimi K2.6 or DeepSeek V4 Pro for instance, at different prices and different uptime.
- By default OpenRouter load-balances across providers by price while weighting in recent uptime, so a provider having a bad week gets deprioritized automatically
- Append :floor to a model string to force the cheapest available provider, good for batch jobs where latency doesn't matter
- Append :nitro to force the fastest provider by throughput, good for anything user-facing
- Pass a provider order array if you want to pin a specific provider and only fall back when it's actually down
Model-level fallback is a different setting
Provider failover happens inside one model automatically. Model-level fallback is separate: you pass a models array in priority order, and OpenRouter walks down it on context-length errors, moderation flags, rate limits or downtime. I keep a cheap, reliable model last in that list on purpose, not my best model, my most boring one.
Order your fallback list so the last entry is the one you'd trust to answer when everything ahead of it has already failed.
What you give up
The real limitation: OpenRouter adds a small markup over calling a vendor directly, and it lags on day-one access to brand-new frontier models while terms get negotiated, Claude Fable 5 showed up on OpenRouter about a week after Anthropic's own API went live. You also lose some vendor-specific features that don't map cleanly onto the normalized schema, like Anthropic's extended-thinking token budgets, which need vendor-specific passthrough fields instead of working out of the box.
For prototyping across models, or running a fleet of open-weight coders, none of that matters. For a single production app married to one frontier model's specific features, calling that vendor directly is still the better call.
The migration itself is mechanical. Point your existing OpenAI-compatible client at OpenRouter's base URL and swap the model string for a vendor-prefixed one. Retry logic stays exactly as it was, because the wire format underneath doesn't change. That's it.