- 技術 💻
OpenRouterとは|使い方・APIキー・無料モデル・料金とコード例
結論
OpenRouterは、多数のLLMを1つのAPIキーとOpenAI互換のAPIで呼べるサービスです。base_url を変えるだけで、OpenAI の SDK がそのまま使えます。
この記事でわかること
- 登録から最初の1回までの4ステップと料金の計算例
- curl・Python・TypeScript の完成コードと送信内容の実物
- 401・402・429 など8種のエラーと、SDKの再試行の実測
アプリは OpenRouter の1つの URL に送るだけで、どの提供元のどのモデルに届けるかは OpenRouter が決めます。
flowchart TD
A[アプリ<br>OpenAI SDK・curl] --> B[OpenRouter /api/v1]
B --> C{振り分け}
C --> D[提供元A]
C -.失敗時.-> E[提供元B]
D --> F[応答<br>model・usage.cost]
E --> F
よく使う設定の早見表です。
| やりたいこと | 書くもの | 補足 |
|---|---|---|
| OpenAI SDK で呼ぶ | base_url="https://openrouter.ai/api/v1" |
キーは OpenRouter のもの |
| 認証 | Authorization: Bearer <キー> |
キーは openrouter.ai/keys で作る |
| モデルを選ぶ | "model": "提供元/モデル名" |
例 openai/gpt-5.2 |
| 無料で試す | 末尾が :free のモデル |
1日50回(条件で1,000回) |
| 失敗時に別モデルへ | "models": [第1候補, 第2候補] |
実際に使った名前は model |
| アプリ名を出す | HTTP-Referer・X-OpenRouter-Title |
どちらも任意 |
| 使った金額を見る | 応答の usage.cost |
毎回自動で付く |
| 残高・上限を見る | GET /api/v1/key |
limit_remaining など |
確認環境:OpenRouter の公式ドキュメント(Quickstart・Authentication・Errors・Limits・Model Fallbacks・Provider Routing・Model Variants・Streaming・Usage Accounting・App Attribution・FAQ)と料金ページ、モデルのページで仕様を確かめました。コードは openai SDK(Python 3.31.0/Python 3.11.15、JavaScript 7.34.0/Node.js 22.22.2)と curl 8.5.0 で動かし、ドキュメントどおりの形で応答を返すローカルの擬似エンドポイントに base_url を向けて、SDK が送るリクエストの中身を記録しました。型は TypeScript 7.0.2 で確かめています(確認日 2026年10月17日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「OpenRouterとは|使い方・APIキー・無料モデル・料金とコード例」
OpenRouterとは:1つのAPIで多数のLLMを呼ぶ仕組み
OpenRouter は、各社の LLM(大規模言語モデル)を 1つの API・1つのキー・1つの請求 にまとめるサービスです。公式の FAQ は「OpenRouter provides a unified API to access all the major LLM models on the market.」と説明しています。
使う側から見た特徴は3つです。
1OpenAI 互換のAPI
エンドポイントは https://openrouter.ai/api/v1/chat/completions。OpenAI の SDK の base_url を差し替えるだけで呼べます。
2モデルを名前で切り替える
openai/…・anthropic/…・google/… のように、提供元/モデル名 の文字列を変えるだけで別のモデルになります。
3失敗したら別の提供元・別のモデルへ
同じモデルを複数の提供元が出している場合は自動で振り分け、models 配列で別モデルへのフォールバックも指定できます。
料金はモデルごとの単価で、FAQ には「there is no markup on inference pricing」(推論の料金に上乗せはない)とあります。手数料がかかるのはクレジットを買うときです(詳しくは「OpenRouterの料金」の節)。
直接 OpenAI や Anthropic の API を使う場合との違い
| 項目 | OpenRouter | 各社の API を直接 |
|---|---|---|
| APIキー | 1つで全モデル | 会社ごとに1つずつ |
| 請求 | OpenRouter にまとめて前払い(クレジット) | 会社ごと |
| 呼び方 | OpenAI 互換(Anthropic Messages 互換もあり) | 会社ごとの API・SDK |
| モデルの切り替え | model の文字列を変える |
SDK・コードを書き換える |
| 障害時の切り替え | models・提供元の自動振り分け |
自分で実装 |
| 料金 | 推論は上乗せなし。クレジット購入時に手数料 | 各社の単価 |
OpenRouterの使い方:登録から最初の1回まで
アカウントを作る
openrouter.ai でサインアップします。無料のプランでも、末尾が :free のモデルは呼べます。
APIキーを作る
openrouter.ai/keys でキーに名前を付け、クレジットの上限(または上限なし)を選びます。公式は「We recommend setting a credit limit on every key.」と、すべてのキーに上限を付けることを勧めています。
クレジットを買う(有料モデルを使うとき)
カードは5.5%(最低 $0.80)、暗号資産は5%の手数料がかかります。$10 以上買うと、無料モデルの1日の上限も50回から1,000回に上がります。
キーを環境変数に入れて呼ぶ
キーはコードに直接書かず、OPENROUTER_API_KEY などの環境変数から読みます。次の節の curl で1回呼べれば準備完了です。
作ったキーは、パスワード管理ツールや .env に保存します。.env の扱いは、関連記事「.envの使い方と注意点|APIキーを安全に管理する方法」で扱っています。
export OPENROUTER_API_KEY="sk-or-v1-..."
キーが漏れたとき
公式ドキュメントによると、OpenRouter は GitHub のシークレットスキャン(公開リポジトリに入ったキーの検出)に参加しています。通知が来た、または漏れた疑いがあるときは、openrouter.ai/settings/keys でそのキーを消して作り直す、とされています。リポジトリに push してしまったときの手順は、関連記事「APIキーをGitHubにpushしてしまった時の対処手順」で扱っています。
モデル名の形:「提供元/モデル名」と :free・~ の意味
モデルは 提供元/モデル名 の文字列で指定します。一覧は openrouter.ai/models か、API の GET /api/v1/models で取れます。
| 書き方 | 例 | 意味 |
|---|---|---|
提供元/モデル名 |
openai/gpt-5.2 |
特定のモデル |
~提供元/系列-latest |
~anthropic/claude-sonnet-latest |
系列の最新モデルへ自動で転送 |
末尾 :free |
nvidia/nemotron-3.5-super-vl:free |
無料版(制限あり) |
末尾 :nitro |
openai/gpt-5.2:nitro |
処理速度(スループット)の高い提供元を優先 |
末尾 :floor |
openai/gpt-5.2:floor |
価格の安い提供元を優先 |
末尾 :exacto |
openai/gpt-5.2:exacto |
ツール呼び出しの信頼性を重視して提供元を選ぶ |
openrouter/auto |
― | プロンプトに合うモデルを自動で選ぶ |
openrouter/free |
― | 使える無料モデルからランダムに選ぶ |
~anthropic/claude-sonnet-latestのモデルページには「This model always redirects to the latest model in the Claude Sonnet family.」とあり、2026年10月17日時点の転送先はanthropic/claude-sonnet-5.5です。新しい版が出ると、コードを変えずに転送先が変わります。結果を固定したいときは、版付きの名前を使います。:nitro・:floor・:exactoは振り分けだけを変える接尾辞で、openai/gpt-5.2:nitro:exactoのように組み合わせられます。並べ替えの接尾辞が複数あるときは、最後のものが効きます。:online(Web 検索の結果を付ける)と:thinkingはドキュメントで非推奨になっています。代わりにopenrouter:web_searchのサーバーツールとreasoningパラメータが案内されています。openrouter/autoは、プロンプトを約30種類の作業に分類してモデルを選びます。料金は選ばれたモデルの単価で、ルーター自体の料金はかかりません。
応答の model を必ず見る
~…-latest・openrouter/auto・openrouter/free・フォールバックでは、送った名前と実際に動いたモデルが違うことがあります。応答の model に実際に使われたモデルが入るので、ログに残しておくと、結果が変わったときに原因を追えます。
OpenRouterの無料モデル(:free)と制限
末尾が :free のモデルは、料金が入力・出力とも $0 です。2026年10月17日時点で、openrouter.ai の無料モデルのページには nvidia/nemotron-3-super-120b-a12b:free・nvidia/nemotron-3.5-super-vl:free・poolside/laguna-s-2.1:free・liquid/lfm-2.5-2.6b:free など13個が並んでいます。入れ替わりがあるので、使う前にモデル一覧で確かめます。
無料モデルの制限は、ドキュメントの Limits のページで次のように決まっています。
注意点は3つです。
- 判定は「累計の購入額」です。残高ではありません。ドキュメントには、
is_free_tierではなく累計の購入額で決まると書かれています。 - 入力が学習に使われることがある:無料モデルのページには、Poolside の Laguna について「If you are using Laguna S 2.1 for free, we may use your inputs and outputs to train and improve our models.」、Liquid の LFM について「Prompts and outputs may be retained and used to train Liquid models.」とあります。業務の機密や個人情報は送らない前提で使います。
- プライバシー設定で弾かれることがある:openrouter.ai/settings/privacy には、学習に使う可能性のある提供元への振り分けを許すかどうかの設定が、有料モデルと無料モデルで別々にあります。許可しないと、その条件に合う提供元が無い無料モデルは呼べません。
その日の残り回数は GET /api/v1/key の free_model_daily_requests(used・limit・remaining、UTC の1日単位)で確かめられます。
OpenRouterの料金:手数料と計算例
料金は「モデルの単価 × トークン数」で、単価はモデルのページと GET /api/v1/models の pricing に出ています。API の pricing.prompt・pricing.completion は 1トークンあたりの米ドル(文字列) で、"0" は無料です。
| かかるもの | 金額(2026年10月17日時点) | 出典 |
|---|---|---|
| 推論(モデルの利用) | 提供元の単価のまま(上乗せなし) | FAQ |
| クレジット購入(カード) | 5.5%(最低 $0.80) | FAQ・料金ページ |
| クレジット購入(暗号資産) | 5% | FAQ |
| Business プラン | 8% | 料金ページ |
| BYOK(自分の各社キーを使う) | 月 $25,000 分まで手数料なし、超えた分に5% | 料金ページ |
計算例:~anthropic/claude-sonnet-latest のページの単価は、2026年10月17日時点で入力 $2/100万トークン、出力 $10/100万トークンです。入力2,000トークン・出力500トークンの呼び出しなら、
- 入力:2,000 × 2 ÷ 1,000,000 = $0.004
- 出力:500 × 10 ÷ 1,000,000 = $0.005
- 合計:$0.009/回(1,000回で $9)
クレジット購入の手数料は5.5%と最低 $0.80 の大きいほうです。$0.80 ÷ 5.5% ≒ $14.5 なので、$14.5 より少ない購入では手数料が $0.80 で一定になります($10 の購入なら5.5%は $0.55 で、手数料は $0.80)。
ほかに知っておくと困らない決まりです(FAQ による)。
- 未使用のクレジットは、購入から1年で失効させることがある
- 返金を求められるのは購入から24時間以内。手数料は返金されず、暗号資産の購入は返金されない
- プロンプトと出力は既定では記録されない。記録に同意すると利用料が1%割引になる
日本語のトークン数の目安は、関連記事「トークンとは|生成AIの数え方・日本語の文字数目安と節約方法」で扱っています。
curlでOpenRouterのAPIを呼ぶ
いちばん小さい呼び出しです。HTTP-Referer と X-OpenRouter-Title は任意です。
curl https://openrouter.ai/api/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-H "HTTP-Referer: https://example.com" \
-H "X-OpenRouter-Title: RJC Demo" \
-d '{"model":"openai/gpt-5.2","messages":[{"role":"user","content":"こんにちは"}]}'
このコマンドの宛先をローカルの擬似エンドポイントに替えて送ると、届いたリクエストは次のとおりでした。
POST /api/v1/chat/completions
User-Agent: curl/8.5.0
Accept: */*
Content-Type: application/json
Authorization: Bearer sk-or-v1-dummy0000
HTTP-Referer: https://example.com
X-OpenRouter-Title: RJC Demo
Content-Length: 83
{"model":"openai/gpt-5.2","messages":[{"role":"user","content":"こんにちは"}]}
応答は OpenAI の Chat Completions と同じ形に、OpenRouter の項目(native_finish_reason・usage.cost など)が加わります。次はドキュメントのスキーマどおりに擬似エンドポイントが返した例です(主な項目を抜粋)。
{
"id": "gen-1760000000-demo",
"object": "chat.completion",
"model": "openai/gpt-5.2",
"choices": [{
"index": 0,
"finish_reason": "stop",
"native_finish_reason": "stop",
"message": {"role": "assistant", "content": "こんにちは。OpenRouter 経由の応答です。"}
}],
"usage": {"prompt_tokens": 12, "completion_tokens": 9, "total_tokens": 21, "cost": 0.000114}
}
finish_reasonはstop・length・tool_calls・content_filter・errorに揃えられ、提供元の元の値はnative_finish_reasonに入ります。usageはドキュメントによると毎回自動で付きます。usage: { include: true }は非推奨で、付けても効果はありません。costはこの呼び出しで差し引かれた金額(クレジット)です。
キーの残高と上限を確かめる
curl https://openrouter.ai/api/v1/key \
-H "Authorization: Bearer $OPENROUTER_API_KEY"
応答の data に入る主な項目です。
| 項目 | 意味 |
|---|---|
limit |
キーのクレジット上限(上限なしは null) |
limit_remaining |
キーの残り(上限なしは null) |
usage・usage_daily・usage_monthly |
使ったクレジット(累計・日・月) |
is_free_tier |
まだクレジットを買ったことがないか |
free_model_daily_requests |
無料モデルの当日の used・limit・remaining |
PythonでOpenRouterを使う(openai SDK)
OpenAI の Python SDK の base_url を差し替えます。アプリ名のヘッダーは default_headers に入れると毎回付きます。
pip install openai
import os
from openai import OpenAI
client = OpenAI(
base_url=os.environ.get("OPENROUTER_BASE_URL", "https://openrouter.ai/api/v1"),
api_key=os.environ["OPENROUTER_API_KEY"],
default_headers={
"HTTP-Referer": "https://example.com", # 任意:アプリのURL
"X-OpenRouter-Title": "RJC Demo", # 任意:アプリ名
},
)
res = client.chat.completions.create(
model="openai/gpt-5.2",
messages=[{"role": "user", "content": "こんにちは"}],
extra_body={
"models": ["openai/gpt-5.2", "nvidia/nemotron-3.5-super-vl:free"],
},
)
print("model :", res.model)
print("text :", res.choices[0].message.content)
print("tokens:", res.usage.prompt_tokens, "+", res.usage.completion_tokens)
print("cost :", res.usage.cost)
model : openai/gpt-5.2
text : こんにちは。OpenRouter 経由の応答です。
tokens: 12 + 9
cost : 0.000114
res.usage.cost は OpenAI の型に無い項目ですが、openai SDK 3.31.0 ではそのまま属性として読めました。
SDK が実際に送っているもの
上のコードを擬似エンドポイントに向けて実行したときに届いたリクエストです(openai SDK 3.31.0)。
POST /api/v1/chat/completions
authorization: Bearer sk-or-v1-dummy0000
accept: application/json
content-type: application/json
user-agent: OpenAI/Python 3.31.0
x-stainless-lang: python
x-stainless-package-version: 3.31.0
x-stainless-os: Linux
x-stainless-arch: x64
x-stainless-runtime: CPython
x-stainless-runtime-version: 3.11.15
http-referer: https://example.com
x-openrouter-title: RJC Demo
x-stainless-async: false
x-stainless-retry-count: 0
x-stainless-read-timeout: 600
Content-Length: 147
{"model":"openai/gpt-5.2","messages":[{"role":"user","content":"こんにちは"}],"models":["openai/gpt-5.2","nvidia/nemotron-3.5-super-vl:free"]}
分かることは3つです。
- 宛先は
base_url+/chat/completionsです。base_urlは/api/v1まで書きます。 extra_bodyのmodelsは、JSON の 最上位に そのまま入ります。OpenRouter の独自パラメータ(models・providerなど)はこの方法で送ります。x-stainless-retry-countは、SDK の再試行の回数です(エラーの節で使います)。
ストリーミング
stream = client.chat.completions.create(
model="openai/gpt-5.2",
messages=[{"role": "user", "content": "こんにちは"}],
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
if getattr(chunk, "usage", None):
print("\nusage:", chunk.usage.total_tokens, "tokens / cost", chunk.usage.cost)
ドキュメントによると、OpenRouter は処理中に : OPENROUTER PROCESSING というコメント行を送り、最後の data: [DONE] の直前に usage の入った塊を送ります。擬似エンドポイントからこの形で送ると、curl では次のように見えます(途中の塊を省略)。
: OPENROUTER PROCESSING
data: {"id": "gen-1760000000-demo", "object": "chat.completion.chunk", "model": "openai/gpt-5.2", "choices": [{"index": 0, "delta": {"role": "assistant", "content": "こんにちは。"}, "finish_reason": null}]}
data: {"id": "gen-1760000000-demo", "object": "chat.completion.chunk", "model": "openai/gpt-5.2", "choices": [{"index": 0, "delta": {"content": ""}, "finish_reason": "stop", "native_finish_reason": "stop"}], "usage": {"prompt_tokens": 12, "completion_tokens": 9, "total_tokens": 21, "cost": 0.000114}}
data: [DONE]
openai SDK はコメント行を読み飛ばし、Python のコードの出力は次のとおりでした。
こんにちは。OpenRouter 経由の応答です。
usage: 21 tokens / cost 0.000114
SSE(サーバーから少しずつ送る仕組み)を自分で読む場合は、: で始まる行を JSON.parse の前に飛ばします。ストリームの途中でエラーが起きたときは、HTTP の状態は 200 のまま、error を持つイベントが届き、finish_reason が "error" になって終わる、とドキュメントにあります。
TypeScriptでOpenRouterを使う
Node.js では OpenAI の JavaScript SDK を使います。baseURL と defaultHeaders の綴りが Python と違います。
npm install openai
import OpenAI from "openai";
const client = new OpenAI({
baseURL: process.env.OPENROUTER_BASE_URL ?? "https://openrouter.ai/api/v1",
apiKey: process.env.OPENROUTER_API_KEY,
defaultHeaders: {
"HTTP-Referer": "https://example.com", // 任意:アプリのURL
"X-OpenRouter-Title": "RJC Demo", // 任意:アプリ名
},
});
const res = await client.chat.completions.create({
model: "openai/gpt-5.2",
messages: [{ role: "user", content: "こんにちは" }],
// @ts-expect-error OpenRouter 独自のパラメータ
models: ["openai/gpt-5.2", "nvidia/nemotron-3.5-super-vl:free"],
});
console.log("model:", res.model);
console.log("text :", res.choices[0].message.content);
model: openai/gpt-5.2
text : こんにちは。OpenRouter 経由の応答です。
models は OpenAI の型に無いので、// @ts-expect-error を外すと TypeScript 7.0.2 の型チェックで次のエラーになります。JavaScript SDK は、知らない項目もそのまま JSON に入れて送ります(届いた本文は Python と同じ147バイトでした)。
error TS2769: No overload matches this call.
The last overload gave the following error.
Object literal may only specify known properties, but 'models' does not exist in type 'ChatCompletionCreateParamsBase'. Did you mean to write 'model'?
届いたヘッダーは user-agent: OpenAI/JS 7.34.0・x-stainless-lang: js・x-stainless-runtime: node などで、http-referer と x-openrouter-title も付いていました。ファイルの先頭で await を使うには、package.json に "type": "module" が要ります。
OpenRouter 公式の SDK(TypeScript の @openrouter/sdk、Python の openrouter)もあり、こちらは httpReferer・appTitle などを型付きで渡せます。
フォールバック:models配列で別のモデルに切り替える
models に優先順でモデルを並べると、先頭が失敗したときに次のモデルが試されます。ドキュメントで挙がっている切り替えのきっかけは、コンテキスト長の超過・モデレーションでの拒否・レート制限・停止中で、既定ではどのエラーでも切り替わります。最後の候補も失敗すると、そのエラーが返ります。
flowchart TD
A[1番目のモデル] -->|成功| D[応答は1番目]
A -->|エラー| B[2番目のモデル]
B -->|成功| E[応答は2番目]
B -->|エラー| F[エラーを返す]
1番目を停止中にした擬似エンドポイントで試すと、応答の model は2番目になりました。
r = client.chat.completions.create(
model="demo/down-model",
messages=[{"role": "user", "content": "hi"}],
extra_body={"models": ["demo/down-model", "openai/gpt-5.2"]},
)
print("fallback ->", r.model)
fallback -> openai/gpt-5.2
- 料金は実際に使われたモデルの単価です(「Requests are priced using the model that was ultimately used」)。安いモデルから高いモデルに切り替わると、その分高くなります。
- 同じモデルの中で提供元を選ぶのは
providerです。order(試す順)・allow_fallbacks(既定true)・data_collection(既定"allow")・zdr・sort(price・throughput・latency)・max_priceなどがあります。
{
"model": "openai/gpt-5.2",
"messages": [{"role": "user", "content": "hi"}],
"provider": {
"sort": "price",
"data_collection": "deny",
"max_price": {"prompt": 1, "completion": 2}
}
}
- Anthropic Messages 互換の
/api/v1/messagesでは、modelsではなくfallbacks(最大3件)を使い、両方を送ると 400 になります。
HTTP-RefererとX-OpenRouter-Title:ヘッダーの意味
| ヘッダー | 必須か | 役割 |
|---|---|---|
Authorization |
必須 | Bearer <APIキー> |
HTTP-Referer |
任意 | アプリのURL。ランキングとアプリページの識別子 |
X-OpenRouter-Title |
任意 | アプリの表示名。HTTP-Referer と組で使う |
X-Title |
任意 | X-OpenRouter-Title の旧名。互換のため使える |
X-OpenRouter-Categories |
任意 | カテゴリ(カンマ区切りで2つまで) |
X-OpenRouter-App-Visibility |
任意 | hidden で新しいアプリを一覧に出さない |
- ドキュメントには「
X-Titleis still supported for backwards compatibility」とあり、以前の記事にあるX-Titleも動きます。新しく書くならX-OpenRouter-Titleです。 HTTP-Refererが無いと、アプリのページは作られません。localhostの URL を使う場合は、X-OpenRouter-Titleも付けないと集計されません。- どちらも付けなくても、API の呼び出し自体には影響しません。
OpenRouterのエラー:401・402・429の意味と直し方
エラーの本文は、どのコードでも {"error": {"code": 数値, "message": 文字列, "metadata": {…}}} の形です。次の表の「原文」はドキュメントの Errors のページの説明です。
| コード | 原文(ドキュメント) | よくある原因と直し方 |
|---|---|---|
| 400 | Bad Request (invalid or missing params, CORS) | パラメータの綴り・型を確かめる。models と fallbacks の併用も400 |
| 401 | Invalid credentials (OAuth session expired, disabled/invalid API key) | キーの貼り間違い・削除済み。Bearer の後ろを確かめる |
| 402 | Your account or API key has insufficient credits. Add more credits and retry the request. | 残高不足かキーの上限到達。クレジットを足すかキーの上限を上げる |
| 403 | Forbidden (insufficient permissions, guardrail block, or moderation flag) | 入力がモデレーションで拒否された。error.metadata.reasons を見る |
| 408 | Your request timed out | 出力を短くする・ストリーミングにする |
| 429 | You are being rate limited | 待って再試行。無料モデルは20回/分・1日の上限を確かめる |
| 502 | Your chosen model is down or we received an invalid response from it | models で別モデルを足す。少し待って再試行 |
| 503 | There is no available model provider that meets your routing requirements | provider の条件(zdr・max_price など)を緩める |
ドキュメントによると、429 と 503 には待つ秒数を示す Retry-After ヘッダーが付くことがあります。
openai SDK の再試行を実測
同じ本文を返す擬似エンドポイントに openai SDK を向けて、コードごとの例外と再試行を測りました(429 には Retry-After: 1 を付けています)。
openai/gpt-5.2 AuthenticationError status=401 0.0s body={'code': 401, 'message': 'Invalid credentials (OAuth session expired, disabled/invalid API key)'}
demo/broke APIStatusError status=402 0.0s body={'code': 402, 'message': 'Your account or API key has insufficient credits. Add more credits and retry the request.'}
demo/busy RateLimitError status=429 2.0s body={'code': 429, 'message': 'You are being rate limited'}
demo/busy RateLimitError status=429 0.0s body={'code': 429, 'message': 'You are being rate limited'} ← max_retries=0
demo/down InternalServerError status=502 1.3s body={'code': 502, 'message': 'Your chosen model is down or we received an invalid response from it'}
| コード | Python の例外 | 送った回数 |
|---|---|---|
| 401 | AuthenticationError |
1回(再試行なし) |
| 402 | APIStatusError(専用の型は無い) |
1回(再試行なし) |
| 429 | RateLimitError |
3回(Retry-After の1秒ずつ待って2回再試行) |
429(max_retries=0) |
RateLimitError |
1回 |
| 502 | InternalServerError |
3回(約1.3秒で2回再試行) |
- openai SDK は既定で 429 と 5xx を2回まで自動で再試行します(
max_retries=2)。サーバーのログではx-stainless-retry-countが 0・1・2 と増えていました。JavaScript SDK 7.34.0 も 429 では3回送り(再試行2回)、2.0秒かかりました。 - 自分で再試行を書くときは、
max_retries=0にしてから書くと、待ち時間が二重になりません。 - 402 は専用の例外が無いので、
e.status_code == 402で見分けます。再試行しても直りません。
再試行の書き方(指数バックオフ)は、関連記事「LLM APIの429・529エラー対処|リトライ実装とエラー一覧」で扱っています。
SDK 側で出るエラー
キーを渡し忘れると、OpenRouter に届く前に SDK がエラーにします。openai SDK は OPENAI_API_KEY を探すので、OPENROUTER_API_KEY だけを設定していると次の文が出ます。
OpenAIError: Missing credentials. Please pass an `api_key`, `workload_identity`, `admin_api_key`, or set the `OPENAI_API_KEY` or `OPENAI_ADMIN_KEY` environment variable.
JavaScript SDK 7.34.0 では、同じ文の api_key が apiKey になります。api_key=os.environ["OPENROUTER_API_KEY"] のように明示して渡すと出なくなります。
状態は200なのにエラー
ドキュメントには、ヘッダーを送った後にエラーが起きると、状態は 200 のまま本文に error があり choices が無い場合がある、と書かれています。choices を読む前に error があるかを確かめると、KeyError や undefined で落ちるのを防げます。
よくある質問
Q. OpenRouterとは何ですか。 A. 多数の LLM を、1つの API キーと OpenAI 互換の API で呼べるサービスです。請求も1か所にまとまります。仕組みは「OpenRouterとは」の節にあります。
Q. OpenRouterは無料で使えますか。
A. 末尾が :free のモデルと openrouter/free は無料です。1分20回、1日50回(累計 $10 以上購入していれば1,000回)の制限があり、入力が学習に使われるモデルもあります。
Q. open router の料金はいくらですか。 A. モデルごとの単価そのままで、推論への上乗せはありません。クレジットを買うときにカードで5.5%(最低 $0.80)の手数料がかかります(2026年10月17日時点)。
Q. OpenRouterのAPIキーはどこで作りますか。 A. openrouter.ai/keys です。キーごとにクレジットの上限を付けられ、公式も上限を付けることを勧めています。
Q. OpenAIのSDKでそのまま使えますか。
A. 使えます。base_url(JavaScript は baseURL)を https://openrouter.ai/api/v1 にし、キーを OpenRouter のものにします。独自のパラメータは Python では extra_body で送ります。
Q. 402エラーが出ます。 A. 残高が足りないか、キーに付けた上限に達しています。クレジットを足すか、キーのページで上限を上げます。openai SDK は 402 を再試行しません。
まとめ
- OpenRouter は 1つのキー・OpenAI 互換の API で多数のモデルを呼べる。
base_urlをhttps://openrouter.ai/api/v1にする - モデルは
提供元/モデル名。~…-latest・openrouter/auto・フォールバックでは 応答のmodelで実際のモデルを確かめる - 無料モデルは 1分20回・1日50回(累計 $10 以上で1,000回)。学習に使われるものがある
- 推論は上乗せなし、クレジット購入時に5.5%(最低 $0.80)。キーには上限を付ける
- 独自パラメータ(
models・provider)は Python ならextra_body、TypeScript は型エラーを抑えて送る - openai SDK は 429・5xx を既定で2回再試行し、401・402 は再試行しない
構造化出力(JSON で受け取る)の方式は、関連記事「LLMの構造化出力とJSON|4方式の違いとPydantic検証の実行結果」で扱っています。費用を下げる方法は、関連記事「LLM APIのコスト削減方法|キャッシュとバッチの仕組みと計算例」で扱っています。
参考・出典
確認日はいずれも 2026年10月17日です。
- OpenRouter Docs「Quickstart」:https://openrouter.ai/docs/quickstart
- OpenRouter Docs「Authentication」:https://openrouter.ai/docs/api/reference/authentication
- OpenRouter Docs「Errors and Debugging」:https://openrouter.ai/docs/api/reference/errors-and-debugging
- OpenRouter Docs「Limits」:https://openrouter.ai/docs/api/reference/limits
- OpenRouter Docs「API Reference Overview」:https://openrouter.ai/docs/api/reference/overview
- OpenRouter Docs「Streaming」:https://openrouter.ai/docs/api/reference/streaming
- OpenRouter Docs「Model Fallbacks」:https://openrouter.ai/docs/guides/routing/model-fallbacks
- OpenRouter Docs「Provider Routing」:https://openrouter.ai/docs/guides/routing/provider-selection
- OpenRouter Docs「Model Variants」:https://openrouter.ai/docs/guides/routing/model-variants
- OpenRouter Docs「Auto Router」:https://openrouter.ai/docs/guides/routing/auto-model-selection
- OpenRouter Docs「Models」:https://openrouter.ai/docs/guides/overview/models
- OpenRouter Docs「Usage Accounting」:https://openrouter.ai/docs/guides/administration/usage-accounting
- OpenRouter Docs「App Attribution」:https://openrouter.ai/docs/app-attribution
- OpenRouter Docs「Provider Logging」:https://openrouter.ai/docs/guides/privacy/provider-logging
- OpenRouter Docs「FAQ」:https://openrouter.ai/docs/faq
- OpenRouter「Pricing」:https://openrouter.ai/pricing
- OpenRouter「Free Models」:https://openrouter.ai/collections/free-models
- OpenRouter「Claude Sonnet Latest」:https://openrouter.ai/~anthropic/claude-sonnet-latest
- OpenRouter「Free Models Router」:https://openrouter.ai/openrouter/free
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「OpenRouterとは|使い方・APIキー・無料モデル・料金とコード例」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。