Registering for OpenRouter and Creating Your API Key
What this lesson covers
OpenRouter is one API key and one endpoint in front of hundreds of models from Anthropic, OpenAI, Google, Meta, Mistral, DeepSeek, Qwen and more. In this lesson you create an account, add credits, mint a key with its own spend cap, prove it works, and learn the two things OpenRouter gives you that a direct provider key cannot: model switching by string, and automatic fallback. Budget about 25 minutes.
Why a gateway instead of direct keys
- One key, many vendors. Swap
anthropic/claude-fable-5.1foropenai/gpt-6-astraby changing a string — no new account, no new billing relationship. - OpenAI-compatible. The endpoint speaks the Chat Completions format, so the official OpenAI SDKs work by changing one base URL.
- Automatic fallback. If a provider errors or is overloaded, OpenRouter transparently routes to the next one.
- Per-key spend caps. Each key can carry its own credit limit — useful for a demo, a client, or a class.
The trade-off: you are adding a middleman. For a single-vendor production app, a direct key is simpler. For prototyping, comparison and multi-model agents — the bulk of this course — the gateway wins.
Before you start
- A GitHub or Google account, or an email address (OpenRouter supports social sign-in).
- A terminal, and a card or crypto wallet if you want paid models.
- Roughly $5–$10 to start. You can explore free models first without paying anything.
Console tour (2 minutes)
Sign in at openrouter.ai. The pages you will actually use:
| Page | What it is for |
|---|---|
| Models | Every model, its exact id string, context length, per-token price and which providers serve it. This is your source of truth for model IDs. |
| Settings → Keys | Create, name, cap, and delete API keys. (openrouter.ai/keys lands here too.) |
| Settings → Credits | Top up, enable auto top-up, see your balance. |
| Activity | Every request: model, tokens, cost, latency. Your debugging and cost-control page. |
| Settings → Privacy | Whether prompts may be logged, and whether to allow providers that train on data. |
| Rankings | What other apps are actually using — a decent sanity check when picking a model. |
Lab 1 — Create the account and add credits
- Go to https://openrouter.ai and sign up with GitHub, Google or email.
- Open Settings → Credits and note your balance. New accounts get a small allowance to try things.
- Optional but recommended: add $10. Two reasons — it unlocks paid models, and it lifts free-model limits from 50 requests/day to 1,000 requests/day.
- Check the fee before you click: card top-ups carry 5.5% (minimum $0.80), crypto 5%. There is no markup on inference itself — you pay provider rates.
- While you are here, open Settings → Privacy and decide your logging posture. Prompts are not logged by default; opting in earns a 1% discount.
Done when: Settings → Credits shows a non-zero balance and you know your logging setting.
Lab 2 — Create your API key
- Go to Settings → Keys and click Create Key.
- Name:
openrouter-api-course. Name it after the app that will use it. - Credit limit: set $5. This is the feature to actually use — a capped key cannot drain your balance if it leaks or if a loop runs away. You can also set a reset period (daily/weekly/monthly).
- Create it and copy the key immediately — it starts with
sk-or-v1-and is shown once.
Never ship this key to a browser or mobile app. Anything on a user's device can be read by that user. OpenRouter partners with GitHub on secret scanning and will email you if your key turns up in a public repo — delete it and create a new one the moment that happens.
Done when: the key list shows openrouter-api-course with a $5 limit and a masked value.
Lab 3 — Store the key safely
macOS / Linux:
export OPENROUTER_API_KEY="sk-or-v1-..."
Windows PowerShell:
$env:OPENROUTER_API_KEY = "sk-or-v1-..."
[Environment]::SetEnvironmentVariable("OPENROUTER_API_KEY","sk-or-v1-...","User")
Per project, a .env plus a .gitignore entry in the same commit:
# .env
OPENROUTER_API_KEY=sk-or-v1-...
# .gitignore
.env
Done when: echo $OPENROUTER_API_KEY prints the key and git status does not list .env.
Lab 4 — Your first call
The endpoint is https://openrouter.ai/api/v1/chat/completions and auth is a bearer token:
curl https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-fable-5.1",
"messages": [{"role": "user", "content": "Reply with the words: router works."}]
}'
Two headers are required: Authorization: Bearer ... and Content-Type: application/json. Two more are optional and worth sending — they attribute your traffic on the public rankings:
-H "HTTP-Referer: https://your-site.example"
-H "X-OpenRouter-Title: Your App Name"
Because the endpoint is OpenAI-compatible, the official SDKs work with one changed base URL. Python (pip install openai):
import os
from openai import OpenAI
client = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.environ["OPENROUTER_API_KEY"],
)
completion = client.chat.completions.create(
model="anthropic/claude-fable-5.1",
messages=[{"role": "user", "content": "Reply with the words: router works."}],
)
print(completion.choices[0].message.content)
TypeScript / Node (npm i openai):
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://openrouter.ai/api/v1',
apiKey: process.env.OPENROUTER_API_KEY,
});
const completion = await client.chat.completions.create({
model: 'anthropic/claude-fable-5.1',
messages: [{ role: 'user', content: 'Reply with the words: router works.' }],
});
console.log(completion.choices[0].message.content);
Done when: you get a completion back and the request appears on the Activity page with its cost.
Lab 5 — Swap the model, then go free
This is the whole point of the gateway. Change nothing but the model string and re-run Lab 4 against each of these:
openai/gpt-6-astragoogle/gemini-3.8-flashdeepseek/deepseek-v4.1-flash
Then find a model on the Models page whose id ends in :free and run it. Free variants cost nothing but are rate limited: 20 requests/minute, and 50 requests/day until you have bought $10 of credits (then 1,000/day).
Model IDs change. The IDs above were current when this lesson was written. Always confirm against the Models page or GET https://openrouter.ai/api/v1/models rather than trusting a hard-coded list in any tutorial — including this one.
Done when: you have run the same code against at least three different vendors and one free model.
Lab 6 — Inspect your key, then add a fallback
Every key can report on itself:
curl https://openrouter.ai/api/v1/key \
-H "Authorization: Bearer $OPENROUTER_API_KEY"
Read limit_remaining (credits left on this key), usage (all-time, daily, weekly, monthly) and is_free_tier (false once you have purchased credits). Worth wiring into a health check in any real app.
Now make a request that survives a provider outage. Pass a models array instead of a single model — OpenRouter tries them in order:
{
"models": ["anthropic/claude-fable-5.1", "openai/gpt-6-astra", "google/gemini-3.8-flash"],
"messages": [{"role": "user", "content": "Say hello."}]
}
Or hand the choice over entirely with the auto router, "model": "openrouter/auto", which picks a model for each prompt. You can constrain it with an allowed_models plugin config using wildcards such as anthropic/*.
Done when: GET /api/v1/key returns your usage, and a models-array request returns a completion (check Activity to see which one actually served it).
Troubleshooting
| Symptom | Status | Fix |
|---|---|---|
| Key rejected | 401 | Missing or malformed Authorization: Bearer header, or a deleted key. Check for a stray newline or quotes in the env var. |
| Payment required — even on a free model | 402 | Negative account balance blocks everything, free variants included. Top up. |
| Key spend cap hit | 402 | The per-key credit limit you set in Lab 2 is exhausted. Raise it or wait for its reset period. |
| Too many requests | 429 | Free-model limits (20/min, 50/day before $10 of credits). Extra accounts or keys do not bypass this — spread load across models or buy credits. |
| Unknown model | 400 | The model id is wrong or the model was retired. Copy it from the Models page. |
| No provider available | 404 / 502 | Every provider for that model is down or filtered out by your provider preferences. Use a models fallback array. |
| Works in curl, fails in the SDK | — | base_url not set to https://openrouter.ai/api/v1, or the SDK is reading OPENAI_API_KEY instead of your OpenRouter key. |
Knowledge check
Q1. What is the base URL and which header carries the key?
https://openrouter.ai/api/v1, and Authorization: Bearer sk-or-v1-.... Note this differs from Anthropic's direct API, which uses x-api-key.
Q2. Why can you use the OpenAI Python SDK against OpenRouter?
The endpoint implements the Chat Completions format, so only base_url and api_key change.
Q3. You get a 402 on a :free model. How is that possible?
A negative account balance blocks all models, free ones included. It can also mean the per-key credit limit is exhausted.
Q4. What does buying $10 of credits change about free models?
The daily cap rises from 50 requests/day to 1,000 requests/day. The per-minute limit stays at 20.
Q5. How do you make one request survive a provider outage?
Send a models array instead of a single model; OpenRouter tries them in order. Provider-level fallback within a single model happens automatically.
Q6. What are the two optional headers for, and are they required?
HTTP-Referer and X-OpenRouter-Title attribute your traffic on the public rankings. Purely optional — calls work without them.
Q7. Which key type can create other keys?
A Management API key, created on the Management API Keys page. It works only against /api/v1/keys and cannot call completion endpoints.
FAQ
Is OpenRouter free?
The service takes no markup on inference — you pay provider rates. It earns on credit top-ups: 5.5% (minimum $0.80) by card, 5% by crypto. There are also genuinely free model variants with low rate limits.
Do I still need accounts with OpenAI, Anthropic and Google?
No. That is the point — one account and one key reach all of them. You can optionally bring your own keys (BYOK) if you already have provider contracts; pay-as-you-go includes a large monthly BYOK allowance, above which a 5% fee applies.
Are my prompts logged?
Not by default. You can opt into logging for a 1% discount, and Privacy settings control whether providers that train on data may serve your requests.
How do I keep costs predictable?
Three layers: a per-key credit limit, cheap models for development (a -flash or :free variant), and the Activity page to spot which route is costing you money.
Can I call it from the browser?
Not with this key. Put it on a server and have the client call your server — the pattern the Next.js, Node.js, PHP and n8n lessons in this section all follow.
What is openrouter/auto?
A router "model" that picks a real model per prompt. Convenient for a demo, but for production pin an explicit id so behaviour and cost are predictable.
Does OpenRouter support streaming, tools and vision?
Yes, via the standard Chat Completions fields — subject to what the underlying model supports. Check the model's page before relying on tool calling or image input.
How do I find the right model id?
The Models page, or GET https://openrouter.ai/api/v1/models for a machine-readable list with prices and context lengths.
Resources
- OpenRouter home — https://openrouter.ai
- API keys — https://openrouter.ai/settings/keys
- Credits and top-ups — https://openrouter.ai/settings/credits
- Activity / usage log — https://openrouter.ai/activity
- Model catalogue and prices — https://openrouter.ai/models
- Quickstart — https://openrouter.ai/docs/quickstart
- Authentication — https://openrouter.ai/docs/api-reference/authentication
- Rate limits and credits — https://openrouter.ai/docs/api-reference/limits
- Model routing and fallbacks — https://openrouter.ai/docs/features/model-routing
- Provisioning / Management API keys — https://openrouter.ai/docs/features/provisioning-api-keys
- FAQ — https://openrouter.ai/docs/faq
Next
Keep the key in your environment — Calling the OpenRouter API with cURL and REST Basics takes the request from Lab 4 apart field by field.