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

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

公開日: 2026-10-31
Source: https://webhookadmin.com/blog/webhook-response-status-codes/

## 要点

- 受け取れたら 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](https://docs.stripe.com/webhooks)、[Shopify の troubleshoot](https://shopify.dev/docs/apps/build/webhooks/troubleshoot)、[Shopify の配信](https://shopify.dev/docs/apps/build/webhooks/subscribe/https)、[GitHub の失敗の扱い](https://docs.github.com/en/webhooks/using-webhooks/handling-failed-webhook-deliveries)、[GitHub の推奨](https://docs.github.com/en/webhooks/using-webhooks/best-practices-for-using-webhooks)、[Slack の Events API](https://docs.slack.dev/apis/events-api/)、[LINE の受信](https://developers.line.biz/ja/docs/messaging-api/receiving-messages/)、[LINE のエラーの統計](https://developers.line.biz/ja/docs/messaging-api/check-webhook-error-statistics/)、[Standard Webhooks の仕様](https://github.com/standard-webhooks/standard-webhooks/blob/main/spec/standard-webhooks.md)

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

- **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 のドキュメント](https://developers.google.com/apps-script/guides/content)、2026-09-27 に確認）。GAS の側では `doPost` が実行されて処理が済んでいても、リダイレクトを追わない送る側には失敗と記録され、再送が来ます。GAS で受ける場合は、重複して処理されても困らない作りにするか、2xx を直接返せる受け口を別に用意します。

GitHub から Jenkins に送る Webhook が 302 で失敗するという質問は、[Stack Overflow](https://stackoverflow.com/questions/49848884/github-webhook-with-jenkins-return-302-found) で 1 万 6 千回以上閲覧されています。送る側の画面の記録で 3xx が出ていたら、まず URL をリダイレクト先そのものに直します。

## 送る側として決めること

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

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

再送の間隔と諦めるまでの期間は[再送の設計の記事](https://webhookadmin.com/blog/webhook-retry-design/)で、各社のタイムアウトの秒数は[タイムアウトの記事](https://webhookadmin.com/blog/webhook-timeouts/)で扱います。

## 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 の側のエラーのコードは[エラーのドキュメント](https://webhookadmin.com/docs/api/#errors)にあります。応答のコードと本文を配信ごとに記録する送信の仕組みが必要なら、Webhook Admin を無料で試せます（月 5 万通まで）。[https://app.webhookadmin.com/signup](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 の側で処理が済んでいても送る側には失敗と記録されます。
