Migrate from OpenAI SDK
Switching from OpenAI to Routor takes two minutes and three line changes. Your existing SDK, your existing patterns, your existing code. Nothing else moves.
Before and After
Node.js / TypeScript
Before:
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
const response = await client.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: prompt }],
});
After:
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.ROUTOR_API_KEY, // change 1
baseURL: "https://api.routor.ai/v1", // change 2
});
const response = await client.chat.completions.create({
model: "auto", // change 3
messages: [{ role: "user", content: prompt }],
});
Three changes. Everything else stays the same.
Python
Before:
from openai import OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}]
)
After:
from openai import OpenAI
client = OpenAI(
api_key=os.environ["ROUTOR_API_KEY"],
base_url="https://api.routor.ai/v1",
)
response = client.chat.completions.create(
model="auto",
messages=[{"role": "user", "content": prompt}]
)
Environment Variable
Add your Routor key to .env:
ROUTOR_API_KEY=sk-routor-YOUR_KEY_HERE
Keep your OPENAI_API_KEY if you use OpenAI directly anywhere else. They are completely separate.
What Changes in Practice
| OpenAI direct | With Routor |
|---|
| Model used | Always GPT-5.5 | Right model for each prompt |
| Cost | Fixed GPT-5.5 pricing | 25 to 70% lower on average |
| Failover | None | Automatic across 13 providers |
model in response | "gpt-4o" | Actual model used |
| Response format | OpenAI format | Identical OpenAI format |
Gradual Rollout
You do not have to switch everything at once. Routor runs alongside direct OpenAI calls. They are independent. Keep critical features on a direct GPT-5.5 call while you test Routor on lower-stakes requests:
const routorClient = new OpenAI({
apiKey: process.env.ROUTOR_API_KEY,
baseURL: "https://api.routor.ai/v1",
});
// Regular requests go through Routor
const regularResponse = await routorClient.chat.completions.create({
model: "auto",
messages: [...],
});
// High-stakes requests: force COMPLEX tier minimum
const criticalResponse = await routorClient.chat.completions.create({
model: "auto",
routor_tier_floor: "COMPLEX",
messages: [...],
});
Verifying the Switch Worked
Check the model field in the response body. It will show the actual model used instead of "auto":
console.log(response.model);
// "kimi-k2.6" — the provider's bare model id
// Non-streaming responses also include a routor object with the full decision:
console.log((response as any).routor);
// { model: "moonshot/kimi-k2.6", tier: "LIGHT", profile: "auto", savingsPct: 83.2, ... }
Or check the Logs page in your dashboard to see routing decisions in real time.
TypeScript users: extra fields like routor_tier_floor are accepted by the API and passed through by the SDK at runtime, but the SDK’s types don’t know them — add // @ts-expect-error above the line or cast the params object.