改一下 base URL,再換成 OrcaRouter 金鑰。你的模型、SDK 和其餘程式碼完全不用動——只有 openrouter/ 開頭的路由器 ID 需要改名。
OrcaRouter 原生支援 OpenAI、Anthropic 和 Gemini 的 API,你可以繼續使用現有的 SDK。每段程式碼中,以 - 開頭的行是要刪除的,以 + 開頭的行是要新增的。
client = OpenAI(
- base_url="https://openrouter.ai/api/v1",
+ base_url="https://api.orcarouter.ai/v1",
api_key=ORCAROUTER_API_KEY,
)程式碼上就改這一處。另外把金鑰換成 OrcaRouter 的——你的模型名稱、訊息和串流都不用變,除非你呼叫的是 openrouter/ 開頭的路由器 ID。
client = Anthropic(
+ base_url="https://api.orcarouter.ai",
api_key=ORCAROUTER_API_KEY,
)我們直接支援 Anthropic 的 API,而 OpenRouter 不支援。如果你先前為了配合 OpenRouter 而用 OpenAI SDK 呼叫 Claude,現在可以不用了。
const ai = new GoogleGenAI({
apiKey: ORCAROUTER_API_KEY,
+ httpOptions: { baseUrl: "https://api.orcarouter.ai" },
});我們同樣直接支援 Gemini 的 API,Google SDK 不必修改即可使用。
包含匯入、用戶端初始化與一次真實呼叫。只要環境變數 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/ 路由器 ID,那些需要改名。
| 在 OpenRouter 上 | 在 OrcaRouter 上 |
|---|---|
openrouter/auto | orcarouter/auto |
openrouter/free | orcarouter/free |
| 其他 openrouter/ 路由器 | 沒有對應項——請直接寫一個具體模型 |
| 任何 vendor/model 形式的 ID,例如 anthropic/claude-sonnet-4 | 同一個 ID,不需更動 |
與其上線後才發現,不如現在就知道。
對大多數整合來說可以。改一下 base URL,再換成 OrcaRouter 金鑰;你的 SDK、模型名稱、訊息和串流輸出都維持不變。例外是 OpenRouter 自己的 openrouter/ 路由器 ID 需要改名,以及上面列出的 OrcaRouter 刻意不做的四件事。
OpenAI SDK 需要 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 個。值得好好改。留在最外層我們不會讀取,於是你的 fallback 會悄悄失效;而在啟用請求內容原樣轉送的部署上,模型會收到這些多餘欄位,並可能直接拒絕這次呼叫。
從回應標頭讀取 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 狀態碼處理:帶 Retry-After 的 429 可以重試;5xx 退避後重試,但 501 例外——它表示這個呼叫我們根本不提供;中繼呼叫回傳 4xx 則應當去改你的請求。例外是 /v1/generation 的 404:它可能只是這筆請求還沒結算完,可以短暫重試幾次。不要把 error.type 當作來源判斷:orcarouter_api_error 一定是我們這邊的,但我們會刻意用服務商自己的說法來標註我們自己的某些故障,好讓你的 SDK 走它原本的分支——我們施加的限流和模型施加的限流都寫作 rate_limit_error。需要我們查某一次呼叫時,請附上 X-Orca-Request-Id。