API エラーコード

本サイトが返すすべての失敗を、2026-09-01 に実際のエンドポイントへ 1 件ずつ投げて確認したものです。返ってくる 8 件のうち 5 件はステータスコードが本当の原因を指しておらず、そのうち 2 件は公式 SDK が黙って再試行するため、プログラムに届くのはさらに後になります。

2026-09-01 検証

ステータスコードが実際の原因と異なる

ステータスコードではなく error.code を読む

モデル名の誤りは 503、messages フィールドの欠落は 500 で返ってきます。どちらもリクエスト自体の誤りで、何度再試行しても結果は変わりません。ところが openai-python、openai-node、Anthropic の各 SDK はいずれも 408・409・429 と 5xx 全般を既定で 2 回、指数バックオフ付きで再試行します。つまり 1 か所のタイプミスが 3 往復と数十秒の待ち時間に変わり、そのあとで最初から確定していた原因がようやく表示されます。本当の原因は最初からレスポンスボディの error.code にあり、嘘をついているのはステータスコードの側です。

一覧

ステータスコード

数値順ではなく、実際に遭遇する頻度の順に並べています。

  • HTTP 401空文字列
    実際に起きていること
    キーが存在しない、すでに失効している、または Authorization ヘッダー自体が付いていません。
    対処方法
    コンソールの「API キー」ページでキーが残っているか確認し、必要なら新しく発行してください。なお "Bearer " の付け忘れは原因になりません——本サイトはキーだけの形式も受け付けます。
    SDK の再試行
    しない(即座に失敗)
    実際のエンドポイントで計測
    probes-errors.mjs: invalid-token / missing-auth
    返されたメッセージ
    Invalid token
  • HTTP 503model_not_foundステータスコードが実際の原因と異なる
    実際に起きていること
    そのモデル ID は本サイトのカタログにありません。ほとんどの場合、他社のドキュメントから写したもの(gpt-4o、claude-sonnet-4-5)です。障害ではなく、存在しないモデルに割り当てる経路がないだけです。
    対処方法
    GET /v1/models の結果と照合してください。それが唯一の正式な一覧です。本サイトの ID は必ず ベンダー/モデル の形式で、例えば deepseek/deepseek-v4-flash です。
    SDK の再試行
    する(既定で 2 回)
    実際のエンドポイントで計測
    probes-errors.mjs: unknown-model
    返されたメッセージ
    No available channel for model gpt-4o under group y-api (distributor)
  • HTTP 403insufficient_user_quotaステータスコードが実際の原因と異なる
    実際に起きていること
    アカウント残高がゼロになりました。このメッセージは中国語で、残高には全角の $ が使われています。英語で検索しても何も出てこないのはそのためです。
    対処方法
    https://y-api.bestvirtualgoods.com/app/billing で入金してください。クレジットは即時に回復し、既存のキーはそのまま使えます。コードの変更も不要です。
    SDK の再試行
    しない(即座に失敗)
    上流のソースコードで確認(本サイトでは未発生)
    service/billing_session.go:355-359
    返されたメッセージ
    用户额度不足, 剩余额度: $0.00
  • HTTP 403pre_consume_token_quota_failedステータスコードが実際の原因と異なる
    実際に起きていること
    アカウントには残高がありますが、このキー 1 本が作成時に設定した上限に達しました。メッセージにはそのキーの残額と、今回のリクエストに必要だった額の両方が示されます。
    対処方法
    「API キー」ページでそのキーの上限を引き上げるか解除するか、上限のないキーに切り替えてください。アカウントへの入金では解決しません——上限はキー単位です。
    SDK の再試行
    しない(即座に失敗)
    実際のエンドポイントで計測
    probes-errors.mjs: quota-exhausted
    返されたメッセージ
    token quota is not enough, token remain quota: $0.000002, need quota: $0.000074
  • HTTP 500invalid_requestステータスコードが実際の原因と異なる
    実際に起きていること
    リクエストボディに必須フィールドがありません。多いのは messages です。本来 400 系のリクエストエラーであるものが、サーバーエラーとして返っています。
    対処方法
    メッセージにフィールド名がそのまま出るので、ステータスコードではなくそちらを読んでください。ボディを直すこと。再試行しても同じ結果です。
    SDK の再試行
    する(既定で 2 回)
    実際のエンドポイントで計測
    probes-errors.mjs: missing-field
    返されたメッセージ
    field messages is required
  • HTTP 400invalid_request_errorステータスコードが実際の原因と異なる
    実際に起きていること
    そのエンドポイントは本サイトにありません。/v1/embeddings、/v1/completions、/v1/images/generations はすべてこのケースになります。しかもボディは messages が必須だと述べるため、本当の原因とはまったく無関係な方向を指します。
    対処方法
    本サイトが提供するのは chat completions と Anthropic の messages エンドポイントです。フレームワークが内部で embeddings を呼んでいる場合、その部分は別のプロバイダーが必要です。
    SDK の再試行
    しない(即座に失敗)
    実際のエンドポイントで計測
    probes-errors.mjs: unsupported-endpoint
    返されたメッセージ
    `messages` is required and must be a non-empty array.
  • HTTP 400空文字列
    実際に起きていること
    リクエストボディが正しい JSON ではありません。上流が自身の "Invalid request:" という接頭辞を二重に付けますが、これは表示上の問題です。
    対処方法
    手書きのペイロードかシェルのクォートが原因のことが多いです。送信前に JSON を検証し、シェルではボディ全体をシングルクォートで囲んでください。
    SDK の再試行
    しない(即座に失敗)
    実際のエンドポイントで計測
    probes-errors.mjs: malformed-json
    返されたメッセージ
    Invalid request: Invalid request: invalid JSON request body
  • HTTP 404空文字列
    実際に起きていること
    POST /v1/messages/count_tokens は実装されていません。Claude Code と Anthropic SDK は、送信前にコンテキスト量を見積もるためこれを呼びます。
    対処方法
    こちら側で直すものはありません。クライアントは見積もりを省略するか警告を出すだけで、チャット・ストリーミング・ツール呼び出しには影響しません。
    SDK の再試行
    しない(即座に失敗)
    実際のエンドポイントで計測
    probes-errors.mjs: count-tokens
    返されたメッセージ
    Invalid URL (POST /v1/messages/count_tokens)

静かな失敗

エラーより厄介な HTTP 200

200 を返し、例外も投げず、プログラムがそのまま進んでしまう失敗が 3 つあります。おかしいのは内容か請求額です。だからこそ自力では見つけにくいのです。

画像は受け取られ、そして無視される

上流は 5 つのモデルに image_ratio を付けています。あれは課金係数であって、視覚能力を意味しません。5 つとも data URL の画像を受け取り 200 を返し、見ていない画像について自信たっぷりに答えます——プローブが送ったのは純緑色の PNG ですが、色を当てたモデルは 1 つもありませんでした。推奨モデルはむしろ 400 で拒否します。2 つの失敗のうち、そちらのほうが安全です。

クライアント互換性マトリクスより

max_completion_tokens はテキストを抑えるが、請求は抑えない

上限を 12 にしても moonshotai/kimi-k2.5 の課金は 261、21.8 倍でした。切り詰め自体は効いています(finish_reason=length)。超過分は推論トークンで、課金されるのに content には現れません。この上限から算出したコスト見積もりは、同じ倍率で過小になります。

クライアント互換性マトリクスより

Anthropic のメッセージ id に msg_ 接頭辞がない

POST /v1/messages は接頭辞なしの 16 進数 id を返します。msg_ 接頭辞を前提にアサートしたり、id を解析してレスポンスを振り分けるコードは一致しません——ボディのそれ以外は仕様どおりであるにもかかわらず。

クライアント互換性マトリクスより

パース

エラーボディの形

外側は必ず {"error": {...}} ですが、フィールドの集合は一定ではありません。param があるエラーとないエラーがあり、code は空文字列であることが多いです。すべてのフィールドを省略可能として扱ってください。

401、param フィールドなし
{"error":{"code":"","message":"Invalid token (request id: 2026090114474514374…)","type":"new_api_error"}}
404、param はあるが空
{"error":{"message":"Invalid URL (POST /v1/messages/count_tokens)","type":"invalid_request_error","param":"","code":""}}

どのメッセージも末尾に request id が付き、リクエストごとに異なります。このページと見比べる前に取り除いてください。逆に、問題を報告するときは必ず添えてください——ログでそのリクエストを特定できる唯一の手がかりです。

切り分け

ほぼ何でも切り分けられる 3 ステップ

この順番で。1 つずつ層を除外していくので、手が止まったところが答えです。

  1. まずキーと経路を確認する

    GET /v1/models はクレジットを消費せず、同じキーを使います。200 とモデル一覧が返れば、キー・ネットワーク・CDN エッジのすべてに問題がないことが分かります。つまり原因は認証ではなくリクエストボディです。

    curl -s https://api.y-api.bestvirtualgoods.com/v1/models -H "Authorization: Bearer $YAPI_KEY" | head -c 200
  2. curl で再現する

    これで SDK を切り離せます。curl が成功して自分のコードが失敗するなら、差はそのライブラリのリクエストの組み立て方にあり、本サイト側ではありません。

    curl -i https://api.y-api.bestvirtualgoods.com/v1/chat/completions \
      -H "Authorization: Bearer $YAPI_KEY" \
      -H "Content-Type: application/json" \
      -d '{"model":"deepseek/deepseek-v4-flash","messages":[{"role":"user","content":"hi"}]}'
  3. 切り分け中は再試行を切る

    再試行を切れば、自分のリクエストが原因の 500 や 503 が 1 回目で表に出ます。2 回の無駄な待ちが挟まりません。終わったら戻してください——本物の一時障害に対しては再試行に意味があります。

    client = OpenAI(
        base_url="https://api.y-api.bestvirtualgoods.com/v1",
        api_key=os.environ["YAPI_KEY"],
        max_retries=0,  # 切り分け時のみ
    )

どれにも当てはまらない場合

ステータスページでは本サイト自体が劣化しているかどうかを、過去 90 日分の記録とともに確認できます。そこが緑のままで解決しないときは、エラーボディの request id を送っていただくのが最も有効です。