Changez votre base URL et remplacez la clé par une clé OrcaRouter. Vos modèles, votre SDK et le reste de votre code restent exactement tels quels — les identifiants de routeur openrouter/ sont le seul renommage.
OrcaRouter parle nativement les API d'OpenAI, d'Anthropic et de Gemini : vous gardez le SDK que vous utilisez déjà. Dans chaque extrait, les lignes qui commencent par - sont à supprimer et celles qui commencent par + sont à ajouter.
client = OpenAI(
- base_url="https://openrouter.ai/api/v1",
+ base_url="https://api.orcarouter.ai/v1",
api_key=ORCAROUTER_API_KEY,
)C’est la seule modification de code. Remplacez aussi la clé par une clé OrcaRouter — vos noms de modèles, vos messages et le streaming restent identiques, sauf si vous appelez un identifiant de routeur openrouter/.
client = Anthropic(
+ base_url="https://api.orcarouter.ai",
api_key=ORCAROUTER_API_KEY,
)Nous prenons en charge l'API d'Anthropic nativement, ce que OpenRouter ne fait pas. Si vous appeliez Claude via le SDK OpenAI pour vous adapter à OpenRouter, ce n'est plus nécessaire.
const ai = new GoogleGenAI({
apiKey: ORCAROUTER_API_KEY,
+ httpOptions: { baseUrl: "https://api.orcarouter.ai" },
});Nous prenons aussi en charge l'API Gemini nativement : le SDK Google fonctionne sans modification.
Les imports, le client et un appel réel. Exécutable tel quel, dès que ORCAROUTER_API_KEY est défini dans votre environnement.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.orcarouter.ai/v1",
api_key=os.environ["ORCAROUTER_API_KEY"],
)
response = client.chat.completions.create(
model="anthropic/claude-sonnet-4",
messages=[{"role": "user", "content": "Hello"}],
)
print(response.choices[0].message.content)import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.orcarouter.ai/v1",
apiKey: process.env.ORCAROUTER_API_KEY,
});
const response = await client.chat.completions.create({
model: "anthropic/claude-sonnet-4",
messages: [{ role: "user", content: "Hello" }],
});
console.log(response.choices[0].message.content);curl https://api.orcarouter.ai/v1/chat/completions \
-H "Authorization: Bearer $ORCAROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-sonnet-4",
"messages": [{"role": "user", "content": "Hello"}]
}'import os
from anthropic import Anthropic
client = Anthropic(
base_url="https://api.orcarouter.ai",
api_key=os.environ["ORCAROUTER_API_KEY"],
)
message = client.messages.create(
model="anthropic/claude-sonnet-4",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
)
print(message.content[0].text)import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://api.orcarouter.ai",
apiKey: process.env.ORCAROUTER_API_KEY,
});
const message = await client.messages.create({
model: "anthropic/claude-sonnet-4",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello" }],
});
console.log(message.content[0].text);curl https://api.orcarouter.ai/v1/messages \
-H "x-api-key: $ORCAROUTER_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-sonnet-4",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello"}]
}'import os
from google import genai
client = genai.Client(
api_key=os.environ["ORCAROUTER_API_KEY"],
http_options={"base_url": "https://api.orcarouter.ai"},
)
response = client.models.generate_content(
model="google/gemini-2.5-pro",
contents="Hello",
)
print(response.text)import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({
apiKey: process.env.ORCAROUTER_API_KEY,
httpOptions: { baseUrl: "https://api.orcarouter.ai" },
});
const response = await ai.models.generateContent({
model: "google/gemini-2.5-pro",
contents: "Hello",
});
console.log(response.text);curl "https://api.orcarouter.ai/v1beta/models/google/gemini-2.5-pro:generateContent" \
-H "x-goog-api-key: $ORCAROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [{"parts": [{"text": "Hello"}]}]
}'Nous utilisons les mêmes noms vendor/model : anthropic/claude-sonnet-4 fonctionne tel quel. L'exception, ce sont les identifiants de routeur openrouter/ propres à OpenRouter : ceux-là sont renommés.
| Sur OpenRouter | Sur OrcaRouter |
|---|---|
openrouter/auto | orcarouter/auto |
openrouter/free | orcarouter/free |
| Tout autre routeur openrouter/ | Pas d'équivalent — indiquez plutôt un modèle |
| Tout identifiant vendor/model, par exemple anthropic/claude-sonnet-4 | Le même identifiant, inchangé |
Mieux vaut le savoir maintenant que le découvrir en production.
Pour la plupart des intégrations, oui. Changez la base URL et remplacez votre clé par une clé OrcaRouter ; votre SDK, vos noms de modèles, vos messages et le streaming restent identiques. Les exceptions sont les identifiants de routeur openrouter/ propres à OpenRouter, qui sont renommés, et les quatre choses qu'OrcaRouter ne fait volontairement pas, listées plus haut.
Le SDK OpenAI attend https://api.orcarouter.ai/v1. Les deux autres attendent https://api.orcarouter.ai — chacun ajoute son propre chemin.
La valeur change — une clé OpenRouter ne permet pas de s'authentifier ici — mais pas l'emplacement : quel que soit l'en-tête que votre SDK envoie déjà, nous le lisons.
Les routeurs d'OrcaRouter sont ceux en orcarouter/. Deux correspondent directement aux leurs : utilisez orcarouter/auto à la place d'openrouter/auto, et orcarouter/free à la place d'openrouter/free — même principe dans les deux cas, nous choisissons un modèle pour vous au moment de la requête, et le second vous maintient sur le palier gratuit. Leurs autres routeurs n'ont pas de contrepartie ici : indiquez plutôt un modèle.
Déplacez models et route à l'intérieur de extra_body. Tout le reste est identique : listez vos modèles par ordre de préférence et nous les essayons l'un après l'autre. Au moins 2 modèles, au plus 5. Cela vaut la peine de le faire correctement. Au premier niveau nous ne les lisons pas, donc vos replis cessent silencieusement de fonctionner ; et sur les déploiements qui transmettent le corps de la requête tel quel, le modèle reçoit ces champs supplémentaires et peut refuser l'appel.
Lisez X-Orca-Request-Id dans la réponse, puis appelez /v1/generation. Une 501 signifie que la consultation des coûts est désactivée sur ce déploiement.
Envoyez X-Title et votre application conserve son nom dans vos statistiques, sans rien changer ; nous lisons aussi les noms d'en-têtes propres à OpenRouter. HTTP-Referer seul ne nomme votre application que si son domaine fait partie de ceux que nous reconnaissons déjà : envoyez un en-tête de titre si vous voulez en être sûr. Cette ligne est là pour que vous ne les supprimiez pas par erreur.
Nous n’utilisons ni l’un ni l’autre. Sur un canal normal, ils sont supprimés avant que la requête n’atteigne le modèle ; sur un canal configuré pour transmettre le corps brut, ils sont transmis et un fournisseur strict peut refuser la requête. Les retirer est le choix sûr dans les deux cas.
Tout ce à quoi vous vous attendez, plus quelques-uns que OpenRouter n'a pas. Disponibles ici et pas chez OpenRouter : /v1/messages, /v1beta/models … generateContent, /v1/rerank et /v1/realtime. Non disponibles : /v1/fine-tunes, GET /v1/files et /v1/images/variations.
Les erreurs reviennent dans la forme que vous gérez déjà. Agissez selon le statut HTTP : réessayez un 429 quand nous envoyons un Retry-After, temporisez puis réessayez un 5xx sauf 501 — qui signifie que nous ne servons pas cet appel du tout — et traitez un 4xx sur un appel de relais comme quelque chose à corriger dans votre requête. Le 404 de /v1/generation fait exception : il peut simplement signifier que la requête n'est pas encore soldée, réessayez-le brièvement. Ne lisez pas error.type comme l'origine : orcarouter_api_error est toujours le nôtre, mais nous envoyons délibérément le vocabulaire du fournisseur pour certaines de nos propres défaillances afin que votre SDK prenne sa branche habituelle — une limite de débit que nous appliquons et une que le modèle applique disent toutes deux rate_limit_error. Citez X-Orca-Request-Id lorsque vous avez besoin que nous recherchions un appel précis.