ブログ · · 約 10 分で読めます

Webhook の応答コードの意味:受ける側が返す値と送る側の扱い

Webhook を受ける側が返すべき応答コードと、Stripe・Shopify・GitHub・Slack・LINE・Standard Webhooks が 2xx 以外・3xx・410・429 をどう扱うかを表で整理します。

要点

  • 受け取れたら 2xx、署名が不正なら 400 か 401、後で送り直してほしいときは 5xx を返します。200 と 204 に扱いの違いはありません。
  • 主要な送る側は 2xx だけを成功とし、3xx のリダイレクトは追わずに失敗として扱います。
  • 410 で送信先を止めるか、429 で送る速さを落とすかは送る側ごとに違うので、相手の仕様を確かめてから使います。

Webhook を受ける側が返す応答コードの基本は 3 つです。受け取れたら 2xx、署名が合わないなど要求そのものが不正なら 400 か 401、一時的な障害で後から送り直してほしいなら 5xx です。送る側の多くは 2xx だけを成功とし、それ以外は失敗として再送します。この記事では、コードごとに受ける側が返すべき値と、主要な送る側がそれをどう扱うかをまとめます。

受ける側が返すコード

状況 返すコード 送る側の一般的な扱い
受け取って記録した(処理はこれから) 200 か 204 成功。再送しない
同じイベントがもう一度届いた(重複) 200 か 204 成功。再送しない
署名が合わない、必須のヘッダーがない 400 か 401 失敗。多くは再送する
知らないイベントの種類 200 か 204 成功。受け取るだけにする
データベースが落ちているなど一時的な障害 500・503 失敗。再送する
処理が重く、タイムアウトになった (応答が返らない) 失敗。再送する
もうこの URL で受けない 410 送る側によって、止める・再送する

表の中で間違えやすいのは次の 3 つです。

  • 重複には 2xx を返します。4xx を返すと、送る側は失敗として再送を続けます。
  • 知らないイベントの種類にも 2xx を返します。送る側が新しい種類を追加したときに、受ける側が失敗を返し続けることになるからです。
  • 署名が合わないときの 4xx も、多くの送る側は再送します。鍵を直せば次の再送で通るので、署名の失敗を「永久の失敗」と考える必要はありません。

200 と 204 の違い

扱いの違いはありません。Stripe は「200 が表示されていれば送信は成功」と書きつつ、成功の応答を 2xx と表しています。Shopify は「200 番台の応答を成功とみなす」、GitHub は「10 秒以内に 2XX を返す」と書いています(いずれも 2026-09-27 に公式で確認)。本文のない 204 でも、短い本文を付けた 200 でも同じです。

応答の本文は送る側の配信の記録に残ることがあります。エラーのときに原因を短く返しておくと、送る側の画面で原因が分かります。個人情報やスタックトレースは返さないようにします。

主要な送る側の扱い

2026-09-27 に各社の公式のドキュメントで確かめた内容です。

送る側 成功 3xx 2xx 以外のとき タイムアウト
Stripe 2xx 失敗 本番は最長 3 日間、指数バックオフで再送 記載なし
Shopify 200 番台 記載なし 4 時間で最大 8 回再送。続けば購読を削除 5 秒(接続は 1 秒)
GitHub 2XX 2XX 以外として失敗 自動の再送なし。手動か API で再配信 10 秒
Slack(Events API) 2xx 3 回以上のリダイレクトは失敗 すぐ・1 分後・5 分後の 3 回再送。x-slack-no-retry: 1 で止められる 3 秒
LINE 200 番台 記載なし 再送は設定で有効にしたときだけ(回数は非公開) 2 秒で request_timeout
Standard Webhooks(仕様) 2xx 失敗。URL を直すよう勧める 410 は送信先を無効に、429・502・504 は送る速さを落とす 記載なし

出典: Stripe、Shopify の troubleshoot、Shopify の配信、GitHub の失敗の扱い、GitHub の推奨、Slack の Events API、LINE の受信、LINE のエラーの統計、Standard Webhooks の仕様

表から読み取れることを補足します。

  • Slack は、失敗の多いアプリのイベントの配信を止めます。60 分間の配信の 95% 以上が失敗の条件(証明書の検証の失敗、3 秒を超える応答、3 回以上のリダイレクト、2xx 以外の応答)に当たると、イベントの購読が無効になります。
  • Slack だけが「再送しないで」を受ける側から伝えられます。2xx 以外の応答に x-slack-no-retry: 1 を付けると再送されません。
  • Shopify は購読そのものを消します。Admin API で作った購読は、8 回続けて失敗すると自動で削除されます。
  • LINE はタイムアウトが短い。エラーの統計で、2 秒以内に応答がなかったものを request_timeout に分類しています。LINE は、タイムアウトの場合でもボットのサーバー側では受け取れていることがあると注意しています。

5xx と 4xx の使い分け

送る側の多くは 4xx と 5xx を区別せずに再送しますが、受ける側では意味を分けて返しておくと、送る側の記録を見る人が原因を切り分けられます。

  • 4xx: 要求そのものに問題がある(署名が合わない、本文が壊れている)。送り直しても同じ結果になる見込みが高い。
  • 5xx: 受ける側の都合で処理できなかった(データベースの障害、依存先の停止)。時間を置けば通る見込みがある。

署名の検証に失敗したときは、受け取った内容を処理せずに 400 か 401 を返します。検証を通ったあとで処理に失敗した場合、重い処理をキューに入れる前なら 5xx を返して再送させ、キューに入れた後なら 2xx を返してキューの側でやり直します。

429 と Retry-After

受ける側が過負荷のときに 429 と Retry-After を返しても、それに従う送る側は多くありません。上の表の送る側で、Retry-After に従うと公式に書いているものは見当たりませんでした。Standard Webhooks の仕様も「送る速さを落とすことを勧める」にとどまります。受ける側の負荷対策は、429 に頼らず、受け取ったらすぐキューに入れて 2xx を返す形にしておくのが確実です。

リダイレクトと Google Apps Script の 302

送る側の多くはリダイレクトを追いません。Stripe は 3xx を失敗とみなし、「リダイレクトで解決される先の URL を送信先に設定する」よう書いています。追わない理由は、登録時に検査した URL と違う宛先へ本文と署名を送ることになるためです。Standard Webhooks の仕様も 3xx は失敗とし、URL を直すよう勧めています。

Google Apps Script(GAS)の Web アプリで Webhook を受けると、送る側に 302 が返ることがあります。Apps Script の Content Service が返す内容は、安全のため script.googleusercontent.com の一度きりの URL にリダイレクトされるからです(Apps Script のドキュメント、2026-09-27 に確認)。GAS の側では doPost が実行されて処理が済んでいても、リダイレクトを追わない送る側には失敗と記録され、再送が来ます。GAS で受ける場合は、重複して処理されても困らない作りにするか、2xx を直接返せる受け口を別に用意します。

GitHub から Jenkins に送る Webhook が 302 で失敗するという質問は、Stack Overflow で 1 万 6 千回以上閲覧されています。送る側の画面の記録で 3xx が出ていたら、まず URL をリダイレクト先そのものに直します。

送る側として決めること

自社が Webhook を送る側なら、次の 4 点を決めて、受け手向けのドキュメントに書いておきます。

  1. 成功とみなすコード(2xx だけにするのが一般的)
  2. リダイレクトを追うか(追わないのが一般的)
  3. 410 で送信先を止めるか、他の失敗と同じく再送するか
  4. 429 と Retry-After に従うか

再送の間隔と諦めるまでの期間は再送の設計の記事で、各社のタイムアウトの秒数はタイムアウトの記事で扱います。

Webhook Admin の扱い

Webhook Admin は次のように扱います(2026-09-27 時点)。

  • 2xx だけを成功とします。
  • リダイレクトは追わず、3xx は失敗として再送します。
  • 410 も失敗として再送します。410 を受けても送信先は自動では止めず、失敗が 5 日続いたときに止めます。
  • 429 も他の失敗と同じ再送の予定(すぐ・5 秒・5 分・30 分・2 時間・5 時間・10 時間・10 時間)で送り直します。Retry-After は見ません。代わりに、同じ送信先に同時に送る数を 10 本までにし、5 回続けて失敗したら 30 秒送らずに様子を見ます。
  • タイムアウトは 15 秒です。応答の本文の先頭 1,024 バイトを配信の記録に残します。

API の側のエラーのコードはエラーのドキュメントにあります。応答のコードと本文を配信ごとに記録する送信の仕組みが必要なら、Webhook Admin を無料で試せます(月 5 万通まで)。https://app.webhookadmin.com/signup

よくある質問

200 と 204 はどちらを返せばよいですか。

どちらでも構いません。主要な送る側は 2xx の範囲を成功とみなしていて、200 と 204 を区別しません。応答の本文は送る側の記録に残ることがあるので、返すなら短い文にします。

410 を返すと送信は止まりますか。

送る側によります。Standard Webhooks の仕様は 410 を受けたら送る側が送信先を無効にするよう勧めていますが、2xx 以外をすべて同じ失敗として扱う送る側もあります。止めたい場合は、送る側の管理画面や API で送信先を消すか止めるのが確実です。

Google Apps Script で受けると 302 になるのはなぜですか。

Apps Script の Content Service が返す内容は、安全のために script.googleusercontent.com の一度きりの URL へリダイレクトされるからです。Webhook の送る側の多くはリダイレクトを追わず、3xx を失敗として扱うので、Apps Script の側で処理が済んでいても送る側には失敗と記録されます。

関連記事