Zmień swój base URL i wstaw klucz OrcaRouter. Modele, SDK i cała reszta kodu zostają dokładnie takie, jakie są — zmienia się tylko identyfikatory routerów openrouter/.
OrcaRouter natywnie obsługuje API OpenAI, Anthropic i Gemini, więc zostajesz przy SDK, którego już używasz. W każdym fragmencie linie zaczynające się od - należy usunąć, a linie zaczynające się od + — dodać.
client = OpenAI(
- base_url="https://openrouter.ai/api/v1",
+ base_url="https://api.orcarouter.ai/v1",
api_key=ORCAROUTER_API_KEY,
)To jedyna zmiana w kodzie. Wstaw jeszcze klucz OrcaRouter — nazwy modeli, wiadomości i streaming zostają bez zmian, chyba że wywołujesz identyfikator routera openrouter/.
client = Anthropic(
+ base_url="https://api.orcarouter.ai",
api_key=ORCAROUTER_API_KEY,
)Obsługujemy API Anthropic natywnie, czego OpenRouter nie robi. Jeśli wywoływałeś Claude przez SDK OpenAI, żeby dopasować się do OpenRoutera, możesz z tego zrezygnować.
const ai = new GoogleGenAI({
apiKey: ORCAROUTER_API_KEY,
+ httpOptions: { baseUrl: "https://api.orcarouter.ai" },
});API Gemini również obsługujemy natywnie, więc SDK Google działa bez zmian.
Importy, klient i jedno prawdziwe wywołanie. Działa bez zmian, gdy tylko ORCAROUTER_API_KEY jest ustawiona w Twoim środowisku.
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"}]}]
}'Używamy tych samych nazw vendor/model, więc anthropic/claude-sonnet-4 działa bez zmian. Wyjątkiem są własne identyfikatory routerów openrouter/ w OpenRouterze: te się zmienia.
| W OpenRouter | W OrcaRouter |
|---|---|
openrouter/auto | orcarouter/auto |
openrouter/free | orcarouter/free |
| Każdy inny router openrouter/ | Brak odpowiednika — wskaż konkretny model |
| Każdy identyfikator vendor/model, np. anthropic/claude-sonnet-4 | Ten sam identyfikator, bez zmian |
Lepiej wiedzieć teraz niż odkryć to na produkcji.
W większości integracji tak. Zmień base URL i podstaw klucz OrcaRouter; SDK, nazwy modeli, wiadomości i streaming pozostają bez zmian. Wyjątki to własne identyfikatory routerów openrouter/ z OpenRouter, którym zmienia się nazwy, oraz cztery rzeczy, których OrcaRouter celowo nie robi, wymienione wyżej.
SDK OpenAI oczekuje https://api.orcarouter.ai/v1. Pozostałe dwa oczekują https://api.orcarouter.ai — ścieżkę każde dopisuje samo.
Wartość się zmienia — klucz OpenRouter nie uwierzytelni się tutaj — ale miejsce nie: czytamy ten nagłówek, który Twój SDK już wysyła.
Routery OrcaRoutera to te z orcarouter/. Dwa odpowiadają ich routerom wprost: użyj orcarouter/auto zamiast openrouter/auto i orcarouter/free zamiast openrouter/free — w obu przypadkach ta sama idea, dobieramy model za Ciebie w momencie zapytania, a drugi zostawia Cię na poziomie bezkosztowym. Pozostałe ich routery nie mają tu odpowiednika, więc wskaż konkretny model.
Przenieś models i route do wnętrza extra_body. Poza tym wszystko działa tak samo: wypisz modele w kolejności preferencji, a my spróbujemy ich po kolei. Minimum 2 modele, maksimum 5. Warto zrobić to porządnie. Na najwyższym poziomie ich nie czytamy, więc Twoje trasy zapasowe po cichu przestają działać, a we wdrożeniach, które przekazują treść zapytania bez zmian, model otrzyma te dodatkowe pola i może odrzucić całe wywołanie.
Odczytaj X-Orca-Request-Id z odpowiedzi, a potem wywołaj /v1/generation. 501 znaczy, że na tym wdrożeniu odpytywanie o koszt jest wyłączone.
Wyślij X-Title, a Twoja aplikacja zachowa swoją nazwę w statystykach bez żadnych zmian; czytamy też nazwy nagłówków samego OpenRoutera. Sam HTTP-Referer wskaże nazwę Twojej aplikacji tylko wtedy, gdy jej domena jest jedną z już rozpoznawanych, więc dla pewności wyślij nagłówek tytułu. Ten punkt jest tu po to, żebyś ich przez pomyłkę nie usunął.
Nie używamy żadnego z nich. Na zwykłym kanale są odrzucane, zanim żądanie dotrze do modelu; na kanale ustawionym na przekazywanie surowego ciała są przesyłane dalej, a restrykcyjny dostawca może żądanie odrzucić. Usunięcie ich jest bezpieczne w obu przypadkach.
Wszystko, czego oczekujesz, plus kilka, których OpenRouter nie ma. Dostępne tutaj, a niedostępne w OpenRouter: /v1/messages, /v1beta/models … generateContent, /v1/rerank i /v1/realtime. Niedostępne: /v1/fine-tunes, GET /v1/files i /v1/images/variations.
Błędy wracają w tym samym kształcie, który już obsługujesz. Kieruj się statusem HTTP: ponów 429, gdy wysyłamy Retry-After, odczekaj i ponów 5xx poza 501 — który oznacza, że tego wywołania w ogóle nie obsługujemy — a 4xx na wywołaniu relayu potraktuj jako coś do poprawienia w Twoim żądaniu. Wyjątkiem jest 404 z /v1/generation: może po prostu znaczyć, że żądanie jeszcze się nie rozliczyło, więc ponów je przez chwilę. Nie czytaj error.type jako źródła: orcarouter_api_error jest zawsze nasz, ale przy części własnych awarii celowo wysyłamy słownictwo dostawcy, żeby Twój SDK poszedł swoją zwykłą gałęzią — limit tempa nałożony przez nas i ten nałożony przez model mówią tak samo rate_limit_error. Podaj X-Orca-Request-Id, gdy potrzebujesz, żebyśmy odszukali pojedyncze wywołanie.