2026-06-03 · flo2 blog

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:

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:

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:

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.

One key, every model — zero markup.
Bring your own provider keys. flo2 routes to the cheapest, fastest model with fallback, racing and true cost accounting — free during Beta.
Get your flo2 key →
© 2026 flo2.com — the zero-markup LLM gateway & router. flow → to