Cambi la sua base URL e inserisca una chiave OrcaRouter. I modelli, l’SDK e il resto del codice restano esattamente come sono: l'unica cosa da rinominare sono gli id dei router openrouter/.
OrcaRouter parla nativamente le API di OpenAI, Anthropic e Gemini, quindi può tenere l'SDK che usa già. In ogni frammento, le righe che iniziano con - sono da rimuovere e quelle che iniziano con + sono da aggiungere.
client = OpenAI(
- base_url="https://openrouter.ai/api/v1",
+ base_url="https://api.orcarouter.ai/v1",
api_key=ORCAROUTER_API_KEY,
)È l’unica modifica al codice. Inserisca anche una chiave OrcaRouter: i nomi dei modelli, i messaggi e lo streaming restano uguali, a meno che non chiami un id di router openrouter/.
client = Anthropic(
+ base_url="https://api.orcarouter.ai",
api_key=ORCAROUTER_API_KEY,
)Parliamo l'API di Anthropic in modo nativo, cosa che OpenRouter non fa. Se chiamava Claude tramite l'SDK di OpenAI per adattarsi a OpenRouter, può smettere.
const ai = new GoogleGenAI({
apiKey: ORCAROUTER_API_KEY,
+ httpOptions: { baseUrl: "https://api.orcarouter.ai" },
});Parliamo nativamente anche l'API di Gemini, quindi l'SDK di Google funziona senza modifiche.
Import, client e una chiamata reale. Eseguibile così com'è, una volta impostata ORCAROUTER_API_KEY nel tuo ambiente.
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"}]}]
}'Usiamo gli stessi nomi vendor/model, quindi anthropic/claude-sonnet-4 funziona così com'è. L'eccezione sono gli id dei router openrouter/ di OpenRouter: quelli vanno rinominati.
| Su OpenRouter | Su OrcaRouter |
|---|---|
openrouter/auto | orcarouter/auto |
openrouter/free | orcarouter/free |
| Qualsiasi altro router openrouter/ | Nessun equivalente: indichi invece un modello |
| Qualsiasi ID vendor/model, come anthropic/claude-sonnet-4 | Lo stesso ID, invariato |
Meglio saperlo ora che scoprirlo in produzione.
Per la maggior parte delle integrazioni, sì. Cambi la base URL e sostituisca la chiave con una di OrcaRouter; SDK, nomi dei modelli, messaggi e streaming restano uguali. Le eccezioni sono gli ID dei router openrouter/ propri di OpenRouter, che vanno rinominati, e le quattro cose che OrcaRouter volutamente non fa, elencate sopra.
L'SDK di OpenAI vuole https://api.orcarouter.ai/v1. Gli altri due vogliono https://api.orcarouter.ai — il percorso se lo aggiunge ciascuno.
Il valore cambia — una chiave OpenRouter qui non autentica —, ma il posto no: leggiamo la stessa intestazione che il suo SDK invia già.
I router di OrcaRouter sono quelli con orcarouter/. Due corrispondono direttamente ai loro: usi orcarouter/auto al posto di openrouter/auto e orcarouter/free al posto di openrouter/free — stessa idea in entrambi i casi, scegliamo noi un modello per lei al momento della richiesta, e il secondo la tiene sul livello a costo zero. Gli altri loro router non hanno una controparte qui, quindi indichi direttamente un modello.
Sposti models e route dentro extra_body. Tutto il resto è uguale: elenchi i modelli in ordine di preferenza e li proviamo uno dopo l'altro. Minimo 2 modelli, massimo 5. Vale la pena farlo bene. Al livello superiore non li leggiamo, quindi i suoi fallback smettono di funzionare in silenzio; e sulle installazioni che inoltrano il corpo della richiesta così com'è, il modello riceve quei campi in più e può rifiutare del tutto la chiamata.
Leggi X-Orca-Request-Id dalla risposta, poi chiama /v1/generation. Un 501 vuol dire che su questo deployment le consultazioni dei costi sono disattivate.
Invii X-Title e la sua applicazione manterrà il proprio nome nelle statistiche senza alcuna modifica; leggiamo anche i nomi di header propri di OpenRouter. HTTP-Referer da solo indica il nome della sua applicazione soltanto se il dominio è tra quelli che già riconosciamo, quindi invii un header di titolo se vuole esserne certo. Questa riga è qui perché non li rimuova per sbaglio.
Non usiamo né l’uno né l’altro. Su un canale normale vengono scartati prima che la richiesta raggiunga il modello; su un canale configurato per inoltrare il corpo grezzo vengono trasmessi, e un fornitore rigoroso può rifiutare la richiesta. Toglierli è la scelta sicura in entrambi i casi.
Tutto quello che si aspetta, più alcuni che OpenRouter non ha. Disponibili qui e non su OpenRouter: /v1/messages, /v1beta/models … generateContent, /v1/rerank e /v1/realtime. Non disponibili: /v1/fine-tunes, GET /v1/files e /v1/images/variations.
Gli errori tornano nella stessa forma che già gestisce. Si regoli sullo stato HTTP: riprovi un 429 quando inviamo un Retry-After, attenda e riprovi un 5xx tranne 501 — che significa che quella chiamata non la serviamo affatto — e tratti un 4xx su una chiamata del relay come qualcosa da correggere nella richiesta. L'eccezione è un 404 da /v1/generation: può semplicemente voler dire che la richiesta non è ancora liquidata, quindi lo riprovi per poco. Non legga error.type come l'origine: orcarouter_api_error è sempre nostro, ma per alcuni nostri guasti inviamo deliberatamente il vocabolario del fornitore così che il suo SDK prenda il ramo abituale: un limite di frequenza applicato da noi e uno applicato dal modello dicono entrambi rate_limit_error. Citi X-Orca-Request-Id quando ha bisogno che cerchiamo una singola chiamata.