Create an OpenRouter credential with a clear workload purpose and credit boundary. Verify the account route before granting the application broader model or routing freedom.
Before you start
Decide which workspace should own the experiment and which process will use the key. Record the application purpose and responsible operator before creating the secret. This makes a later rotation or budget investigation tractable when the account has several model integrations.
OpenRouter’s authentication guide supports named keys and optional credit limits, sent as Bearer credentials on direct HTTP requests. Official documentation.
Open the key controls through the official documentation. Check that the account and workspace are the intended ones, then inspect available billing and model-access controls. A key is an authorization mechanism; it is not proof that every catalog model is appropriate for the application’s data or output requirements.
Step-by-step: create the key
- Open OpenRouter’s official key settings and select the intended workspace.
- Create a key with a label that identifies the application and environment.
- Set its available credit limit and related controls deliberately before copying the secret.
- Place the secret in protected server-side configuration and record its purpose without the value.
The screenshots for this guide must come from the real current account workflow. Capture navigation and controls only after cropping unrelated information and redacting identifiers and secrets. The pending-image record makes any uncollected step explicit instead of replacing evidence with a mock console.
Keep the key’s purpose narrow enough that it can be retired without disrupting an unrelated application. If several services share a credential, create an inventory of those consumers before deployment. Otherwise a routine rotation can turn into a search through unknown background jobs.
Set a spending limit / budget alerts
Workspace budgets add enforced spending boundaries at workspace scope, with configurable reset behavior described in the workspace guide. Official documentation.
Coordinate the workspace and key controls instead of treating them as interchangeable. Decide which boundary should trigger first for the experiment and how a worker should present the resulting state. A stopped request should remain visible as a budget condition, not be transformed into a generic empty answer.
Inspect the available notification destination and test the application’s own stop path with a local simulation. Do not intentionally spend through a budget merely to demonstrate the rejection. The useful application test is that an account-limit response pauses work and preserves unfinished tasks for a deliberate restart.
Verify the key: first call with cURL and Python
curl https://openrouter.ai/api/v1/chat/completions --max-time 60 -H "Authorization: Bearer $OPENROUTER_API_KEY" -H "Content-Type: application/json" -d '{"model":"~openai/gpt-sol-latest","messages":[{"role":"user","content":"Hello"}],"max_tokens":512}'
import os
import sys
import json
from openai import OpenAI, APIStatusError
model = os.environ.get("OPENROUTER_MODEL", "~openai/gpt-sol-latest")
if "--bad-model" in sys.argv:
model = "ai-api-hub/invalid-model"
client = OpenAI(
api_key=os.environ["OPENROUTER_API_KEY"],
base_url="https://openrouter.ai/api/v1",
timeout=60.0,
max_retries=0,
)
try:
result = client.chat.completions.create(
model=model,
messages=[{"role":"user","content":"Explain why an API response should identify the model used, in one sentence."}],
max_tokens=512,
)
payload = result.model_dump()
if payload.get("error"):
print(json.dumps(payload["error"], ensure_ascii=False))
raise SystemExit(1)
if not result.choices:
print("No completion choices returned")
raise SystemExit(1)
print(result.choices[0].message.content)
print("Resolved model:", result.model)
print("finish_reason:", result.choices[0].finish_reason)
print(result.usage.model_dump_json() if result.usage else "Usage unavailable")
except APIStatusError as exc:
print(f"HTTP {exc.status_code}")
print(exc.response.text)
raise SystemExit(1)
finally:
client.close()
This example uses the documented latest-family alias and prints the concrete model returned. For a fixed regression baseline, select a concrete catalog identifier through OPENROUTER_MODEL instead. Keep the selected identifier with the request when inspecting cost or output behavior.
The following response shape is schematic and was not captured from a live inference request.
{"id":"example-generation","model":"author/concrete-model","choices":[{"message":{"role":"assistant","content":"Example answer"},"finish_reason":"stop"}]}
Check the returned body as well as status. A parser should not assume that every response with a successful HTTP status has a valid completion. The script detects an error object before reading choices and stops if the expected result is absent.
Where to put the key
Store OPENROUTER_API_KEY in the environment of the server process. Follow the authentication guide for the Bearer header and avoid putting the credential in a public repository or browser bundle.
Keep application-attribution headers separate from authentication. They identify an application where used; they do not protect a secret or grant model access. The starter omits optional attribution fields so the minimum request is easy to inspect.
Verify the service launch path after deployment. A credential loaded by a development shell may be absent from a background worker. Check configuration presence without printing the secret, then run a safe minimal request from the actual process environment.
Common rejections
For authentication failure, inspect the active key and configured base URL. For insufficient credit, inspect both account balance and the key’s remaining allowance. For a routing failure, inspect whether the requested capabilities and account rules leave an eligible endpoint. These cases require different corrective actions.
Use OpenRouter error handling to preserve the response code and normalized error type where present. Read credit and capacity scopes before changing account controls.
Rotate and revoke
Deploy a replacement to every identified consumer, verify it from the real launch paths and retire the previous key. Keep a record of infrequent scheduled jobs so a rotation does not appear successful only because the affected job has not run yet.
If a key is exposed, OpenRouter directs the owner to delete the compromised key and create a replacement. Official documentation.
Inspect usage after an exposure and remove the leaked value from the place it appeared. Deleting a local file alone does not revoke the credential, and changing a label does not invalidate copies. Preserve enough safe incident evidence to explain the response without copying the secret into another record.
Use the AI API cost calculator to turn the model and workload you are considering into an estimate.
Last verified · Source ↗
Frequently asked questions
Does the attribution header authenticate a request?
Why name the key for a workload?
What does the starter’s latest alias imply?
Where should the production secret live?
What should I inspect for insufficient credit?
Does deleting a file revoke a leaked key?
Sources
- OpenRouter quickstart ↗
- Models and pricing schema ↗
- Authentication ↗
- Credit and rate limits ↗
- Errors and debugging ↗
- Provider routing ↗
- Free model variants ↗
- Free router ↗
- Workspace budgets ↗
- Prompt caching ↗
- BYOK ↗
- Provider logging ↗
- Batch quickstart ↗
- Latest aliases ↗
Last verified · Source ↗