Migrer depuis OpenRouter tient en une ligne

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.

Trois points à vérifier

  1. Utilisez la bonne base URL pour votre SDK — Le SDK OpenAI attend https://api.orcarouter.ai/v1. Les deux autres attendent https://api.orcarouter.ai — chacun ajoute son propre chemin.
  2. Remplacez votre clé API par votre clé OrcaRouter — 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.
  3. Gardez vos noms de modèles — 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.

Avant et après : la ligne qui change

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.

OpenAI — Python

  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/.

Anthropic — Python

  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.

Gemini — TypeScript

  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.

Exemples complets pour chaque SDK

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.

OpenAI — Python

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)

OpenAI — TypeScript

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);

OpenAI — cURL

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"}]
  }'

Anthropic — Python

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)

Anthropic — TypeScript

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);

Anthropic — cURL

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"}]
  }'

Gemini — Python

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)

Gemini — TypeScript

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);

Gemini — cURL

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"}]}]
  }'

Identifiants de modèle : ce qu'il faut renommer

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 OpenRouterSur OrcaRouter
openrouter/autoorcarouter/auto
openrouter/freeorcarouter/free
Tout autre routeur openrouter/Pas d'équivalent — indiquez plutôt un modèle
Tout identifiant vendor/model, par exemple anthropic/claude-sonnet-4Le même identifiant, inchangé

Différences de facturation

Quatre choses que nous ne faisons pas

Mieux vaut le savoir maintenant que le découvrir en production.

Questions fréquentes

OrcaRouter peut-il remplacer OpenRouter tel quel ?

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.

Quelle base URL faut-il pour chaque SDK ?

Le SDK OpenAI attend https://api.orcarouter.ai/v1. Les deux autres attendent https://api.orcarouter.ai — chacun ajoute son propre chemin.

Puis-je continuer à utiliser ma clé API OpenRouter ?

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.

Par quoi remplacer openrouter/auto et openrouter/free ?

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.

Le routage de repli fonctionne-t-il de la même façon ?

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.

Comment connaître le coût d'une requête ?

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.

X-Title et HTTP-Referer identifient-ils toujours mon application ?

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.

Que deviennent provider et transforms dans mes requêtes ?

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.

Quels endpoints OrcaRouter propose-t-il ?

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-elles sous la même forme ?

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.