情報確認日:2026年10月15日
OpenAI APIのWebhookは、同じ通知が複数回届く場合があります。受信側は署名を検証し、webhook-idで重複を判定して、一度だけ業務処理する設計にします。重い処理は別のワーカーへ渡し、受信には速く2xxを返します。ただし、保存せずに成功を返すと通知を失うため、受付の記録まで確実に残すことが必要です。
通知が届いたことと、業務が一度だけ終わることは別
Webhookは、バックグラウンド回答の完了やBatchの完了などを、管理するサーバーのURLへHTTP POSTで知らせる仕組みです。完了した回答を定期的に問い合わせる方法とは異なります。OpenAIのWebhookガイド
受信サーバーが成功を返さなかった場合や、数秒以内に応答しない場合、OpenAIは再送を試みます。公式説明では、指数バックオフで最大72時間配信を試みます。まれな内部システムの事情による重複も説明されています。
したがって、「一つのイベントだから一回しか届かない」という前提で、届くたびにメール送信や請求、ファイル作成を行うと、同じ処理が重なる可能性があります。
三種類のIDを取り違えない
公式の通知例には、ヘッダーのwebhook-id、本文のイベントid、data.idが出てきます。役割を分けて扱います。
| 項目 | 主な役割 | 確認する場面 |
|---|---|---|
| webhook-id | 通知の重複を除くキーとして公式が案内 | 同じ通知を再び受けたか |
| 本文のイベントid | イベントを特定 | ログ・イベントの対応 |
| data.id | 回答等の対象リソースを特定 | 完了した回答の取得など |
response.completedの例では、data.idは回答のIDです。同じ文字列のように見えても、重複判定のキーを対象回答IDへ勝手に置き換えません。Webhookのイベント参照
複数のイベント種類を購読する場合は、どのイベントを処理するかも決めます。想定外の種類を、正常な完了通知と同じ業務へ流し込まないようにします。
署名は、JSONを加工する前の本文で検証する
通知にはwebhook-timestampやwebhook-signatureなどのヘッダーがあります。受信側では、作成時に受け取った署名用のsecretと、原文のリクエスト本文・ヘッダーを使います。
公式SDKのwebhooks.unwrap()は、署名検証とイベントの解析を扱う方法として案内されています。JSONを一度読み込み、整形して文字列に戻すと、空白などが変わり、元の署名を検証する本文ではなくなります。フレームワーク側で生の本文を取得できるようにする必要があります。
APIを呼ぶキーと、Webhookの署名用secretも別です。署名が合わないときは、対象エンドポイントのsecret、本文を先に加工していないか、必要なヘッダーや時刻の扱いを確認します。検証を外して通す修正に進まないでください。
secretは作成後に再表示できないと公式に案内されています。漏えいや紛失があればローテーションし、受信サーバー側の設定も対応させます。secretを記事、ログ、問い合わせ文へ貼る必要はありません。
受付と、実際の処理を二段階にする
編集部による設計例は、次の順です。特定の言語で完成した実装を示すものではありません。
- 生の本文とヘッダーを受け取り、署名を検証する。
- 通知IDを記録し、処理待ちのイベントを確実に保存する。
- 同じIDがすでに受け付けられていれば、業務処理を重ねない。
- 受付ができたら2xxを返し、重い処理はワーカーで実行する。
- 業務側の成功・失敗・再試行を別に記録する。
同じ通知がほぼ同時に届くことを考えると、IDを調べてから保存するだけでは、その間に別の受信が進む可能性があります。データベースの一意制約や原子的な受付など、重複しない保存方法を開発側で選びます。
重複しない受付だけで、メールや外部システムへの送信まで必ず一回になる保証ではありません。途中失敗時にどこから再開するか、業務処理自体にも同じキーを使えるかを決めます。
動かない場合は、受信の段階を追う
ダッシュボードで購読するイベント種類と、外部から到達可能な最終URLを確認します。公式説明では3xxのリダイレクトは追わず失敗と扱うため、転送前のURLを登録したままにしません。
テスト通知で、受信、署名、記録、2xx応答、ワーカー処理の順にログを確認します。同じ通知を再び入力したケースや、ワーカーが失敗したケースも分けて確認すると、通知だけ成功して業務が止まる問題を発見できます。
問い合わせるときは、発生日時、イベント種類、通知ID、応答コード、処理段階を整理し、secretやAPIキーは除きます。Webhookは通知の仕組みなので、再送と重複を前提に、受信した記録と業務の完了を別々に追えるようにしておくことが実用上の要点です。
参照資料
あわせて読みたい記事
執筆・検証:カネさん(政経プラスチャンネル運営)+ ChatGPT
