Passare da OpenRouter richiede una riga

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

Tre cose da verificare

  1. Usi la base URL giusta per il suo SDK — L'SDK di OpenAI vuole https://api.orcarouter.ai/v1. Gli altri due vogliono https://api.orcarouter.ai — il percorso se lo aggiunge ciascuno.
  2. Sostituisca la chiave API con quella di OrcaRouter — Il valore cambia — una chiave OpenRouter qui non autentica —, ma il posto no: leggiamo la stessa intestazione che il suo SDK invia già.
  3. Mantenga i nomi dei modelli — 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.

Prima e dopo: la riga che cambia

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.

OpenAI — Python

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

Anthropic — Python

  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.

Gemini — TypeScript

  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.

Esempi completi per ogni SDK

Import, client e una chiamata reale. Eseguibile così com'è, una volta impostata ORCAROUTER_API_KEY nel tuo ambiente.

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

ID dei modelli: cosa rinominare

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 OpenRouterSu OrcaRouter
openrouter/autoorcarouter/auto
openrouter/freeorcarouter/free
Qualsiasi altro router openrouter/Nessun equivalente: indichi invece un modello
Qualsiasi ID vendor/model, come anthropic/claude-sonnet-4Lo stesso ID, invariato

Differenze di fatturazione

Quattro cose che non facciamo

Meglio saperlo ora che scoprirlo in produzione.

Domande frequenti

OrcaRouter può sostituire OpenRouter così com'è?

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.

Quale base URL serve a ciascun SDK?

L'SDK di OpenAI vuole https://api.orcarouter.ai/v1. Gli altri due vogliono https://api.orcarouter.ai — il percorso se lo aggiunge ciascuno.

Posso continuare a usare la mia chiave API di OpenRouter?

Il valore cambia — una chiave OpenRouter qui non autentica —, ma il posto no: leggiamo la stessa intestazione che il suo SDK invia già.

Cosa sostituisce openrouter/auto e openrouter/free?

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.

Il routing di fallback funziona allo stesso modo?

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.

Come vedo quanto è costata una richiesta?

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.

X-Title e HTTP-Referer identificano ancora la mia app?

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.

Che fine fanno provider e transforms nelle mie richieste?

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.

Quali endpoint offre OrcaRouter?

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 nello stesso formato?

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.