OpenRouter API Key: How to Get, Use & Secure It
If you want to reach hundreds of models behind a single endpoint, the first practical step is getting an OpenRouter API key and wiring it into your code. OpenRouter is a well-built aggregator: one key, one prepaid balance, and an OpenAI-compatible surface that fronts models from OpenAI, Anthropic, Google, Mistral, Meta, and many open-weight hosts. This guide is the hands-on version — how to create a key, how OpenRouter authentication actually works over HTTP, working curl and Python examples against the real base URL, the security practices that keep a leaked key from becoming a bill, and how the bring-your-own-key (BYOK) model differs when you'd rather control spend at the source.
One note up front: OpenRouter's dashboard layout and limits evolve, so treat anything UI-specific as "check the current console." The mechanics below — bearer auth, the base URL, the OpenAI request shape — are stable.
How to get an OpenRouter API key
Creating a key takes a couple of minutes and no code:
- Sign in. Create an account or log in at openrouter.ai. You'll authenticate with an email or an OAuth provider.
- Open the Keys section. In your account settings, find the Keys (API keys) page. This is where every key you own is listed.
- Create a new key. Click to generate one, give it a recognisable name (for example
prod-backendorlocal-dev), and optionally set a credit limit scoped to that key. - Copy it once. OpenRouter shows the full secret a single time. Copy it straight into a secret store or an environment variable — if you lose it, you rotate rather than recover.
- Load credits. Because OpenRouter bills from a prepaid balance, top up before you expect real traffic, or your calls will fail once the balance hits zero.
OpenRouter keys are conventionally prefixed (you'll see something like sk-or-...), which makes them easy to spot in logs and secret scanners. Creating several scoped keys — one per environment or service — is good hygiene, since you can revoke or re-limit one without disturbing the others.
OpenRouter authentication: the Authorization bearer token
OpenRouter authentication follows the standard bearer token scheme. Every request carries your key in an Authorization header, formatted as Bearer followed by a space and the key:
Authorization: Bearer sk-or-your-key-here
That single header is what identifies and bills your account, so it is also the thing you must never leak. There's no separate handshake or token exchange — the OpenRouter bearer token is the credential, sent on each call over HTTPS. The other piece is the base URL.
The OpenAI-compatible base URL
OpenRouter exposes an OpenAI-compatible API at:
https://openrouter.ai/api/v1
Because it mirrors the OpenAI Chat Completions shape, most existing SDKs and tooling work after changing two things: the base URL and the key. You select among models by setting the model field to a provider-qualified ID (for example openai/gpt-4o-mini or anthropic/claude-3.5-sonnet) — check OpenRouter's models page for current IDs, since the catalog changes often. If you want the deeper background on why this swap works at all, see our explainer on the OpenAI-compatible API.
Optional ranking headers (HTTP-Referer and X-Title)
OpenRouter accepts two optional headers that have nothing to do with auth and don't affect billing — they're for attribution on OpenRouter's public app rankings and analytics:
HTTP-Referer— the URL of your site or app.X-Title— a human-readable name for your app.
Set them if you want your traffic attributed to your project on OpenRouter's leaderboards; omit them and your requests still work exactly the same. They are a nicety, not a requirement.
A working curl example
The fastest way to confirm a fresh key works is a single curl against chat completions. Read the key from an environment variable rather than pasting it on the command line (shell history is a common leak path):
export OPENROUTER_API_KEY="sk-or-your-key-here"
curl https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-H "Content-Type: application/json" \
-H "HTTP-Referer: https://your-app.example" \
-H "X-Title: Your App Name" \
-d '{
"model": "openai/gpt-4o-mini",
"messages": [
{"role": "user", "content": "Say hello in one short sentence."}
]
}'
The two ranking headers are optional — drop them and the call still succeeds. A 200 with an OpenAI-shaped JSON body means your key, balance, and base URL are all good; a 401 means the bearer token is wrong or missing, and a 402 typically points at an empty balance.
Using your OpenRouter API key with the Python openai client
Because the endpoint is OpenAI-compatible, you don't need an OpenRouter-specific library — the official openai Python package talks to it with two overrides, base_url and api_key:
from openai import OpenAI
import os
client = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.environ["OPENROUTER_API_KEY"],
)
resp = client.chat.completions.create(
model="openai/gpt-4o-mini", # use a current OpenRouter model ID
messages=[
{"role": "user", "content": "Give me one tip for storing API keys."}
],
extra_headers={
"HTTP-Referer": "https://your-app.example", # optional
"X-Title": "Your App Name", # optional
},
)
print(resp.choices[0].message.content)
The optional ranking headers ride along via extra_headers; remove that argument if you don't want attribution. Everything else — temperature, max_tokens, stream=True — behaves as it does against OpenAI, because the request and response shapes match. That same two-line override is what makes OpenRouter (and any OpenAI-compatible host) a drop-in target; our piece on what is OpenRouter covers how the routing behind that endpoint works.
OpenRouter API key security best practices
An OpenRouter key maps to a prepaid balance, so a leaked key is a direct path to spent credits. Standard secret-handling discipline applies, and it's worth being strict about:
- Keep it in environment variables or a secret manager. Never hard-code the key in source. Read it from
OPENROUTER_API_KEYin development and from a managed secret store (Vault, AWS/GCP Secrets Manager, your platform's secrets) in production. - Never commit it. Add
.envto.gitignore, and turn on push-protection or a secret scanner so a key can't slip into git history. If one does land in a commit, rotate immediately — rewriting history is not enough once it's been pushed. - Keep it server-side. Don't embed the key in a browser bundle, mobile app, or any client a user can inspect. Proxy LLM calls through your own backend so the secret never reaches the client.
- Scope and limit. Issue separate keys per environment and service, and set per-key credit limits where available. A leaked
local-devkey capped at a small balance is an annoyance; an uncapped production key is an incident. - Rotate regularly. Rotate on a schedule and immediately on any suspected exposure or staff change. Distinct, named keys make rotating one painless.
- Monitor usage. Watch your activity and spend in the dashboard, and alert on unexpected spikes. A sudden jump in token usage is often the first sign a key has leaked.
None of this is unique to OpenRouter — it's the same hygiene every provider key deserves — but the prepaid balance makes the blast radius of a leak immediate, so it pays to be disciplined from the first key you create.
The BYOK contrast: one key per provider, spend controlled at the source
OpenRouter's design means a single key unlocks the whole catalog, billed from one balance you top up. That's wonderfully convenient — and it's also the trade-off. You're buying inference through a reseller, so your spend, rate-limit standing, and provider relationship all live with the aggregator rather than with OpenAI or Anthropic directly.
A bring-your-own-key, zero-markup gateway inverts that. Instead of one aggregator key over a prepaid wallet, you bring each provider's own key — OpenAI, Anthropic, Gemini, Groq, Cerebras, DeepInfra, Mistral, xAI, and OpenRouter itself — and the gateway holds those keys and handles routing. You pay each provider directly at their published price, so you control spend at the source: provider-side budgets, rate limits, committed-use discounts, and existing credits all stay yours, and there's no markup layered on top because the gateway never sits in the money path. If you're weighing the two architectures, our what is an LLM gateway writeup goes deeper on routing and fallback.
The honest caveat: BYOK means you manage several provider keys instead of one, and you own their security — the practices above, multiplied across providers. In exchange you get raw provider pricing and exact per-call cost accounting. Which trade is right depends on whether you value one-key convenience or source-level control over spend.
That's the model flo2 is built for. You bring your own provider keys, set per-model prices, and get a single key that's drop-in compatible with both the OpenAI and Anthropic APIs; it routes each request to the cheapest or fastest qualifying model, with fallback when a provider fails — and because flo2 isn't in the money path, it adds zero token markup and you pay providers directly. It's free during Beta, so if owning your keys and your spend sounds like the right fit, the cheapest way to find out is to point a key at it and watch your real per-call costs.