Authenticating and Configuring the OpenRouter Base URL
Pointing an OpenAI-compatible client at OpenRouter is mostly three settings: base URL, API key, and model slug.
Search across all documentation pages
Pointing an OpenAI-compatible client at OpenRouter is mostly three settings: base URL, API key, and model slug.
Get those wrong and every higher-level agent framework fails in confusing ways.
OpenRouter authenticates with a Bearer API key and exposes an OpenAI-compatible root at https://openrouter.ai/api/v1 (verify at build).
Configure your SDK once, inject the key from the environment, and keep optional attribution headers separate from credentials.
Create a single shared client factory that sets base URL + key so agent code never reimplements auth.
import os
from openai import OpenAI
OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1"
def openrouter_client() -> OpenAI:
key = os.environ.get("OPENROUTER_API_KEY")
if not key:
raise RuntimeError("OPENROUTER_API_KEY is not set")
return OpenAI(
base_url=OPENROUTER_BASE_URL,
api_key=key,
default_headers={
"HTTP-Referer": os.environ.get("APP_URL", "https://localhost"),
"X-OpenRouter-Title": os.environ.get("APP_NAME", "agent-app"),
},
)When to reach for this:
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="openai/gpt-4o-mini", # verify at build
messages=[
{"role": "system", "content": "Be concise."},
{"role": "user", "content": "What is OpenRouter in one sentence?"},
],
extra_headers={
"HTTP-Referer": "https://example.com",
"X-OpenRouter-Title": "auth-recipe",
},
)
print(completion.choices[0].message.content)import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://openrouter.ai/api/v1",
apiKey: process.env.OPENROUTER_API_KEY,
defaultHeaders: {
"HTTP-Referer": "https://example.com",
"X-OpenRouter-Title": "auth-recipe",
},
});
const completion = await client.chat.completions.create({
model: "openai/gpt-4o-mini", // verify at build
messages: [{ role: "user", content: "What is OpenRouter in one sentence?" }],
});
console.log(completion.choices[0].message.content);curl https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"openai/gpt-4o-mini","messages":[{"role":"user","content":"ping"}]}'What this demonstrates:
Authorization| Piece | Value |
|---|---|
| Header | Authorization: Bearer <OPENROUTER_API_KEY> |
| Key creation | openrouter.ai keys UI (verify at build) |
| Optional credit limits | Per-key spend caps in the dashboard |
| Optional attribution | HTTP-Referer, X-OpenRouter-Title |
If a key is exposed, revoke it in the dashboard and create a new one.
OpenRouter participates in secret scanning programs; treat email alerts as incidents.
| Mistake | Symptom |
|---|---|
Trailing path typos (/v1/v1) | 404 or opaque client errors |
| Leaving the OpenAI default host | 401 against wrong product / wrong key type |
| Using browser-exposed keys | Key theft and runaway spend |
| Mixing Anthropic Messages base path without docs | Wrong skin / wrong fields |
For OpenAI Chat Completions compatibility, use https://openrouter.ai/api/v1.
Other skins (Anthropic Messages, Responses API beta) may use related roots - verify docs before wiring.
OpenRouter also ships first-party clients (openrouter Python package, @openrouter/sdk TypeScript) that take apiKey without manually setting base URL.
They are fine for greenfield work.
This page focuses on the OpenAI SDK path because most agent stacks already depend on it.
# .env.example (never store real secrets in repo)
OPENROUTER_API_KEY=
OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
APP_URL=https://localhost
APP_NAME=my-agent
DEFAULT_MODEL=openai/gpt-4o-miniLoad with your platform's secret system in production.
Do not bake keys into container images or frontend bundles.
base_url / baseURL. Requests hit OpenAI and fail or bill the wrong account. Fix: shared client factory.model field or query string. Not supported for normal chat auth. Fix: Authorization header / SDK apiKey..env with live keys. Immediate rotate. Fix: gitignore + secret scanning.| Alternative | Use When | Don't Use When |
|---|---|---|
| OpenAI SDK + base URL (this page) | Existing OpenAI-shaped code | You want first-party OpenRouter types only |
| Official OpenRouter SDK | New services, full API surface | Team standard is already OpenAI SDK |
Raw fetch / requests | Scripts, debugging | Large apps needing retries and types |
| Framework plugins (LangChain, Vercel AI, etc.) | Framework-native apps | You have not verified base URL mapping yet |
| Direct provider APIs | Single-provider lock-in is OK | You need multi-model routing |
No.
Create keys in the OpenRouter dashboard even if you only call OpenAI-hosted models through OpenRouter.
Yes if you also set OPENAI_BASE_URL / client base_url to OpenRouter and your code reads those variables.
Prefer an explicit OPENROUTER_API_KEY name to avoid sending the wrong key to the wrong host.
Not for standard OpenRouter chat completions.
Use OpenRouter-documented headers for your product version.
Inference keys call models.
Management keys (where offered) administer keys and org settings - keep them off application servers if possible (verify product docs at build).
A valid key with exhausted credits returns payment-required style errors (402).
Auth succeeded; billing did not.
Avoid embedding secret keys in browsers.
Proxy through your backend or use a documented OAuth / user-key flow if you deliberately expose user-owned keys.
Provider preferences belong in the request body (provider object), not in auth headers.
Auth only proves who pays and who is allowed to call.
Use normal public HTTPS.
Corporate proxies that MITM TLS need their CA trust store configured on the client.
Usually a wrong base URL, double /v1, or env var not loaded in the process that runs the SDK.
Print the client configuration in a safe debug path (never print the full key).
They are for attribution and rankings.
They are not a substitute for auth and should not contain secrets.
Stack versions: Pins from the category manifest (verify at build): OpenRouter (~315+ models, July 2026 pricing/fees); LangGraph 1.0+; CrewAI 1.14+; Microsoft Agent Framework 1.0; Vercel AI SDK 6; Pydantic AI (latest); LlamaIndex (latest); OpenAI Agents SDK (latest + MCP); MCP (Linux Foundation governance); A2A (HTTP+SSE+JSON-RPC 2.0); Solana
@solana/web3.js+@solana/spl-token.
Reviewed by Chris St. John·Last updated Jul 16, 2026