Cost & Fallback Basics
8 examples to get you started with OpenRouter cost control and provider fallback - 5 basic and 3 intermediate.
You will call the chat API, set provider order, enable or disable fallbacks, sort by price, read usage cost, and sketch a per-key spend cap.
Prerequisites
- Python 3.11+ recommended
- OpenRouter account with credits and an API key
- Optional: a Management API key if you create keys with credit limits via API
python -m venv .venv && source .venv/bin/activate
pip install openai requests
export OPENROUTER_API_KEY="sk-or-v1-..."
# Optional management key for /api/v1/keys (not for chat):
# export OPENROUTER_MANAGEMENT_KEY="sk-or-v1-..."Basic Examples
1. Call OpenRouter Once and Read Cost
Start with a single completion so you see the usage object OpenRouter always returns.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.environ["OPENROUTER_API_KEY"],
default_headers={
"HTTP-Referer": "https://localhost", # optional app attribution
"X-OpenRouter-Title": "cost-fallback-basics",
},
)
resp = client.chat.completions.create(
model="openai/gpt-4o-mini", # verify slug at build
messages=[{"role": "user", "content": "Reply with one word: pong"}],
)
print(resp.choices[0].message.content)
print(resp.usage) # includes cost when provided by OpenRouter- One request in, text plus usage out.
- No provider prefs yet; OpenRouter load-balances for price and uptime.
- Treat
usage.costas the amount charged for that generation (verify field names at build).
2. Prefer a Provider Order With Fallbacks
Pin preferred hosts, then allow others if those fail.
resp = client.chat.completions.create(
model="meta-llama/llama-3.3-70b-instruct",
messages=[{"role": "user", "content": "Name two colors."}],
extra_body={
"provider": {
"order": ["together", "fireworks", "deepinfra"],
"allow_fallbacks": True,
}
},
)
print(resp.choices[0].message.content)orderis tried first, in list sequence.- With
allow_fallbacks: True(default), non-listed providers may still serve as backups. - Copy exact provider slugs from the model page when you need variants like
deepinfra/turbo.
3. Disable Fallbacks for a Strict Path
Fail closed when only your ordered providers may answer.
resp = client.chat.completions.create(
model="meta-llama/llama-3.3-70b-instruct",
messages=[{"role": "user", "content": "Say hi"}],
extra_body={
"provider": {
"order": ["together", "fireworks"],
"allow_fallbacks": False,
}
},
)- If both listed providers fail, the request errors instead of wandering.
- Use this for compliance drills, not for maximum uptime.
- Pair with monitoring so you notice the stricter error rate.
4. Sort Providers by Price (:floor Shortcut)
Force lowest-price routing for a slug without writing a full provider object.
resp = client.chat.completions.create(
model="meta-llama/llama-3.3-70b-instruct:floor",
messages=[{"role": "user", "content": "Summarize fallback in 8 words."}],
)
print(resp.choices[0].message.content)
# Equivalent: extra_body={"provider": {"sort": "price"}}:floorsetsprovider.sortto"price".- Load balancing is disabled when you set
sortororder. - Cheap is not always best for tool-calling quality; measure your agent tasks.
Related: Cost-Based Routing: Sending Cheap Tasks to Cheap Models
5. Check Key Credits Before a Batch
Poll GET /api/v1/key so a long agent job does not die mid-run on 402.
import requests
r = requests.get(
"https://openrouter.ai/api/v1/key",
headers={"Authorization": f"Bearer {os.environ['OPENROUTER_API_KEY']}"},
)
r.raise_for_status()
info = r.json()["data"]
print("limit:", info.get("limit"))
print("limit_remaining:", info.get("limit_remaining"))
print("usage:", info.get("usage"), "daily:", info.get("usage_daily"))limit/limit_remainingdescribe an optional per-key credit cap.- Account balance and key cap both can produce 402 Payment Required.
- Log these fields in CI or a cron before heavy eval suites.
Intermediate Examples
6. Combine Provider Order With Model Fallbacks
Survive both host failure and full model unavailability.
resp = client.chat.completions.create(
model="anthropic/claude-sonnet-4.5", # verify at build
messages=[{"role": "user", "content": "Outline a 3-step plan."}],
extra_body={
"models": [
"anthropic/claude-sonnet-4.5",
"openai/gpt-4o-mini",
"google/gemini-2.5-flash", # verify slugs at build
],
"provider": {
"allow_fallbacks": True,
"data_collection": "deny", # optional privacy filter
},
},
)
print("served model:", resp.model)
print("usage:", resp.usage)- Provider hops try to keep the primary model.
- The
modelslist walks alternate models when the primary cannot serve. - You are billed for the model that actually ran.
7. Cap a New Key With the Management API
Create a customer or staging key with a hard dollar limit (management key required).
import os
import requests
mgmt = os.environ["OPENROUTER_MANAGEMENT_KEY"]
resp = requests.post(
"https://openrouter.ai/api/v1/keys/",
headers={
"Authorization": f"Bearer {mgmt}",
"Content-Type": "application/json",
},
json={
"name": "agent-staging",
"limit": 25.0, # credit limit in USD-equivalent credits
"limit_reset": "monthly", # or daily / weekly / null; verify enums at build
},
)
resp.raise_for_status()
print(resp.json()) # includes key secret once on create; store securely- Management keys cannot call chat completions.
- Use separate keys per agent environment (dev / staging / prod).
- Reset policies contain runaway loops without wiping the whole account.
8. Tiny Cost-Aware Agent Step
Route classification to a cheap model and hard reasoning to a stronger one.
def complete(model: str, prompt: str, **provider):
return client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}],
extra_body={"provider": provider} if provider else None,
)
def agent_step(user_text: str) -> str:
route = complete(
"openai/gpt-4o-mini",
f"Classify as CHEAP or HARD (one word): {user_text}",
sort="price",
).choices[0].message.content or ""
model = (
"openai/gpt-4o-mini"
if "CHEAP" in route.upper()
else "anthropic/claude-sonnet-4.5"
)
out = complete(model, user_text, allow_fallbacks=True)
print("route:", route, "model:", out.model, "usage:", out.usage)
return out.choices[0].message.content or ""
print(agent_step("What is 2+2?"))- Application routing multiplies savings beyond provider sort alone.
- Keep the classifier prompt short; it still costs tokens.
- Always retain fallbacks on the expensive path so HARD tasks still complete.
Related: How OpenRouter's Provider Fallback Actually Protects Uptime
What to Practice Next
- Tighten
only/ignorelists once you know which providers pass evals. - Add latency sort for interactive agents.
- Wire spend alerts from
usage.costand the Activity or Analytics APIs.
Related: Comparing OpenRouter's Per-Model Pricing Against Direct Provider Rates
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.