OpenAI互換APIの目的はSDKがそのまま動くことです。したがって401が発生する場合、ほとんどの場合バグは変更した2行、つまりbase_urlとapi_keyにあります。ここでは、実際に発生する順に失敗パターンを説明します。
エラー
{
"error": {
"type": "invalid_api_key",
"message": "Invalid or missing API key.",
"code": "invalid_api_key"
}
}原因と対処法の概要
| 原因 | 対処法 |
|---|---|
| base_urlに/v1サフィックスがない(または二重になっている) | ほとんどのゲートウェイでは、ベースURLを正確にhttps://host/v1にする必要があります。SDK自身が/chat/completionsを追加します。 |
| 別のホストで発行されたキー | sk-…キーは発行元のサービスに対してのみ認証できます。プレフィックスとホストの対応を確認してください。 |
| 企業プロキシ / WAFがAuthorizationヘッダーを削除している | クリーンなネットワークからテストし、Authorizationを通過させるようプロキシを設定してください。 |
| OPENAI_API_KEY環境変数が明示的なキーを上書きしている | SDKはデフォルトで環境変数を読み取ります。一部の構成では古い環境変数が黙って優先されます。api_keyを明示的に渡してください。 |
SDKがアクセスしている正確なURLを確認する
client.base_urlを出力し、GET /v1/modelsを呼び出してください。これは最も低コストな認証済みエンドポイントです。/modelsが機能するなら認証は正常で、エラーは別の場所にあります:
from openai import OpenAI
client = OpenAI(
base_url="https://api.kunavo.com/v1", # exactly one /v1
api_key="sk-kn-...", # explicit beats env vars
)
print(client.base_url)
print([m.id for m in client.models.list().data][:5])同じホストをCurlしてSDKを切り分ける
Authorization: Bearer付きのcurlが機能し、SDKが機能しない場合は、SDKの実際のリクエストを比較してください(OPENAI_LOG=debugを設定)。10回に9回はプロキシまたは環境変数が何かを書き換えています。
Kunavo経由で呼び出している場合
Kunavoのエンドポイントはhttps://api.kunavo.com/v1にあり、OpenAIのAPI形式に厳密に準拠し、Bearer認証を使用します。GET /v1/modelsは認証のスモークテストとして機能します。コードがapi.openai.comに対して動作しているなら、base_urlをKunavoに向けることだけが変更点です。同じSDK、同じワイヤ形式で、1つのキーでClaude、GPT、メディアモデルを利用できます。
よくある質問
ゲートウェイの401と403 — 違いは?
401 = 認証情報自体が受け付けられなかった(キーがない、または無効)。403 = キーは有効だが、その操作が許可されていない(無効化されたキー、停止されたアカウント、許可されていないモデル)。エラー本文を読んでください。互換APIでは理由がerror.messageに入っています。
ローカルでは動くのにCIで401になるのはなぜ?
CIは別の環境です。シークレットが設定されていない、別のサービス用に設定されている、またはプロキシがヘッダーを削除している可能性があります。CI内部からrepr(key[:12])とbase_urlをログ出力し、実際に送信されている内容を確認してください。