Python (OpenAI client)
Use nRouter as a drop-in replacement with the OpenAI Python SDK
Last updated
If your codebase already uses the OpenAI Python client, you don't need to switch SDKs. Set base_url to https://api.nrouter.ai/v1 and use your sk-nrouter-... key as the api_key — no other changes.
Already using the OpenAI Python client elsewhere? This page is the minimal base-URL swap; the Python SDK guide walks through the same client in more depth.
Installation
pip install openaiSetup
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["NROUTER_API_KEY"],
base_url="https://api.nrouter.ai/v1",
)Chat Completion
response = client.chat.completions.create(
model="gpt-5.4-mini",
messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)Switching Providers
You don't need new credentials, new SDKs, or new endpoints to change models — just change the model string:
# OpenAI
client.chat.completions.create(model="gpt-5.4-mini", messages=[...])
# Google
client.chat.completions.create(model="gemini-2.5-flash", messages=[...])Anthropic Claude Models: To call Anthropic Claude models on nRouter, use the native Anthropic Messages wire format (
/v1/messages) via the officialnrouter-sdkor standard Anthropic client library pointed athttps://api.nrouter.ai.
Per-Request Overrides
The OpenAI SDK supports extra_body to forward nRouter-specific fields:
response = client.chat.completions.create(
model="gpt-5.5",
messages=[{"role": "user", "content": "Summarize Q1 earnings..."}],
extra_body={
"nrouter_prompt_template_id": "your-summarizer-id",
"nrouter_prompt_variables": {"language": "Spanish"},
"nrouter_cache": False,
},
)Guardrails are not one of these fields. You assign them in the dashboard at key, team, or organization scope — the narrowest scope that mentions a guardrail wins — and they run automatically on every request that scope covers.
Streaming
stream = client.chat.completions.create(
model="gpt-5.5",
messages=[{"role": "user", "content": "Write a short poem."}],
stream=True,
)
for chunk in stream:
content = chunk.choices[0].delta.content
if content is not None:
print(content, end="", flush=True)Response Headers
Every successful response carries:
x-nr-request-id— id for this call, and the join key for its spend rowx-nr-model— the model that actually served the requestx-nr-cost-status—exactwhen we priced the call,unpricedwhen we could notx-nr-request-cost— USD spend for this call. Absent whenx-nr-cost-statusisunpriced: nRouter never reports a cost of0for a call it could not pricex-nr-input-tokens,x-nr-output-tokens,x-nr-total-tokens— token counts as reported by the provider
Read them off response._response.headers (synchronous client) or via the with_raw_response accessor.
Next Steps
- Python SDK — Native nRouter Python SDK
- Node.js SDK — Same drop-in pattern for TypeScript
- Chat Completions API — Full API reference