Chuyển từ OpenRouter chỉ tốn một dòng

Đổi base URL và thay bằng khóa OrcaRouter. Các mô hình, SDK và phần còn lại của mã nguồn giữ nguyên hoàn toàn — chỉ các id router openrouter/ là phải đổi tên.

Ba điều cần kiểm tra

  1. Dùng đúng base URL cho SDK của bạn — SDK của OpenAI cần https://api.orcarouter.ai/v1. Hai SDK còn lại cần https://api.orcarouter.ai — mỗi cái tự thêm đường dẫn của nó.
  2. Thay bằng khóa OrcaRouter của bạn — Giá trị thay đổi — khóa OpenRouter không xác thực được ở đây — nhưng vị trí thì không: SDK của bạn đang gửi qua header nào, chúng tôi đọc header đó.
  3. Giữ nguyên tên mô hình — Chúng tôi dùng cùng cách đặt tên vendor/model, nên anthropic/claude-sonnet-4 dùng được ngay. Ngoại lệ là các id router openrouter/ của chính OpenRouter: những id đó phải đổi tên.

Trước và sau: dòng duy nhất thay đổi

OrcaRouter hỗ trợ sẵn API của OpenAI, Anthropic và Gemini, nên bạn giữ nguyên SDK đang dùng. Trong mỗi đoạn mã, các dòng bắt đầu bằng - là phần cần xóa, còn các dòng bắt đầu bằng + là phần cần thêm.

OpenAI — Python

  client = OpenAI(
-     base_url="https://openrouter.ai/api/v1",
+     base_url="https://api.orcarouter.ai/v1",
      api_key=ORCAROUTER_API_KEY,
  )

Đó là thay đổi mã nguồn duy nhất. Ngoài ra hãy thay bằng khóa OrcaRouter — tên mô hình, tin nhắn và streaming đều giữ nguyên, trừ khi bạn gọi một id router openrouter/.

Anthropic — Python

  client = Anthropic(
+     base_url="https://api.orcarouter.ai",
      api_key=ORCAROUTER_API_KEY,
  )

Chúng tôi hỗ trợ trực tiếp API của Anthropic, điều mà OpenRouter không có. Nếu bạn đang gọi Claude qua SDK của OpenAI để phù hợp với OpenRouter thì nay không cần nữa.

Gemini — TypeScript

  const ai = new GoogleGenAI({
    apiKey: ORCAROUTER_API_KEY,
+   httpOptions: { baseUrl: "https://api.orcarouter.ai" },
  });

Chúng tôi cũng hỗ trợ trực tiếp API của Gemini, nên SDK của Google chạy được mà không cần sửa.

Ví dụ đầy đủ cho từng SDK

Gồm phần import, khởi tạo client và một lệnh gọi thật. Chạy được ngay như vậy, chỉ cần đã đặt ORCAROUTER_API_KEY trong môi trường của bạn.

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 mô hình: những gì cần đổi tên

Chúng tôi dùng cùng cách đặt tên vendor/model, nên anthropic/claude-sonnet-4 dùng được ngay. Ngoại lệ là các id router openrouter/ của chính OpenRouter: những id đó phải đổi tên.

Trên OpenRouterTrên OrcaRouter
openrouter/autoorcarouter/auto
openrouter/freeorcarouter/free
Mọi router openrouter/ khácKhông có tương đương — hãy ghi rõ một mô hình
Mọi ID dạng vendor/model, ví dụ anthropic/claude-sonnet-4Giữ nguyên ID như cũ

Khác biệt về tính phí

Bốn điều chúng tôi không làm

Biết trước vẫn hơn là phát hiện khi đã chạy thật.

Câu hỏi thường gặp

OrcaRouter có thay thế trực tiếp OpenRouter được không?

Với hầu hết các tích hợp thì được. Đổi base URL và thay bằng khóa OrcaRouter; SDK, tên mô hình, tin nhắn và streaming đều giữ nguyên. Ngoại lệ là các ID router openrouter/ riêng của OpenRouter, vốn phải đổi tên, và bốn điều OrcaRouter cố ý không làm, đã liệt kê ở trên.

Mỗi SDK cần base URL nào?

SDK của OpenAI cần https://api.orcarouter.ai/v1. Hai SDK còn lại cần https://api.orcarouter.ai — mỗi cái tự thêm đường dẫn của nó.

Tôi có thể tiếp tục dùng khóa API OpenRouter không?

Giá trị thay đổi — khóa OpenRouter không xác thực được ở đây — nhưng vị trí thì không: SDK của bạn đang gửi qua header nào, chúng tôi đọc header đó.

Dùng gì thay cho openrouter/auto và openrouter/free?

Các router của OrcaRouter là nhóm orcarouter/. Hai cái tương ứng trực tiếp với của họ: dùng orcarouter/auto thay cho openrouter/auto, và orcarouter/free thay cho openrouter/free — cùng một ý tưởng, chúng tôi chọn mô hình giúp bạn ngay tại thời điểm gửi yêu cầu, và cái sau giữ bạn ở mức miễn phí. Các router còn lại của họ không có bản tương ứng ở đây, hãy nêu thẳng một mô hình.

Định tuyến dự phòng có hoạt động như cũ không?

Chuyển models và route vào bên trong extra_body. Mọi thứ khác vẫn như cũ: liệt kê các mô hình theo thứ tự ưu tiên và chúng tôi sẽ thử lần lượt. Tối thiểu 2 mô hình, tối đa 5. Đáng để làm cho đúng. Ở cấp ngoài cùng chúng tôi không đọc chúng, nên phương án dự phòng của bạn lặng lẽ ngừng hoạt động; và trên những bản triển khai chuyển tiếp nguyên vẹn phần thân yêu cầu, mô hình sẽ nhận các trường thừa đó và có thể từ chối hẳn lệnh gọi.

Làm sao xem một yêu cầu tốn bao nhiêu?

Đọc X-Orca-Request-Id từ phản hồi, rồi gọi /v1/generation. Nhận 501 nghĩa là bản triển khai này đã tắt tra cứu chi phí.

X-Title và HTTP-Referer có còn định danh ứng dụng của tôi không?

Hãy gửi X-Title thì ứng dụng của bạn vẫn giữ nguyên tên trong phần phân tích mà không cần sửa gì; chúng tôi cũng đọc các tên header riêng của OpenRouter. Chỉ gửi HTTP-Referer thì tên ứng dụng chỉ hiện ra nếu tên miền nằm trong danh sách chúng tôi đã nhận diện, nên muốn chắc chắn hãy gửi kèm header tiêu đề. Mục này có ở đây để bạn không xóa nhầm.

provider và transforms trong yêu cầu của tôi sẽ được xử lý thế nào?

Chúng tôi không dùng cả hai. Trên kênh thông thường, chúng bị loại bỏ trước khi yêu cầu tới mô hình; trên kênh được đặt chuyển tiếp nguyên thân yêu cầu, chúng được gửi tiếp và một nhà cung cấp khắt khe có thể từ chối yêu cầu. Bỏ chúng đi là lựa chọn an toàn trong cả hai trường hợp.

OrcaRouter cung cấp những endpoint nào?

Tất cả những gì bạn mong đợi, cộng thêm vài cái OpenRouter không có. Có ở đây nhưng không có trên OpenRouter: /v1/messages, /v1beta/models … generateContent, /v1/rerank và /v1/realtime. Không có: /v1/fine-tunes, GET /v1/files và /v1/images/variations.

Lỗi có được trả về theo cùng định dạng không?

Lỗi trả về đúng dạng bạn đang xử lý. Hãy xử lý theo mã trạng thái HTTP: thử lại 429 khi chúng tôi gửi Retry-After, chờ rồi thử lại 5xx trừ 501 — nghĩa là chúng tôi không phục vụ lệnh gọi đó, và coi 4xx trên một lệnh gọi relay là thứ cần sửa trong yêu cầu của bạn. Ngoại lệ là 404 từ /v1/generation: nó có thể chỉ có nghĩa yêu cầu chưa quyết toán xong, hãy thử lại nhanh vài lần. Đừng đọc error.type như nguồn gốc: orcarouter_api_error luôn là của chúng tôi, nhưng với một số lỗi của chính chúng tôi, chúng tôi cố ý gửi đúng từ vựng của nhà cung cấp để SDK của bạn đi nhánh thông thường — giới hạn tần suất do chúng tôi áp và do mô hình áp đều là rate_limit_error. Hãy nêu X-Orca-Request-Id khi cần chúng tôi tra một lệnh gọi cụ thể.