OpenRouter からの移行は 1 行で済みます

base URL を変更し、OrcaRouter のキーに差し替えてください。モデルも SDK も、その他のコードもそのままで構いません。書き換えが要るのは openrouter/ のルーター ID だけです。

確認すべき 3 点

  1. SDK に合った base URL を使う — OpenAI SDK には https://api.orcarouter.ai/v1 を、他の二つには https://api.orcarouter.ai を指定します。パスはそれぞれの SDK が自分で付けます。
  2. OrcaRouter のキーに差し替える — 値は変わります(OpenRouter のキーではここで認証できません)が、場所は変わりません。お使いの SDK がすでに送っているヘッダーをそのまま読み取ります。
  3. モデル名はそのまま — 同じ vendor/model 形式の名前を使うため、anthropic/claude-sonnet-4 はそのまま利用できます。例外は OpenRouter 独自の openrouter/ ルーター ID で、これらは書き換えになります。

変更前と変更後:変わるのはこの 1 行

OrcaRouter は OpenAI・Anthropic・Gemini の API をネイティブに扱えるので、いま使っている SDK をそのまま使えます。各コードでは、- で始まる行が削除する行、+ で始まる行が追加する行です。

OpenAI — Python

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

コードの変更はここだけです。あわせてキーを OrcaRouter のものに差し替えてください。モデル名もメッセージもストリーミングもそのままです。ただし openrouter/ のルーター ID を呼んでいる場合は書き換えが必要です。

Anthropic — Python

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

当サービスは Anthropic の API に直接対応しています(OpenRouter は非対応です)。OpenRouter に合わせて OpenAI SDK 経由で Claude を呼び出していたのであれば、その必要はなくなります。

Gemini — TypeScript

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

Gemini の API にも直接対応しているため、Google SDK はそのまま動作します。

SDK ごとの完全なサンプル

インポート、クライアント、実際の呼び出しまで一式。環境変数 ORCAROUTER_API_KEY を設定すれば、このままで動きます。

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:名前を変えるもの

同じ vendor/model 形式の名前を使うため、anthropic/claude-sonnet-4 はそのまま利用できます。例外は OpenRouter 独自の openrouter/ ルーター ID で、これらは書き換えになります。

OpenRouter での指定OrcaRouter での指定
openrouter/autoorcarouter/auto
openrouter/freeorcarouter/free
その他の openrouter/ ルーター対応するものはありません。モデルを直接指定してください
anthropic/claude-sonnet-4 のような vendor/model 形式の ID すべて同じ ID のまま

課金の違い

提供していない 4 つのこと

本番で気づくより、今知っておくほうが安全です。

よくある質問

OrcaRouter は OpenRouter の代わりにそのまま使えますか?

ほとんどの連携では使えます。base URL を変えて OrcaRouter のキーに差し替えるだけで、SDK・モデル名・メッセージ・ストリーミングはそのままです。例外は OpenRouter 独自の openrouter/ ルーター ID(名前が変わります)と、上に挙げた、OrcaRouter が意図的に提供していない 4 つのことです。

各 SDK にはどの base URL が必要ですか?

OpenAI SDK には https://api.orcarouter.ai/v1 を、他の二つには https://api.orcarouter.ai を指定します。パスはそれぞれの SDK が自分で付けます。

OpenRouter の API キーをそのまま使えますか?

値は変わります(OpenRouter のキーではここで認証できません)が、場所は変わりません。お使いの SDK がすでに送っているヘッダーをそのまま読み取ります。

openrouter/auto と openrouter/free の代わりは何ですか?

OrcaRouter のルーターは orcarouter/ の方です。うち 2 つは相手側と直接対応します。openrouter/auto の代わりに orcarouter/auto を、openrouter/free の代わりに orcarouter/free を使ってください。考え方はどちらも同じで、リクエスト時にこちらでモデルを選びます。後者なら無料枠のままです。ほかのルーターには対応するものがないので、具体的なモデル名を指定してください。

フォールバックルーティングは同じように動きますか?

models と route を extra_body の中に移してください。それ以外は同じです。優先順にモデルを並べれば、順番に試します。モデルは最少 2 つ、最大 5 つです。きちんと直す価値があります。最上位に残しても当方は読み取らないためフォールバックが静かに機能しなくなり、さらにリクエスト本文をそのまま転送する設定の環境では、モデルが余分なフィールドを受け取ってリクエスト自体を拒否することがあります。

リクエストにかかった費用はどう確認しますか?

レスポンスから X-Orca-Request-Id を読み、/v1/generation を呼びます。501 が返る場合、このデプロイではコスト照会が無効です。

X-Title と HTTP-Referer で引き続きアプリを識別できますか?

X-Title を送れば、アプリ名は解析画面でこれまでどおり表示され、変更は不要です。OpenRouter 独自のヘッダー名も読み取ります。HTTP-Referer だけの場合は、そのドメインが当方の認識済みリストにあるときにのみアプリ名が付くため、確実にしたい場合はタイトルヘッダーを送ってください。この項目は、誤って削除しないようにという注意書きです。

リクエスト内の provider と transforms はどう扱われますか?

どちらも当社では使用しません。通常のチャネルではリクエストがモデルに届く前に取り除かれます。ボディをそのまま転送する設定のチャネルではそのまま送られ、厳格な上流がリクエストを拒否することがあります。いずれにせよ、外しておくのが安全です。

OrcaRouter ではどのエンドポイントが使えますか?

想定どおりのものに加え、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 を添えてください。