- API リクエストエラー — 同期 API 呼び出しに対する HTTP レスポンス(認証、課金、不正なリクエスト、リソースが見つからない場合など)。API リクエストエラーを参照してください。
- 予測の失敗コード — リクエストは受理されてキューに入ったものの、予測自体が
status: "failed"で終了した場合です。失敗の内容は予測に付くerrorオブジェクトが表し、予測ステータスのエンドポイント、webhook の配信、および result エンドポイントから取得できます。予測の失敗コードを参照してください。
予測の失敗コード
失敗した予測はerror オブジェクトを含みます:
失敗した予測は課金されません。そのリクエストのために確保されたクレジットは解放されます。
失敗していない予測は
error: null を持ちます。2026 年 8 月 17 日より前に実装している場合は、移行に関する注記を参照してください。
エラーが届く場所
同じerror オブジェクトはすべてのチャネルで公開されるため、普段見ている場所でそのまま読めます:
result エンドポイントから失敗を読み取る
失敗した予測の出力を要求すると、その原因となった失敗を載せた400 が返ります。リクエストレベルのコードは PREDICTION_FAILED です:
error.codeはPREDICTION_FAILEDで、API リクエストエラーの 1 つです。「出力を要求した予測は出力を生成しなかった」という意味になります。error.detailsは予測自身のerrorオブジェクトです — 同じリクエストについて/statusが報告する内容と同一なので、2 つのエンドポイントが失敗の理由で食い違うことはありません。分岐はerror.details.reasonとerror.details.retryableで行ってください。
error.message は予測の message をそのまま繰り返すため、最上位の message しか読まないクライアントでも有用な情報が得られます。
2 つの timestamp、2 つの意味。 最上位の timestamp はこの HTTP レスポンスが生成された時刻、error.details.timestamp は予測が失敗した時刻です。数日後に取得した予測では、両者は数日離れます。失敗の時刻を指したいときは常に内側を読んでください。
公式のクライアントライブラリはこれを解きほぐしてくれます: result() が投げるエラーの code、reason、retryable は予測自身の値であり、同じ失敗に対して subscribe() が投げるものと同一です。
まだキューに入っている、まだ実行中である、あるいはキャンセルされた予測は、従来どおり同じ汎用の 400 を返し続けます。
再試行すべきかどうかの判断
retryable を見てください。このフィールドが答えるのは 1 つの問いだけです — まったく同じリクエストをもう一度送ったら結果は変わるのか — そして code とは独立しています。同じ code でも、ある失敗では再試行可能、別の失敗ではそうでないということがあります。
retryable は省略可能です。存在しない場合は、下表の code ごとのデフォルトにフォールバックしてください。これはこのフィールドが導入される前の Sunra の挙動そのものなので、フォールバックは常に安全です。精度が落ちるだけです。
code
reason
reason は code の背後にある具体的な原因を示します。メトリクス、ルーティング、サポートでの切り分けに使ってください。再試行の判断には retryable を使います。
現在公開されている reason にはそれぞれ下記に専用のセクションがあり、そのアンカーは reason そのもの — #input_fetch_failed、#moderation_blocked など — なので、エラーレポートから意味に直接リンクできます。
input_validation_failed
code: invalid_input · retryable: false
リクエストが Sunra 自身のスキーマ検証またはパラメータ検証を通過しませんでした。問題のあるフィールドは message に示されます。
対処: 示されたフィールドを修正してください。同じリクエストは失敗し続けます。
provider_rejected_input
code: invalid_input · retryable: false
モデルプロバイダーが 1 つ以上の入力パラメータを拒否しました。どのパラメータかをプロバイダーが伝えてくる場合は message にその内容が入ります。入力が受け付けられなかったことしか返さないプロバイダーもあり、その場合は推測せずそのままお伝えします。
対処: モデルのスキーマと照らし合わせてパラメータを見直してください — 範囲外の値、サポートされない組み合わせ、モデルが受け付けないアスペクト比や長さなどです。
input_fetch_failed
code: invalid_input · retryable: false または true
URL で指定された入力ファイルを取得できませんでした。retryable が実際に変わる唯一の reason なので、決めつけずにフィールドを読んでください:
false— 相手ホストに拒否された場合:4xx、取得を許可されていないアドレス、リダイレクト、サイズ上限を超えるファイル。true— 相手ホストに一時的に到達できなかった場合:5xx、タイムアウト、DNS 解決失敗。
message には送信した URL が反映されます — ただし query string は取り除かれるため、presigned URL に含まれる認証情報がそのまま返されることはありません:
retryable が false のときは、その URL が公開されていて到達可能か、presigned リンクの有効期限が切れていないかを確認してください。true のときは再試行してください。
moderation_blocked
code: unsafe_content · retryable: false
モデルプロバイダーのコンテンツ安全性システムにブロックされました — 入力として送られたプロンプトやメディア、あるいは生成された出力のいずれかが対象です。
対処: プロンプトかメディアを変更してください。同じ内容を再送しても再びブロックされます。
provider_rate_limited
code: service_provider_error · retryable: true
モデルプロバイダーがレート制限をかけています。
対処: バックオフを入れて再試行するか、別のモデルへ振り分けてください。
provider_unavailable
code: service_provider_error · retryable: true
モデルプロバイダーがリクエストを処理できませんでした。
対処: 時間をおいて再試行するか、別のモデルへ振り分けてください。
provider_timeout
code: task_timeout · retryable: true
予測が許容時間内に完了しませんでした。
対処: 再試行してください — 負荷の低い時間帯や、より小さなリクエスト(短い長さ、低い解像度)にすると成功しやすくなります。
provider_account_error
code: internal_server_error · retryable: false
当社がそのモデルプロバイダーに持つアカウントに問題があります — 請求、認証情報、恒久的なクォータのいずれかです。これは当社側の問題であり、入力の問題ではありません。
対処: お客様側での対応は不要です。再試行しても解決せず、当社には自動でアラートが上がっています。今すぐその処理能力が必要な場合は、別のモデルへ振り分けてください。
endpoint_misconfigured
code: internal_server_error · retryable: false
このモデルエンドポイントの当社側の設定に誤りがあります。
対処: お客様側での対応は不要です。再試行しても解決せず、当社には自動でアラートが上がっています。急ぎの場合は request_id を添えてサポートにご連絡ください。
queue_enqueue_failed
code: internal_server_error · retryable: true
予測をキューに入れられませんでした。
対処: リクエストを送信し直してください。
reaped_stalled
code: internal_server_error · retryable: true
予測が停止したため終了させられました。
対処: リクエストを送信し直してください。
不明な値
code と reason はどちらもオープンな集合です。 分類できる失敗が増えるにつれて新しい値が追加され、破壊的変更としての告知は行われません。認識できない値を受け取っても、クラッシュしたり、エラーを握りつぶしたり、ペイロード全体を拒否したりしない実装にしてください。
- 不明な
reason—reasonが存在しない場合と同じ扱いにし、retryable(またはcodeごとのデフォルト)で判断してください。生の値はログに残してください。サポートが失敗を特定する最短の手がかりになります。 - 不明な
code—internal_server_errorとして扱ってください。名前を覚えておく価値のあるセンチネル値が 1 つあります:unknown_error_codeは、予測は確かに失敗したものの、その分類を復元できなかったときに Sunra が返す値です。
移行に関する注記: エラーがない場合 error は null です
2026 年 8 月 17 日より適用。 error オブジェクトの表現は、すべてのチャネルで 1 つに統一されました。チャネル間にあった 3 つの差異は解消されています:
- 予測が失敗していない場合、
errorはnullです。GET /v1/predictions/{prediction_id}は従来、成功・キュー待ち・キャンセルのいずれの予測についても空のオブジェクト —"error": {}— を返していました。現在は"error": nullを返します。これはキューのステータスエンドポイントがすでに行っていた挙動です。空かどうかで判定している場合(Object.keys(response.error).length === 0)は、null チェック(response.error === null)に置き換えてください。 - 失敗には常に、空でない
codeとmessageが付きます。 当社が分類できない内容が記録された失敗では、フィールドが欠落していたり、空だったり、文字列でなかったりする代わりに、センチネル値unknown_error_codeと汎用のメッセージが返るようになりました。 - プレーンテキストとして記録された失敗も、テキストのまま届きます。 2026 年 4 月のごく一部の予測は、エラーを単なる文字列として保存していました。
GET /v1/predictions/{prediction_id}はこれを捨てており、キューのステータスエンドポイントはセンチネルのメッセージで置き換えていましたが、現在はどちらもcode: "unknown_error_code"の下にmessageとして公開します。
error はこれらのレスポンスすべてにもともと存在しており、変わったのはその値だけです。webhook の配信には手を加えていません — 他のチャネルが収束した先がこの形です — また error は引き続き、succeeded の配信では null として送られるのではなく存在しません。
互換性の期間。 二重に送出する期間はありません。API はその日をもって "error": {} の生成を停止しました。それ以前に取得したペイロードを再生・再処理する場合は、保存されたデータが入れ替わるまで null と {} を同じものとして扱ってください。
今後の変更: 一部の失敗にはより具体的な code が付きます
現在、失敗のかなりの割合が service_provider_error として報告されており、その中には一時的でもプロバイダーの責任でもないものが多く含まれます。プロバイダーごとに分類を進めるにつれて、これらの失敗は実態を表す code へ移っていきます:
- プロバイダーが決定的に入力を拒否したもの →
invalid_input(以前はservice_provider_error) - エンドポイントの設定ミスや当社のプロバイダーアカウントの問題など、Sunra 側の問題 →
internal_server_error(以前はservice_provider_error) - 取得できなかった入力ファイル →
invalid_input(以前はinternal_server_error)
code 値が追加されることもありません — 上記の 5 つは分類済みコードの全体のままです。変わるのは、ある失敗がそのうちどれを受け取るかであり、それはプロバイダー単位で段階的に進みます。code で分岐している実装があるなら、そのロジックを retryable と reason に移す好機です。これらは失敗そのものを直接表し、今回の再分類の影響を受けません。