Измените base URL и подставьте ключ OrcaRouter. Ваши модели, ваш SDK и весь остальной код остаются ровно такими, как есть, — переименовать нужно только идентификаторы роутеров openrouter/.
OrcaRouter нативно поддерживает API OpenAI, Anthropic и Gemini, поэтому вы остаётесь на том SDK, которым уже пользуетесь. В каждом фрагменте строки, начинающиеся с -, нужно удалить, а строки, начинающиеся с +, — добавить.
client = OpenAI(
- base_url="https://openrouter.ai/api/v1",
+ base_url="https://api.orcarouter.ai/v1",
api_key=ORCAROUTER_API_KEY,
)Это единственная правка в коде. Ещё подставьте ключ OrcaRouter — названия моделей, сообщения и стриминг остаются прежними, если только вы не вызываете идентификатор роутера openrouter/.
client = Anthropic(
+ base_url="https://api.orcarouter.ai",
api_key=ORCAROUTER_API_KEY,
)Мы поддерживаем API Anthropic напрямую, а OpenRouter — нет. Если вы вызывали Claude через SDK OpenAI, чтобы подстроиться под OpenRouter, от этого можно отказаться.
const ai = new GoogleGenAI({
apiKey: ORCAROUTER_API_KEY,
+ httpOptions: { baseUrl: "https://api.orcarouter.ai" },
});API Gemini мы тоже поддерживаем напрямую, поэтому SDK Google работает без изменений.
Импорты, клиент и один настоящий вызов. Запускается как есть, как только в окружении задана ORCAROUTER_API_KEY.
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"}]}]
}'Мы используем те же имена вида vendor/model, поэтому anthropic/claude-sonnet-4 работает как есть. Исключение — собственные идентификаторы роутеров openrouter/ у OpenRouter: их переименовывают.
| В OpenRouter | В OrcaRouter |
|---|---|
openrouter/auto | orcarouter/auto |
openrouter/free | orcarouter/free |
| Любой другой роутер openrouter/ | Аналога нет — укажите конкретную модель |
| Любой ID вида vendor/model, например anthropic/claude-sonnet-4 | Тот же ID без изменений |
Лучше узнать сейчас, чем обнаружить в продакшене.
Для большинства интеграций — да. Смените base URL и подставьте ключ OrcaRouter; SDK, названия моделей, сообщения и стриминг остаются прежними. Исключения — собственные ID роутеров openrouter/ у OpenRouter, которые переименовываются, и четыре вещи, которых OrcaRouter сознательно не делает (они перечислены выше).
SDK от OpenAI ждёт https://api.orcarouter.ai/v1. Двум другим нужен https://api.orcarouter.ai — путь каждый дописывает сам.
Значение меняется — ключ OpenRouter здесь не пройдёт аутентификацию, — но место остаётся прежним: мы читаем тот заголовок, который ваш SDK уже отправляет.
Роутеры OrcaRouter — это те, что с orcarouter/. Два из них прямо соответствуют их роутерам: используйте orcarouter/auto вместо openrouter/auto и orcarouter/free вместо openrouter/free; идея та же, мы подбираем модель за вас в момент запроса, а второй оставляет вас на бесплатном уровне. У остальных их роутеров здесь соответствия нет — укажите конкретную модель.
Перенесите models и route внутрь extra_body. Всё остальное работает так же: перечислите модели в порядке предпочтения, и мы попробуем их по очереди. Минимум 2 модели, максимум 5. Стоит сделать это аккуратно. На верхнем уровне мы их не читаем, поэтому резервные модели тихо перестают работать, а в развёртываниях, которые передают тело запроса без изменений, модель получит лишние поля и может отклонить вызов целиком.
Прочитайте X-Orca-Request-Id из ответа и вызовите /v1/generation. Ответ 501 означает, что на этой установке запросы стоимости отключены.
Отправляйте X-Title — и ваше приложение сохранит своё имя в аналитике без каких-либо правок; мы также читаем собственные названия заголовков OpenRouter. Один только HTTP-Referer назовёт ваше приложение, лишь если его домен есть в списке уже известных нам, так что для надёжности отправляйте заголовок с названием. Этот пункт здесь для того, чтобы вы не удалили их по ошибке.
Мы не используем ни то, ни другое. На обычном канале они отбрасываются ещё до того, как запрос дойдёт до модели; на канале, настроенном на пересылку исходного тела, они уходят дальше, и строгий поставщик может отклонить запрос. Убрать их — безопасный вариант в любом случае.
Всё, чего вы ожидаете, плюс несколько, которых нет у OpenRouter. Есть здесь, но нет у OpenRouter: /v1/messages, /v1beta/models … generateContent, /v1/rerank и /v1/realtime. Недоступны: /v1/fine-tunes, GET /v1/files и /v1/images/variations.
Ошибки возвращаются в том же виде, который вы уже обрабатываете. Действуйте по HTTP-статусу: повторяйте 429, когда мы присылаем Retry-After; на 5xx делайте паузу и повторяйте, кроме 501 — он означает, что этот вызов мы вообще не обслуживаем; а 4xx на вызове релея считайте тем, что нужно исправить в запросе. Исключение — 404 от /v1/generation: он может означать лишь то, что запрос ещё не рассчитан, так что повторите его несколько раз подряд. Не читайте error.type как источник: orcarouter_api_error — всегда наш, но для некоторых собственных сбоев мы намеренно присылаем словарь провайдера, чтобы ваш SDK пошёл по обычной ветке: и наш лимит запросов, и лимит модели одинаково называются rate_limit_error. Указывайте X-Orca-Request-Id, когда нужно, чтобы мы нашли конкретный вызов.