ドキュメント

API リファレンス

基本

URL
https://api.webhookadmin.com/v1
認証
Authorization: Bearer sk_live_… または sk_test_…。読み書きできるのは、そのキーの環境内のデータのみです
形式
JSON。時刻は Unix ミリ秒、ID は接頭辞付きの文字列
ボディの上限
1.1MB(超えると 413 too_large)
一覧
?cursor=&limit=(limit は 1〜100、既定 50)。レスポンスは { items, next_cursor }

一覧の cursor と、メッセージ・配信の ID は、ログ保存期間の最も古い月から今月までのもののみ受け付けます(範囲外の cursor には 422、ID には 404 を返します)。

エラー

{ "error": "<code>", "message": "<説明>" }
HTTPerror説明
401unauthorizedキーが無い、誤っている、失効済み、または期限切れ
402plan_limitプランの上限に達した
403forbiddenキーのスコープに含まれない操作
404not_found対象が見つからない
409conflict既存のデータと競合する
409endpoint_disabledエンドポイントが自動で無効化されている。設定を修正して再開してから再送信する
413too_largeボディが 1.1MB を超える
422invalid入力内容の誤り
429rate_limitedレート制限を超えた

レート制限

1 分あたりのリクエスト数を、環境ごとにすべてのキーの合計で数えます。

プラン1 分あたり
Free600
Starter3,000
Pro12,000
Business20,000
レスポンスヘッダー説明
x-ratelimit-limit1 分あたりの上限回数
x-ratelimit-remaining現在の 1 分間の残り回数
x-ratelimit-reset現在の 1 分間が終わる時刻(Unix 秒)
retry-after429 の場合のみ。再試行できるまでの秒数

API 一覧

メソッドパススコープ
POST/v1/messagesmessages:send
GET/v1/messageslogs:read
GET/v1/messages/{id}logs:read
POST/v1/deliveries/{id}/retrymessages:retry
GET/v1/consumerslogs:read
POST/v1/consumersconsumers:write
DELETE/v1/consumers/{id}consumers:write
POST/v1/consumers/{id}/portalendpoints:write
GET/v1/endpointslogs:read
POST/v1/endpointsendpoints:write
GET/v1/endpoints/{id}logs:read
PATCH/v1/endpoints/{id}endpoints:write
DELETE/v1/endpoints/{id}endpoints:write
POST/v1/endpoints/{id}/rotate-secretendpoints:write
POST/v1/endpoints/{id}/testmessages:send
POST/v1/destinations/testendpoints:write
GET/v1/endpoints/{id}/transformationlogs:read
PUT/v1/endpoints/{id}/transformationendpoints:write
DELETE/v1/endpoints/{id}/transformationendpoints:write
POST/v1/endpoints/{id}/transformation/testendpoints:write
GET/v1/poller/{endpoint_id}ポーリングトークン(sk_poll_…。API キーではありません)
GET/v1/endpoints/{id}/poller-tokenslogs:read
POST/v1/endpoints/{id}/poller-tokensendpoints:write
DELETE/v1/endpoints/{id}/poller-tokens/{token_id}endpoints:write
POST/v1/endpoints/{id}/recovermessages:retry
GET/v1/endpoints/{id}/recoveries/{recovery_id}logs:read
GET/v1/event-types不要(その環境の API キーであれば可)
POST/v1/event-typesendpoints:write
GET/v1/sourceslogs:read
POST/v1/sourcesendpoints:write
GET/v1/sources/{id}logs:read
PATCH/v1/sources/{id}endpoints:write
DELETE/v1/sources/{id}endpoints:write
PUT/v1/sources/{id}/secretendpoints:write
GET/v1/sources/{id}/requestslogs:read
POST/v1/sources/{id}/requests/{request_id}/reprocessmessages:send
POST/in/{token}受信 URL(API キーは不要)

メッセージの送信

POST /v1/messages

スコープ: messages:send

パラメーター型説明
consumerstring顧客 ID(external_id。200 文字まで)
event_typestringイベントタイプ。英数字と _ . : - で 100 文字まで
payloadJSON配信するペイロード。1MB まで
transformations_paramsobject任意。トランスフォーメーションに webhook.transformationsParams として渡す値(JSON で 4KB まで)。transformationsParams の表記も受け付けます
Idempotency-Key(ヘッダー)string任意。1〜256 文字

レスポンス: 202 { id, deliveries }。deliveries は作成された配信の数です。

  • 同じ Idempotency-Key には、24 時間は同じ id を返します(ペイロードが異なっても最初のメッセージの id です)。
  • consumer に該当する顧客アカウントが無い場合は、自動で作成します(エンドポイントが無いため deliveries は 0 です)。
  • deliveries が 0 のメッセージ(エンドポイントが無い)は、ステータス no_endpoint で記録のみ残します。配信は行わず、月間配信数にも数えません。後からエンドポイントを追加しても、このメッセージは配信されません。
  • レスポンスヘッダー x-usage-month には、組織の今月(UTC)の本番環境の配信数(エンドポイントがあったメッセージの数)が入ります。
  • テスト環境での送信とテスト送信は料金の対象外です。上限は 1 環境につき 1 日(UTC)1,000 通で、超えると 402 plan_limit を返します。

メッセージの一覧

GET /v1/messages

スコープ: logs:read

クエリ: status(pending / retrying / success / failed / cancelled / no_endpoint)・event_type・q・since(Unix ミリ秒。この時刻以降に作成されたもの)・cursor・limit。

no_endpoint は、受け付けた時点で配信先のエンドポイントが 1 つも無かったメッセージです(顧客アカウントにエンドポイントが無い、または対象イベントが一致するエンドポイントが無い)。記録のみ残して配信は行わず、月間配信数にも数えません。後からエンドポイントを追加しても、このメッセージは配信されません。2026-10-05 より前は、これらを pending として返していました(それ以前に受け付けた分も、現在は no_endpoint として返します)。

q は、メッセージ ID・イベントタイプ・顧客 ID(external_id)・Idempotency-Key を部分一致で検索します。ペイロードの中身は検索しません。

q・status・event_type を指定して since を省略すると、直近 7 日間に作成されたメッセージのみを返します。

レスポンス: { items: MessageRow[], next_cursor }。

メッセージの詳細

GET /v1/messages/{id}

スコープ: logs:read

レスポンス: MessageDetail(ペイロードと、エンドポイントごとの配信・配信試行)。

配信の再送信

POST /v1/deliveries/{id}/retry

スコープ: messages:retry

id は Delivery の ID。レスポンス: 202。

  • 配信中(pending・retrying)の場合は 409 conflict を返します。
  • エンドポイントが自動で無効化されている(disabled)場合は、409 endpoint_disabled を返して受け付けません。エンドポイントの設定を修正し、エンドポイントの更新 で status: active に戻してから呼び出してください。状態は MessageDetail の deliveries[].endpoint_status で事前に確認できます。
  • 一時停止中(paused)のエンドポイントへの再送信は受け付けて保留し、再開時に配信します。エンドポイントが削除された配信は 404 not_found を返します。

顧客アカウントの一覧

GET /v1/consumers

スコープ: logs:read

クエリ: cursor・limit。レスポンス: { items: Consumer[], next_cursor }。

顧客アカウントの作成

POST /v1/consumers

スコープ: consumers:write

パラメーター型説明
external_idstring自社サービスでの顧客 ID(200 文字まで)
namestring任意。200 文字まで

レスポンス: 201 Consumer。同じ external_id の顧客アカウントが既にある場合は 409 conflict を返します。

顧客アカウントの削除

DELETE /v1/consumers/{id}

スコープ: consumers:write

顧客アカウントと、そのエンドポイント(署名シークレット・トランスフォーメーション・ポーリングエンドポイントのトークン)、この顧客アカウントに配信するソース(受信ログを含む)を削除します。この操作は取り消せません。レスポンス: 204。存在しない顧客アカウントや、別の環境の顧客アカウントには 404 を返します。

  • 顧客ポータルのリンクは、有効期限内でも直ちに使用できなくなります。
  • 未配信の配信(再送信待ちを含む)は配信しません。ログ上は失敗となり、ポーリングエンドポイントで待機中の配信はキャンセル(cancelled)になります。
  • 配信ログは、プランのログ保存期間を過ぎた時点で、その日の他のログと一緒に削除されます。月間配信数の集計は残ります。
  • 同じ external_id でメッセージを送信すると、エンドポイントの無い新しい顧客アカウントとして作成されます。

エンドポイントの一覧

GET /v1/endpoints

スコープ: logs:read

クエリ: consumer_id(任意)。レスポンス: { items: Endpoint[] }。

エンドポイントの作成

POST /v1/endpoints

スコープ: endpoints:write

パラメーター型説明
consumer_idstring顧客アカウントの id(con_…)
urlstringエンドポイント URL(2,000 文字まで)。type が http(既定)の場合に指定
typestring任意。エンドポイントの種類。http(既定)、polling(ポーリングエンドポイント。url と destination は指定しません)、または Webhook 以外のエンドポイント(Webhook 以外のエンドポイント)。webhook・pollingEndpoint も受け付けます
destinationobjectWebhook 以外のエンドポイントの設定と認証情報。url の代わりに指定します
event_typesstring[]任意。対象イベントのイベントタイプ。省略時はすべて
fixed_ipboolean任意。固定送信元 IP から配信する
descriptionstring任意。200 文字まで
retryobject任意。再送信回数と再送信間隔(再送信ポリシー)。省略時は既定値
compat_signatureobject任意。互換署名(署名検証)
orderingstring任意。配信順序(順序保証)。none(既定)または fifo
body_formatstring任意。ペイロード形式。standard(既定。{ type, timestamp, data })または raw(data そのもの)
secretstring任意。現在お使いの署名シークレット(whsec_…)。省略すると新しく生成します(他サービスからの移行(Webhook))

レスポンス: 201 Endpoint と secret(署名シークレット。作成時のみ)・poller_url(ポーリング用の URL。http の場合は null)。

  • URL は https(ポート 443 または 8443)を指定します。
  • IP アドレスを直接指定した URL、社内向けのホスト名、社内アドレスに解決されるホスト名、名前解決できないホスト名には 422 を返します。
  • 1 つの顧客アカウントに登録できるエンドポイントは 20 個までです。超えると 422 を返します。

エンドポイントの詳細

GET /v1/endpoints/{id}

スコープ: logs:read

レスポンス: Endpoint と recent: AttemptRow[]・retrying_count・waiting_count(順番待ちの件数。ordering: fifo の場合のみで、それ以外は 0)・recovery(直近の一括再送信。無ければ null)・poller_url(ポーリングエンドポイントの URL。http の場合は null)。

エンドポイントの更新

PATCH /v1/endpoints/{id}

スコープ: endpoints:write

パラメーター(すべて任意): url・event_types・status(active / paused)・description・retry・compat_signature・ordering・body_format。レスポンス: Endpoint。

  • paused にしたエンドポイントへの配信は保留されます。active に戻すと、今月と先月の保留分をまとめて配信します。
  • 自動で無効化されたエンドポイント(disabled)は、status を active にすると再開します。
  • retry に null を指定すると既定値に戻り、compat_signature に null を指定すると解除されます。
  • ordering を fifo から none に戻すと、順番待ちの配信を直ちに配信します。
  • type は作成後に変更できません(422)。
  • 署名シークレット(secret)は更新では指定できません(422)。署名シークレットのローテーション で変更してください。

エンドポイントの削除

DELETE /v1/endpoints/{id}

スコープ: endpoints:write

レスポンス: 204。

署名シークレットのローテーション

POST /v1/endpoints/{id}/rotate-secret

スコープ: endpoints:write

レスポンス: { secret }。ローテーション後 24 時間は、旧シークレットによる署名も付けて配信します。

エンドポイントへのテスト送信

POST /v1/endpoints/{id}/test

スコープ: messages:send

このエンドポイントだけにテストメッセージを 1 通送信します。リクエストボディは省略できます。

パラメーター型説明
event_typestring任意。既定値は webhook.test
payloadobject任意。送信する data(JSON オブジェクト、1MB まで)。実際のイベントのサンプルを、このエンドポイントにだけ送信できます
  • payload を省略した場合、Webhook のエンドポイントには { "test": true, "endpoint_id": … } を送信します。チャット(Slack・Teams・Chatwork・Google Chat)のエンドポイントには、題「テストメッセージ」・本文「Webhook Admin からのテスト送信です。この送信先に通知が届くことを確認できました。」のメッセージを送信します(組織の通知の言語が英語の場合は英語)。
  • トランスフォーメーションは、通常のメッセージと同じく配信時に適用されます。
  • テスト送信は月間上限の対象外で、テスト環境での送信と同じく 1 環境 1 日 1,000 通までです。
  • エンドポイントが自動で無効化されている(disabled)場合は、409 endpoint_disabled を返します。

レスポンス: 202 { message_id }。結果は メッセージの詳細 で確認できます。

エンドポイントの接続テスト

POST /v1/destinations/test

スコープ: endpoints:write

パラメーター型説明
endpoint_idstring任意。保存済みのエンドポイントの設定と認証情報を使用
typestringendpoint_id を省略する場合は必須。Webhook 以外のエンドポイントの種類
destinationobjectendpoint_id を省略する場合は、認証情報を含めて必須。指定すると保存済みの設定を上書き
fixed_ipboolean任意。固定送信元 IP から送信する。省略時はエンドポイントの設定に従う

レスポンス: { ok, via, response_status, duration_ms, error, response_head, ref }。その場で 1 通(webhook.test)を送信し、ログには残しません。チャット(Slack・Teams・Chatwork・Google Chat)には、テスト送信 と同じ題「テストメッセージ」の案内文を送信します。テスト環境での送信と同じく、1 日の上限に数えます。Pro プラン以上で利用できます。

トランスフォーメーションの取得

GET /v1/endpoints/{id}/transformation

スコープ: logs:read

レスポンス: { endpoint_id, code, updated_at, enabled, variables }。トランスフォーメーションが無い場合は 404 not_found を返します。

トランスフォーメーションの保存

PUT /v1/endpoints/{id}/transformation

スコープ: endpoints:write

パラメーター型説明
codestringfunction handler(webhook) を定義する JavaScript。51,200 文字まで(トランスフォーメーション)。トランスフォーメーションが未設定の場合は必須
enabledboolean任意。false でコードを残したまま無効化、true で再び有効化
variablesobject任意。webhook.env に渡す値(文字列値で 50 個、JSON で 4KB まで)。null で削除

レスポンス: { endpoint_id, code, updated_at, enabled, variables }。省略した項目は現在の値を保持します。Pro プラン以上で利用できます(enabled: false のみの保存は全プランで可能です)。構文エラーのコード、handler が無いコード、空のコードには 422(fields.code)を返します。

トランスフォーメーションの解除

DELETE /v1/endpoints/{id}/transformation

スコープ: endpoints:write

レスポンス: 204。次回の配信試行から、トランスフォーメーションを適用せずに配信します。全プランで解除できます。

トランスフォーメーションのテスト

POST /v1/endpoints/{id}/transformation/test

スコープ: endpoints:write

パラメーター型説明
codestring任意。テストするコード。省略時は保存済みのコード
payloadany任意。サンプルの data。省略時は { "test": true, "endpoint_id": … }
event_typestring任意。既定値は webhook.test
variablesobject任意。webhook.env に渡す値。省略時は保存済みの値
transformations_paramsobject任意。webhook.transformationsParams に渡す値

レスポンス: { result: "send", method, url, headers, payload, changed, logs }・{ result: "cancel", logs }・{ result: "error", error: { kind, message }, logs } のいずれか。配信も保存も行いません。logs には console.log の出力が入ります。

メッセージの取得(ポーリング)

GET /v1/poller/{endpoint_id}

スコープ: ポーリングトークン(sk_poll_…。API キーではありません)

クエリ型説明
iteratorstring任意。前回のレスポンスの iterator。省略時はログ保存期間の始め(エンドポイントの作成日)から
limitnumber任意。1〜250(既定 50)
event_typestring任意。複数指定可。エンドポイントの event_types の中からさらに絞り込む
afterstring任意。ISO 8601 形式の時刻。iterator が無い場合のみ、その時刻から取得
channelstring任意。受け付けますが、チャンネル機能は未提供のため絞り込みは行いません

レスポンス: { data: PolledMessage[], iterator, done }。受け付けた順に返します。done: true は、現時点で続きが無いことを示します。受信側が Authorization: Bearer sk_poll_… を付けて呼び出します(ポーリングエンドポイント)。

互換パスの API は 他サービスからの移行(ポーリングエンドポイント) を参照してください。

ポーリングトークンの一覧

GET /v1/endpoints/{id}/poller-tokens

スコープ: logs:read

レスポンス: { items: PollerToken[] }(作成順)。トークンの文字列は返しません。

ポーリングトークンの作成

POST /v1/endpoints/{id}/poller-tokens

スコープ: endpoints:write

パラメーター: name(任意、100 文字まで)。リクエストボディは省略できます。

レスポンス: 201 PollerToken と token(sk_poll_…。作成時のみ)。Starter プラン以上で利用できます。1 つのエンドポイントにつき 5 個まで作成でき、超えると 422 を返します。http のエンドポイントには 404 を返します。

ポーリングトークンの削除

DELETE /v1/endpoints/{id}/poller-tokens/{token_id}

スコープ: endpoints:write

レスポンス: 204。削除したトークンでは、直ちにポーリングできなくなります。

一括再送信

POST /v1/endpoints/{id}/recover

スコープ: messages:retry

パラメーター型説明
sincenumberUnix ミリ秒。この時刻以降に作成されたメッセージが対象。ログ保存期間内の過去の時刻を指定

レスポンス: 202 Recovery。進捗は 一括再送信の状態 で確認します。

  • このエンドポイントへの配信が失敗で終わったものを、同じメッセージ(同じ webhook-id)のまま再送信します(一括再送信)。
  • エンドポイントが自動で無効化されている(disabled)場合は 409 endpoint_disabled、一時停止中(paused)の場合は 409 conflict を返します。再開してから呼び出してください。
  • 1 つのエンドポイントで同時に実行できる一括再送信は 1 つだけです。実行中は 409 conflict を返します。

一括再送信の状態

GET /v1/endpoints/{id}/recoveries/{recovery_id}

スコープ: logs:read

レスポンス: Recovery。status は running(実行中)・done(完了)・stopped(完了前にエンドポイントが一時停止・無効化・削除された)のいずれかです。

イベントタイプの一覧

GET /v1/event-types

スコープ: 不要(その環境の API キーであれば可)

レスポンス: { items: EventType[] }(名前順。ページングはありません)。

イベントタイプの登録

POST /v1/event-types

スコープ: endpoints:write

パラメーター型説明
namestringイベントタイプ。英数字と _ . : - で 100 文字まで
descriptionstring任意。200 文字まで

レスポンス: 201 EventType。同じ name のイベントタイプが既にある場合は 409 conflict を返します。

登録したイベントタイプは、管理画面と顧客ポータルでエンドポイントの対象イベントを選ぶときの候補に表示されます。

ソースの一覧

GET /v1/sources

スコープ: logs:read

レスポンス: { items: Source[], next_cursor }(作成順)。

ソースの作成

POST /v1/sources

スコープ: endpoints:write

パラメーター型説明
namestring1〜100 文字
providerstringstripe・github・shopify・slack・meta・zoom・standard・hmac・basic・api_key・none
consumer_idstring配信先の顧客アカウントの ID
secretstring任意。署名シークレット(500 文字まで)。standard の場合は whsec_…。後から 署名シークレットの登録 でも登録できます
configobject任意。SourceConfig(ソースの設定)
statusstring任意。active(既定)または paused

レスポンス: 201 Source。url が受信 URL です。ソースの数がプランの上限を超える場合は 402 plan_limit、顧客アカウントが見つからない場合は 404 を返します。

ソースの詳細

GET /v1/sources/{id}

スコープ: logs:read

レスポンス: Source。署名シークレットは、マスクしたヒント(secret_hint)のみを返します。

ソースの更新

PATCH /v1/sources/{id}

スコープ: endpoints:write

パラメーター: name・provider・consumer_id・status・config(すべて任意)。レスポンス: Source。

  • provider を変更すると、署名シークレットは解除されます。新しいサービスの署名シークレットを 署名シークレットの登録 で登録してください。
  • provider を変更して config を省略すると、その provider の既定の設定が適用されます。config を指定すると、設定を置き換えます。
  • 署名シークレットは 署名シークレットの登録 で再登録します(secret を指定すると 422)。
  • status: paused にすると受信したリクエストを保留します。active に戻すと再開し、保留したリクエストを配信します(一時停止)。

ソースの削除

DELETE /v1/sources/{id}

スコープ: endpoints:write

レスポンス: 204。以降、受信 URL は 404 を返します。受信ログも削除されます。

署名シークレットの登録

PUT /v1/sources/{id}/secret

スコープ: endpoints:write

パラメーター型説明
secretstring | null各サービスの管理画面に表示される署名シークレット(500 文字まで)。standard は whsec_…、それ以外は空白を含まない文字列。null で解除

レスポンス: Source。再登録後も 24 時間は、以前の署名シークレットで署名されたリクエストを受け付けます。null を指定すると、以前のものを含めてすべて解除します。

ソースの受信ログ

GET /v1/sources/{id}/requests

スコープ: logs:read

クエリ(すべて任意): cursor・limit・status(accepted・duplicate・rejected・held のいずれかで絞り込み)。レスポンス: { items: SourceRequest[], next_cursor }(新しい順。プランのログ保存期間内のみ)。

status説明
accepted受付済み。message_id は作成したメッセージの ID
duplicate重複。同じ配信 ID の再送信で、message_id は前回と同じメッセージの ID
rejected拒否。reason に英語の理由
held保留。一時停止中に受信したリクエストで、再開時に処理します
  • method は受信したメソッド(POST・PUT・PATCH・DELETE・GET)です。
  • processed_at は、保留または拒否したリクエストを後から処理した時刻です(未処理の場合は null)。
  • reprocessable: true のリクエストは 拒否したリクエストの再処理 を実行できます。
  • headers には受信したヘッダーが入ります(認証情報・Cookie などは除きます)。

拒否したリクエストの再処理

POST /v1/sources/{id}/requests/{request_id}/reprocess

スコープ: messages:send

拒否したリクエストを、現在の署名シークレットと設定で再検証してから処理します(再処理)。レスポンス: 更新後の SourceRequest。

  • 受け付けると accepted(または duplicate)になり、月間配信数に数えます。一時停止中のソースでは held になります。
  • 検証に失敗した場合は rejected のままで、reason と processed_at を更新します。
  • 拒否以外のリクエストと、ボディが保存されていないリクエスト(reprocessable: false)には 409、ログ保存期間を過ぎたリクエストには 404 を返します。

受信 URL

POST /in/{token}

スコープ: 受信 URL(API キーは不要)

送信元サービスが Webhook を送信する URL です(ソース)。POST・PUT・PATCH・DELETE を受け付けます(GET は Meta のサブスクリプション確認のみ)。ボディは 10MB まで。署名を検証してから、ソースの顧客アカウント宛てのメッセージを作成します。

HTTP説明
200受付済み。{ "id": "msg_…" }(受付時のレスポンス を設定した場合はそのレスポンス)。同じ配信 ID の再送信には同じ ID を返します。一時停止中は保留して { "status": "held", "request_id": "sreq_…" } を返します。Slack・Zoom・Meta の URL 確認には、各サービスの形式で応答します
401署名の不一致、署名ヘッダーが無い、時刻のずれが 5 分以上、署名シークレットが未登録、Basic 認証や API キーの不一致(Basic 認証は WWW-Authenticate: Basic 付き)
402プランのソース数の上限を超えている
403組織が停止されている、または Meta のサブスクリプション確認で hub.verify_token が一致しない
404受信 URL が見つからない
405POST・PUT・PATCH・DELETE 以外のメソッド(meta の GET を除く)
413ボディが 10MB を超える
4291 つのソースで 10 秒間に 1,000 回を超えた、none のソースで API の 1 分あたりのレート制限を超えた(いずれも retry-after 付き)、月間上限に達した、テスト環境の 1 日の上限に達した

拒否した場合のレスポンスボディは { "error": "<英語の理由>" } です(例: invalid signature・invalid credentials・invalid API key・timestamp outside the tolerance・signing secret is not set)。

再送信ポリシー

再送信回数と再送信間隔は、エンドポイントごとに設定できます。設定は管理画面・API(retry)・MCP・顧客ポータルで行います。

項目設定値
count0・1・2・3・5・7・12(初回配信後の再送信回数。0 は再送信しない)
intervalprogressive(5 秒・5 分・30 分・2 時間・5 時間・10 時間・10 時間、以降は 10 時間ごと)、1m・5m・30m・1h・6h(固定間隔)
{ "retry": { "count": 3, "interval": "5m" } }
  • 既定値は count: 7・interval: progressive です(初回配信を含めて最大 8 回、約 28 時間)。retry: null で既定値に戻ります。
  • 初回配信から最後の再送信までが 3 日を超える組み合わせは設定できません(422)。該当するのは progressive と 12 の組み合わせです。
  • 失敗が 5 日間続いたエンドポイントの自動無効化は、再送信ポリシーとは別に判定します。
  • 失敗が続いているエンドポイントへの配信は、一定時間停止します。その間の配信は行わずに再送信回数に数え、再送信ポリシーに従って次の時刻に再送信します。再送信回数を使い切ると失敗となります。

順序保証

エンドポイントごとに、受け付けた順に 1 通ずつ配信する順序保証(FIFO)を設定できます(ordering: fifo、既定は none)。設定は管理画面・API・MCP・顧客ポータルで行います。

{ "ordering": "fifo" }
  • 同時に配信するのは 1 通のみです。前の 1 通が配信成功または失敗で完了するまで、次の 1 通は配信しません。
  • 配信順序は API が 202 を返した順です。前のメッセージの 202 を受け取ってから送信したメッセージは、必ず後に配信されます。
  • 前の 1 通が失敗し続けている間は、後続の配信も待機します。前の 1 通は再送信ポリシーに従って再送信し、回数を使い切ると失敗として次へ進みます。
  • 後続が待機している間は、アラートに待機件数を記載します。エンドポイントの詳細(waiting_count)でも確認できます。
  • 失敗した配信を再送信すると(個別・一括とも)、現在待機中の配信の後に配信します。
  • 一時停止中に受け付けた配信も順序を保持し、再開すると先頭から順に配信します。
  • none に戻すと、待機中の配信を直ちに並行して配信します。fifo に設定する前に受け付けた配信は、順序保証の対象外です。
  • 順序保証はエンドポイント単位です。同じメッセージの他のエンドポイントには影響しません。
  • 1 通ずつ配信するため、配信速度は受信側の応答時間に依存します。

Webhook 以外のエンドポイント

エンドポイントの type を http 以外にすると、Webhook の代わりにキュー・イベントバス・オブジェクトストレージ・チャットへ配信します。ペイロードは Webhook のエンドポイントと同じです(既定は Standard Webhooks の JSON。body_format: raw の場合は data そのもの。チャットには メッセージとして投稿します)。Pro プラン以上で、管理画面・API・MCP・顧客ポータルから設定できます。

{
  "consumer_id": "con_…",
  "type": "sqs",
  "destination": {
    "region": "ap-northeast-1",
    "account_id": "123456789012",
    "queue_name": "orders",
    "credentials": { "access_key_id": "AKIA…", "secret_access_key": "…" }
  }
}
typedestinationcredentials署名と ID
sqsregion・account_id・queue_nameaccess_key_id・secret_access_keyメッセージの属性
eventbridgeregion・event_bus(既定 default)・source(既定 webhookadmin)・detail_type(既定はイベントタイプ)SQS と同じなし
pubsubproject_id・topicservice_account(サービスアカウントキーの JSON)メッセージの属性
s3region・bucket・prefixSQS と同じオブジェクトのメタデータ
r2account_id・bucket・prefixR2 の API トークンのアクセスキーオブジェクトのメタデータ
gcsbucket・prefixHMAC キーまたは service_accountオブジェクトのメタデータ
azure_blobaccount・container・prefixaccount_keyBLOB のメタデータ(webhook_id など)
servicebusnamespace・entity(キューまたはトピック)key_name・key(送信権限を持つ SAS ポリシー)メッセージのプロパティ
kafkaurl(Confluent Cloud の REST エンドポイント。/kafka/v3/… を付けて送信するため、単体の REST Proxy には配信できません)・cluster_id・topicapi_key・api_secretレコードのヘッダー
rabbitmqurl(HTTP API の起点)・vhost(既定 /)・exchange・routing_keyusername・passwordメッセージのヘッダー
slackなしwebhook_url(Slack の Incoming Webhook の URL)署名なし
teamsなしwebhook_url(Teams のワークフローの URL)署名なし
chatworkroom_id(チャット ID の数字)api_token署名なし
google_chatなしwebhook_url(Google Chat のスペースの Webhook の URL)署名なし
  • 署名と ID は、webhook-id・webhook-timestamp・webhook-signature・event-type として、配信先のサービスが保持できる場所に格納します。受信側は Webhook と同じ SDK でペイロードを検証できます(チャットには付与しません)。
  • 配信先のホストは、region などの値から各事業者の公式エンドポイントを組み立てます。Kafka と RabbitMQ の url は、エンドポイント URL と同じ制約(https・ポート 443 または 8443・社内アドレスは不可)です。
  • オブジェクトストレージには、1 通を 1 つのオブジェクト <prefix><年>/<月>/<日>/<メッセージの ID>.json として保存します。再送信時は同じ名前で上書きします。
  • 認証情報は暗号化して保存し、API では返しません。返すのはマスクしたヒント(destination.credentials_hint)のみです。更新時に credentials を省略すると、現在の認証情報を使用します。Kafka と RabbitMQ で url のホストを変更する場合は、認証情報を再入力してください。
  • 再送信・再送信ポリシー・順序保証・トランスフォーメーション(ペイロードの変更とキャンセルのみ)・アラート・固定送信元 IP は、Webhook と同様に機能します。2xx が返っても配信先が受け付けなかったもの(EventBridge の失敗エントリなど)は失敗として扱います。
  • 配信試行の via はエンドポイントの種類(sqs など)、ref は配信先が返した ID(SQS の MessageId・オブジェクト名・Kafka のパーティションとオフセットなど)です。
  • エンドポイントの接続テスト で、保存前に 1 通送信して接続を確認できます。
  • type には、互換の種類名(eventBridge・googleCloudPubSub・amazonS3・googleCloudStorage・azureBlobStorage・rabbitMq)も指定できます。

チャット(Slack・Teams・Chatwork・Google Chat)

チャットには、JSON ではなくメッセージとして投稿します。ペイロードの data(body_format: raw の場合や、トランスフォーメーションで data が無くなった場合はペイロード全体)に文字列の text があれば、title(無ければイベントタイプ)・text・lines(文字列の配列、50 行まで)・link(https の URL のみ)からメッセージを組み立てます。text が無い場合は、件名をイベントタイプ、本文を data の JSON とし、上限を超える部分は切り捨てます(Slack は約 3,000 字、Teams は 28 KB、Chatwork は 60,000 字、Google Chat は全体で 4,000 字)。メッセージ ID を小さく添えます。

{
  "consumer_id": "con_…",
  "type": "chatwork",
  "destination": {
    "room_id": "123456789",
    "credentials": { "api_token": "…" }
  }
}

// ペイロードの data(またはトランスフォーメーション後のペイロード)
{
  "title": "請求書が支払われました",
  "text": "INV-1024 が支払われました(12,000 円)",
  "lines": ["顧客: 株式会社サンプル", "支払い方法: カード"],
  "link": "https://example.com/invoices/INV-1024"
}
  • Slack: Incoming Webhook の URL(https://hooks.slack.com/services/T…/B…/…)を webhook_url に指定します。
  • Teams: チャネルの[ワークフロー]で「Webhook 要求を受信したらチャネルに投稿する」テンプレートから作成した URL(*.powerplatform.com・*.logic.azure.com)を webhook_url に指定します。フローの実行権限は「すべてのユーザー」に設定してください。Adaptive Card 形式で投稿します。旧 Office 365 コネクタの URL(webhook.office.com)は使用できません。
  • Chatwork: 右上の利用者名 →[サービス連携]→[API トークン]で発行したトークンを api_token に、投稿先のチャット ID を room_id に指定します。個人向け以外のプランでは、組織管理者の承認が必要です。
  • Google Chat: スペース名の横のメニュー →[アプリと統合]→[Webhook を追加]で作成した URL(https://chat.googleapis.com/v1/spaces/…/messages?key=…&token=…)を webhook_url に指定します。件名は太字、リンクは <URL|ホスト名> の形式で投稿します。Google Workspace の管理者が Webhook を制限している場合は利用できません。
  • トランスフォーメーションで webhook.payload.data = { text: … }(body_format: raw の場合は webhook.payload = { text: … })のように指定すると、投稿するメッセージを指定できます。
  • 署名は付与しません。URL と API トークンがシークレットの役割を果たします。
  • URL やトークンが無効になった場合(Slack の 403・404・410、Teams の 401・403・404・410、Chatwork の 401・403・404、Google Chat の 401・403・404)は再送信せず、直ちにエンドポイントを disabled にして、理由(disabled_reason)を添えて無効化のアラートを送ります。認証情報を修正してから status を active に戻してください。
  • 400・413 の場合は、その 1 通のみ再送信せずに失敗とします(エンドポイントは無効化しません)。429 の場合は Retry-After(Chatwork は x-ratelimit-reset)の時刻以降に、最長 1 時間後までに再送信します(固定送信元 IP から配信する場合は通常の再送信間隔です)。5xx・タイムアウトは通常どおり再送信します。
  • 配信試行の ref は Chatwork のメッセージ ID です(Slack・Teams・Google Chat は null)。

他サービスからの移行(Webhook 以外のエンドポイント)

POST /api/v1/app/{app_id}/destination は、互換形式のエンドポイント設定(type・config・eventTypes・description)を受け付けて、エンドポイントを作成します。app_id には顧客アカウントの id または external_id を指定し、API キー(endpoints:write)で認証します。エラーは { code, detail } の形式で、detail は英語です。Webhook のエンドポイントの移行は 他サービスからの移行(Webhook) を参照してください。

互換の typeWebhook Admin の typeconfig の扱い
sqssqsqueueUrl から region・アカウント・キュー、accessKeyId・secretAccessKey
eventBridgeeventbridgeregion・eventBusName・detailType・アクセスキー
googleCloudPubSubpubsubprojectId・topicId・credentials(サービスアカウントキーの JSON)
amazonS3s3bucket・region・アクセスキー
googleCloudStoragegcsbucket・credentials(サービスアカウントキーの JSON)
azureBlobStorageazure_blobaccount・container・accessKey
rabbitMqrabbitmquri は HTTP API の URL(https://ユーザー名:パスワード@ホスト/)、routingKey
  • メッセージは 1 件ずつ配信します。batchSize・maxWaitSecs は指定できますが、配信には反映しません。
  • ペイロードは既定で Standard Webhooks の JSON(body_format: raw の場合は data の値)です。署名と ID は属性やメタデータに付与し、Webhook と同じ SDK で検証できます。
  • RabbitMQ の amqp://・amqps:// には対応していません。管理プラグインの HTTP API の URL を指定してください。
  • roleArn・externalId(IAM ロールの引き受け)と endpointUrl には対応していません。アクセスキーを指定してください。
  • SNS・BigQuery・ClickHouse・Snowflake・Redshift・Postgres・OpenTelemetry への配信には対応していません。
  • uid は使用しません。作成したエンドポイントの ID は ep_… で、取得・更新はエンドポイントの API で行います。

トランスフォーメーション

エンドポイントごとに JavaScript の function handler(webhook) を保存すると、配信の直前にペイロード・ヘッダー・URL のパスとクエリ・HTTP メソッドを変更したり、配信をキャンセルしたりできます。Pro プラン以上で、管理画面・API・MCP から設定できます。

function handler(webhook) {
  const d = webhook.payload.data;
  webhook.payload = { text: `Invoice ${d.id} paid (${d.amount})` };
  webhook.headers['x-tenant'] = 'acme';
  webhook.url = webhook.url + '?source=webhookadmin';
  if (d.amount === 0) webhook.cancel = true;
  return webhook;
}
項目説明
payload配信するペイロード。{ type, timestamp, data }(body_format: raw のエンドポイントでは data そのもの)。任意の JSON 値に置き換えられます(1MB まで)
headers追加するヘッダー(20 個・合計 8KB まで)。webhook-*・content-type など配信に使うヘッダーは設定できません
methodPOST・PUT・PATCH
urlスキーム・ホスト・ポートはそのままで、パスとクエリのみ変更できます
canceltrue で配信しません。配信は cancelled となります(失敗ではなく、再送信しません)
eventTypeイベントタイプ(読み取り専用)
envトランスフォーメーションと一緒に保存した variables(読み取り専用。無ければ {})
transformationsParamsメッセージの送信時に指定した transformations_params(読み取り専用。指定しなかった場合は項目自体がありません)
  • 配信試行ごとに、保存されている元のペイロードから実行します。署名はトランスフォーメーション後のペイロードで生成します。
  • 例外、上限超過、戻り値の誤りが発生した場合は配信せずに失敗とし、再送信しません。配信試行の error に transformation: <種類>: <説明> が記録されます。コードを修正してから再送信してください。
  • 1 回の実行あたりの処理量とメモリに上限があります。コードは 51,200 文字までです。外部との通信はできません。
  • トランスフォーメーションに渡せるペイロードは 1MB までです。ソースで受信した 1MB を超えるボディにはトランスフォーメーションを適用できず、配信は失敗となります(受信ボディの転送)。
  • variables は文字列値で 50 個・JSON で 4KB まで、transformations_params は JSON で 4KB までです。
  • enabled: false で保存すると、コードと variables を保持したまま、トランスフォーメーションを適用せずに配信します。無効化は全プランで可能です。
  • トランスフォーメーションでペイロードなどを変更した配信試行は transform: "changed" になります。
  • トランスフォーメーションのテスト で、配信せずに結果と console.log の出力を確認できます。
  • 顧客ポータルには表示されません。

ポーリングエンドポイント

type: polling のエンドポイントは URL を持ちません。受信側がポーリングトークン(sk_poll_…)を付けて メッセージの取得 を呼び出し、受け付けた順にメッセージを取得します。外部から到達できない環境や、Webhook の受信口を公開できない環境でも受信できます。Starter プラン以上で、管理画面・API・MCP・顧客ポータルから作成できます。

curl -H "Authorization: Bearer sk_poll_..." \
  "https://api.webhookadmin.com/v1/poller/ep_...?iterator=<前の iterator>&limit=100"
{
  "data": [
    {
      "id": "msg_2026092912ab34cd56ef7800",
      "event_type": "invoice.paid",
      "timestamp": "2026-09-29T03:04:05.000Z",
      "payload": { "type": "invoice.paid", "timestamp": "2026-09-29T03:04:05.000Z", "data": { "id": "inv_1" } },
      "headers": { "webhook-id": "msg_…", "webhook-timestamp": "1790651045", "webhook-signature": "v1,…" }
    }
  ],
  "iterator": "MjAyNi0wOS0yOS4wLjE",
  "done": true
}
  • payload・id・headers(webhook-id・webhook-timestamp・webhook-signature)は、Webhook で配信する場合と同じです。通信はトークンと TLS で保護されているため署名の検証は不要ですが、エンドポイントの署名シークレットで JSON.stringify(payload) を検証することもできます。
  • 次の呼び出しに前回のレスポンスの iterator を付けると、前のページを受信済みとみなし、その配信を success にします(取得時刻は配信試行 via: "poll" に記録)。処理が完了してから iterator を保存し、次回はそこから取得してください。
  • 少なくとも 1 回の配信(at-least-once)を保証します。前回の iterator で呼び出すと、同じメッセージを再度返します。iterator を付けない場合はログ保存期間の始めから取得するため、必要に応じて id で重複を除外してください。
  • トークンで取得できるのは、発行元のエンドポイントのメッセージのみです。他のエンドポイントには 403 を返します。トークンは 1 つのエンドポイントにつき 5 個まで作成でき、削除すると直ちに無効になります。呼び出しは 1 つのエンドポイントにつき 1 分あたり 600 回までです。
  • ログ保存期間内に取得されなかったメッセージは、ログと一緒に削除されます。組織で設定した時間(既定 24 時間)ポーリングされない場合は、アラート で通知します。
  • 再送信・一括再送信・トランスフォーメーション・固定 IP・互換署名・ordering: fifo には対応していません(受け付けた順に取得するため、順序は保証されます)。
  • 一時停止中、およびプランのダウングレード後に受け付けたメッセージは、このエンドポイントでは取得できません。エンドポイントを削除すると、未取得のメッセージは cancelled になります。
  • event_type で絞り込んだ場合、対象外のメッセージも次の呼び出しで受信済みとして扱います。
  • SDK(Node.js・Python・Go・PHP)の Poller は、ページを順に取得して iterator を返します。

他サービスからの移行(ポーリングエンドポイント)

互換形式のポーリングで取得している受信側は、接続先の URL を https://api.webhookadmin.com に、トークンを sk_poll_… に変更するだけで、同じ形式で取得できます。

メソッドパス説明
GET/api/v1/app/{app_id}/poller/{endpoint_id}{ data: [{ id, eventType, payload, timestamp }], iterator, done }。payload は送信した data の値(エンドポイントの body_format に関係なく同じ)。app_id には顧客アカウントの id または external_id を指定
GET/api/v1/app/{app_id}/poller/{endpoint_id}/consumer/{consumer_id}読み取り位置を Webhook Admin 側で保持し、取得のたびに進めます
POST…/consumer/{consumer_id}/seek{ after }(ISO 8601)→ { iterator }。読み取り位置を指定の時刻に合わせます
GET/api/v1/auth/app/{app_id}/poller/{endpoint_id}/token送信側の API キー(endpoints:write)で、現在のトークン { token, id, name, createdAt, expiresAt, scopes } を取得。無い場合は作成します
POST…/token/rotate{ expiry?, oldTokenExpiry? }(秒)。以前のトークンは既定で 300 秒後に無効になり、0 を指定すると即時に無効になります
  • エラーは { code, detail } の形式で、detail は英語です。形式が正しくない iterator には 400 invalid_iterator を返します。
  • event_type・channel・after のクエリにも対応しています(メッセージの取得)。
  • エンドポイントの種類には http・polling のほか、pollingEndpoint も指定できます。
  • v2 の API(offset と commit)には対応していません。
  • Webhook のエンドポイントの移行は 他サービスからの移行(Webhook) を参照してください。

他サービスからの移行(Webhook)

署名シークレット(whsec_…)とペイロード形式をエンドポイントごとに指定できます。そのため、Standard Webhooks 形式で送信しているサービスから、受信側の設定と署名検証の実装を変更せずに移行できます。function handler(webhook) 形式のトランスフォーメーションのコードも、下記の相違点に該当しない限り修正は不要です。Webhook 以外のエンドポイントは 他サービスからの移行(Webhook 以外のエンドポイント)、ポーリングエンドポイントは 他サービスからの移行(ポーリングエンドポイント) を参照してください。

移行元の項目Webhook Admin での対応
署名シークレット(whsec_…)エンドポイントの作成時に secret で指定
ペイロード(data のみを送る形式)エンドポイントに body_format: "raw" を指定
メッセージの送信(POST /api/v1/app/{app_id}/msg)POST /v1/messages で送信。consumer に顧客 ID(external_id)を指定
トランスフォーメーション(handler(webhook))同じ関数の形式に対応。webhook.env・webhook.transformationsParams も利用可能
POST /v1/endpoints
{
  "consumer_id": "con_…",
  "url": "https://example.com/webhooks",
  "secret": "whsec_…",
  "body_format": "raw"
}
  • secret には、whsec_ に続けて標準の base64 で表したシークレット(デコード後 24〜75 バイト)を指定します。whsec_ は省略できます。非対称鍵(whsk_・whpk_)には対応していません(422)。
  • 指定した署名シークレットは、自動生成したものと同様に暗号化して保存します。表示と ローテーション(ローテーション後 24 時間は旧シークレットの署名も併せて配信)も同じ扱いです。
  • secret を指定できるのは、API・MCP・SDK から作成する場合です。管理画面と顧客ポータルから作成した場合は、新しい署名シークレットを生成します。
  • body_format は管理画面・API・MCP・SDK・顧客ポータルで設定できます。raw の場合も署名は webhook-id・webhook-timestamp・webhook-signature ヘッダーに付与し、計算方法は Standard Webhooks の仕様どおりです。

トランスフォーメーションは、互換パスの API でも取得・更新できます(Pro プラン以上)。

メソッドパス説明
GET/api/v1/app/{app_id}/endpoint/{endpoint_id}/transformation{ code, enabled, variables, updatedAt }。トランスフォーメーションが無い場合、code・variables・updatedAt は null、enabled は false(logs:read)
PATCH同じパス{ code?, enabled?, variables? } → 204。code は 10〜51,200 文字、null で解除。省略した項目は現在の値を保持(endpoints:write)
POST…/transformation/simulate{ code, eventType, payload, variables? } → { url, payload, method, cancel }。payload は配信するペイロードの文字列。配信も保存も行わない(endpoints:write)
  • app_id には顧客アカウントの id または external_id を指定し、API キーで認証します。
  • enabled: false にすると、コードと variables を保持したまま、トランスフォーメーションを適用せずに配信します。
  • body_format: "raw" のエンドポイントでは、webhook.payload は data の値です。
  • これらの API のエラーは { code, detail } の形式で、detail は英語です。422 の場合は fields(項目名は camelCase)も返します。
  • 互換パスのうち、メッセージの送信や配信ログの取得など Webhook Admin で提供していないものは、404 not_found を返します。送信とログの取得には /v1 の API をご利用ください。

移行元との主な相違点は次のとおりです。

  • トランスフォーメーションで変更できるのは URL のパスとクエリのみで、ホストは変更できません。
  • トランスフォーメーションでは、webhook-*・content-type など配信に使うヘッダーは設定できません。
  • Webhook 以外のエンドポイントには、メッセージを 1 件ずつ署名付きで配信します。
  • 顧客ポータルではトランスフォーメーションを設定できません。送信側で設定してください。
  • トランスフォーメーションで配信をキャンセルした場合、配信ログには失敗ではなく cancelled として記録されます。

一括再送信

エンドポイントの障害が復旧した後、そのエンドポイントへの配信が失敗で終わったものを、指定した時刻以降の分だけ一括で再送信します。同じメッセージ(同じ webhook-id)のまま配信するため、受信側は処理済みの ID を破棄できます。

管理画面
エンドポイントの詳細
API
POST /v1/endpoints/{id}/recover(パラメーターとレスポンス)
MCP
recover_endpoint・get_recovery
顧客ポータル
顧客が自身のエンドポイントについて実行できます
  • キューで段階的に配信します(10 秒ごとに 50 通)。エンドポイントの同時接続数が上限に達している間は待機します。
  • 対象は、開始時点で失敗となっていた配信です。開始後に失敗したものや、個別に再送信したものは含みません。
  • 自動で無効化されていた(disabled)間のメッセージは、そのエンドポイント宛ての配信が作成されていないため対象外です。一時停止中(paused)の配信は保留されており、再開時に配信します。
  • 実行中にエンドポイントを一時停止・無効化・削除すると、その時点で終了します(stopped)。
  • 使用量には数えません。

アラートの条件

アラート(Slack・Teams・Chatwork・メール・Webhook)を送る条件は、組織ごとに設定できます。設定は管理画面の「アラート」の「通知条件」、または MCP の update_alert_conditions で行います。条件はすべての通知チャネルで共通です。

条件設定値既定
配信の失敗初回の失敗の直後、または失敗が 5 分・15 分・60 分続いたとき60 分
自動無効化失敗が 5 日間続いてエンドポイントを無効化したとき—
再送信待ちの件数環境の再送信待ちが 100 通・1,000 通・10,000 通を超えたとき(1 日 1 回)1,000 通
使用量今月の配信数が月間上限の 50%・80%・100% に達したとき80%
ポーリングされていないエンドポイントポーリングエンドポイントが 1・6・24・72 時間ポーリングされていないとき(再びポーリングされるまでに 1 回)24 時間
  • 配信の失敗は、どの設定でも再送信回数を使い切った時点で通知します。同じエンドポイントのアラートは 1 時間に 1 回までです。
  • 同じ組織への配信失敗のアラートは、1 時間に 1 通まで即時に送ります。その 1 時間内に失敗し始めた他のエンドポイントは、1 時間ごとに 1 通にまとめて送ります。
  • 再送信待ちの件数は、エンドポイント単位ではなく環境全体の合計で判定します。
  • 組織の owner には、この条件とは別に、使用量が月間上限の 80%・100% に達したときにメールで通知します。

ソース(他サービスからの Webhook の受信)

Stripe・GitHub・Shopify・Slack・Meta・Zoom・LINE などのサービスが送信する Webhook を受信し、署名を検証したうえで、指定した顧客アカウント宛てのメッセージを作成します。作成したメッセージは POST /v1/messages で送信したメッセージと同じ扱いで、その顧客アカウントのエンドポイントに配信します。再送信・順序保証・トランスフォーメーション・固定送信元 IP・Webhook 以外のエンドポイント・アラート・一括再送信もそのまま利用できます。設定は管理画面・API・MCP で行います。

POST /v1/sources
{ "name": "Stripe", "provider": "stripe", "consumer_id": "con_…" }

HTTP/1.1 201 Created
{ "id": "src_…", "provider": "stripe", "status": "active",
  "url": "https://api.webhookadmin.com/in/…", "secret_hint": null, … }
受信 URL
https://api.webhookadmin.com/in/{token}。ソースごとに発行し、送信元サービスの Webhook 設定に登録します(レスポンス)
配信先
ソースごとに指定する顧客アカウント(consumer_id)。自社用の顧客アカウントを作成し、社内システムをエンドポイントとして登録する使い方が一般的です
受け付けるリクエスト
POST・PUT・PATCH・DELETE(GET は Meta のサブスクリプション確認のみ)。ボディは 10MB までで、JSON・フォーム・テキスト・バイナリのいずれも受け付けます
署名シークレット
送信元サービスの管理画面からコピーして登録します。管理画面と API には、マスクしたヒント(secret_hint)のみを表示します。再登録後も 24 時間は、以前の署名シークレットを受け付けます
レート制限
ソースごとの受信回数に上限は設けていません。乱用防止のため、1 つのソースに 10 秒間で 1,000 回を超えて届いたリクエストには、429 と retry-after を返します。署名を検証しないソース(none)は、API の 1 分あたりのレート制限の対象にも含めます
ソース数
Free 1・Starter 5・Pro 20・Business 無制限(組織内のすべての環境の合計)

Stripe

  1. ソースを作成します(provider: stripe)。署名シークレットは後から登録できます。
  2. ソースの受信 URL をコピーします。
  3. Stripe ダッシュボードのワークベンチの「Webhook」タブで「イベント送信先を作成」を選択します。受信するイベントを選び、送信先のタイプに「Webhook エンドポイント」を選択して、エンドポイント URL に受信 URL を入力します。
  4. 作成したエンドポイントのページで「シークレットを表示」を押し、署名シークレット(whsec_…)をコピーして、ソースの署名シークレットに登録します(管理画面または 署名シークレットの登録)。

GitHub

  1. ソースを作成し(provider: github)、推測されにくい文字列を決めて署名シークレットに登録します。
  2. リポジトリまたは組織の「Settings」›「Webhooks」›「Add webhook」で、Payload URL に受信 URL、Content type に application/json、Secret に同じ文字列を入力します。
  3. 受信するイベントを選択して保存します。追加直後に届く ping も、イベントタイプ ping のメッセージとして受け付けます。

Shopify

  1. ソースを作成します(provider: shopify)。
  2. アプリの Webhook サブスクリプション(shopify.app.toml または Admin API)で、Webhook の URL に受信 URL を指定します。ストアの管理画面の「設定」›「通知」›「Webhook」で作成する場合も同様で、形式は JSON を選択します。
  3. 署名シークレットには、アプリで購読した Webhook の場合はアプリのクライアントシークレットを登録します。ストアの管理画面で作成した Webhook の場合は、同じ画面の Webhook 一覧の下に表示される署名キーを登録します。

Slack

  1. ソースを作成し(provider: slack)、Slack アプリの「Basic Information」›「App Credentials」にある「Signing Secret」を署名シークレットに登録します。
  2. 「Event Subscriptions」を有効にし、Request URL に受信 URL を入力します。Slack が送信する確認リクエスト(url_verification)には自動で応答するため、そのまま確認済みになります。
  3. 受信するイベントを選択して保存します。

Meta(Facebook・WhatsApp・Instagram)

  1. ソースを作成し(provider: meta)、アプリの「App settings」›「Basic」にある「App secret」を署名シークレットに登録します。サブスクリプションの確認に使う文字列を決め、config.verify_token に登録します。
  2. アプリの Webhooks の設定(WhatsApp は「WhatsApp」›「Configuration」、WhatsApp のユースケースで作成したアプリは「Use cases」›「Customize」›「Configuration」)で、コールバック URL に受信 URL、認証トークン(Verify token)に同じ文字列を入力します。
  3. Meta が送信するサブスクリプションの確認(GET の hub.mode=subscribe)には、hub.verify_token が config.verify_token と一致すれば hub.challenge を text/plain で返します。一致しない場合と未設定の場合は 403 を返します。
  4. 受信するフィールドを購読します。イベントタイプは、ペイロードの object と entry[0].changes[0].field を連結したものです(例 whatsapp_business_account.messages)。
{
  "provider": "meta",
  "config": { "verify_token": "…" }
}

Zoom

  1. ソースを作成し(provider: zoom)、Zoom App Marketplace のアプリの「Features」›「Access」に表示される「Secret Token」を署名シークレットに登録します。
  2. 同じ画面で「Event Subscription」を有効にし、「Add New Event Subscription」の「Event notification endpoint URL」に受信 URL を入力して「Validate」を押します。Zoom が送信する確認リクエスト(endpoint.url_validation)には、plainToken と encryptedToken で自動で応答します。
  3. 受信するイベントを選択して保存します。イベントタイプはペイロードの event です(例 meeting.started)。

LINE

  1. ソースを作成し(provider: hmac)、下記の config を指定します。LINE Developers コンソールのチャネルの「チャネル基本設定」タブにある「チャネルシークレット」を署名シークレットに登録します。
  2. チャネルの「Messaging API設定」タブで、Webhook URL に受信 URL を入力し、「Webhookの利用」をオンにします。
  3. 「検証」を押すと届くリクエスト(events が空)は、イベントタイプ inbound のメッセージとして受け付けます。
{
  "provider": "hmac",
  "config": {
    "header": "x-line-signature",
    "encoding": "base64",
    "event_type_field": "events.0.type"
  }
}

Standard Webhooks

Standard Webhooks 形式(webhook-id・webhook-timestamp・webhook-signature)で署名するサービスは、provider: standard で受け付けます。Svix で送信するサービスの svix-id・svix-timestamp・svix-signature も同じ形式として受け付けます。OpenAI・Replicate は webhook-、Clerk・Resend は svix- のヘッダーで送信します。署名シークレットには、送信元サービスの署名シークレット(whsec_…)をそのまま登録します。

独自の HMAC 署名

ボディの HMAC-SHA256 をヘッダーに付けて送信するサービスは、provider: hmac で受け付けます。署名シークレットには送信元サービスと共有している文字列をそのまま登録し、ヘッダー名などを config で指定します(ソースの設定)。

{
  "provider": "hmac",
  "config": {
    "header": "x-signature",
    "encoding": "hex",
    "prefix": "sha256=",
    "event_type_field": "event",
    "id_header": "x-delivery-id"
  }
}

Basic 認証

Basic 認証のユーザー名とパスワードを付けて送信するサービスは、provider: basic で受け付けます。ユーザー名を config.username に、パスワードを署名シークレットに登録します。一致しない場合は 401 と WWW-Authenticate: Basic を返します。

{
  "provider": "basic",
  "config": { "username": "webhook" }
}

API キー

API キーをヘッダーまたはクエリに付けて送信するサービスは、provider: api_key で受け付けます。キーの値を署名シークレットに登録します。ヘッダーの場合は config.header(値の前に付く文字列があれば config.prefix。例 "Bearer ")、クエリの場合は config.query にその名前を指定します。

{
  "provider": "api_key",
  "config": { "header": "authorization", "prefix": "Bearer " }
}

署名を付けないサービスは、provider: none で受け付けます。この場合、受信 URL を知っていることが唯一の認証手段になります。

ソースの設定

項目対象説明
headerhmac・api_key署名ヘッダー名(hmac では必須)。api_key ではキーのヘッダー名
queryapi_keyキーのクエリパラメーター名(header または query のいずれか)
encodinghmachex(既定)または base64
prefixhmac・api_key値の前に付く文字列(例 sha256=・"Bearer ")。除去してから比較します
usernamebasicユーザー名(必須。パスワードは署名シークレットに登録)
verify_tokenmetaサブスクリプション確認で hub.verify_token と比較する文字列
event_type_fieldhmac・basic・api_key・noneイベントタイプを読み取るペイロードの項目。入れ子は . で区切り、配列はインデックスで指定(例 data.type・events.0.type)
id_headerhmac・basic・api_key・none重複判定に使うヘッダー(送信元サービスの配信 ID)
event_typeすべてイベントタイプを取得できない場合のイベントタイプ(既定 inbound)
forward_headersすべてエンドポイントへ引き渡す受信時のヘッダー(20 個まで。受信ボディの転送)
responseすべて受付時のレスポンス(受付時のレスポンス)

署名の検証

provider検証するヘッダー時刻
stripeStripe-Signature5 分以内
githubX-Hub-Signature-256—
shopifyX-Shopify-Hmac-Sha256—
slackX-Slack-Signature・X-Slack-Request-Timestamp5 分以内
metaX-Hub-Signature-256(シークレットはアプリの App secret)—
zoomx-zm-signature・x-zm-request-timestamp5 分以内
standardwebhook-id・webhook-timestamp・webhook-signature(または svix-id・svix-timestamp・svix-signature)5 分以内
hmacconfig.header で指定したヘッダー—
basicAuthorization(Basic …)—
api_keyconfig.header のヘッダーまたは config.query のクエリ—

受信したボディのバイト列から計算し、定数時間で比較します。一致しない場合は 401 で拒否し、受信ログに理由を記録します。

次の URL 確認リクエストには、署名を検証したうえで各サービスの形式で応答します。メッセージは作成せず、月間配信数にも数えません。一時停止中も応答します。

  • Slack の url_verification: { "challenge": "…" }
  • Zoom の endpoint.url_validation: { "plainToken": "…", "encryptedToken": "…" }
  • Meta のサブスクリプション確認(GET): hub.challenge の値(text/plain)

イベントタイプと重複判定

providerイベントタイプ重複判定
stripeペイロードの type(例 invoice.paid)ペイロードの id(evt_…)
githubX-GitHub-Event とペイロードの action を連結したもの(例 pull_request.opened)X-GitHub-Delivery
shopifyX-Shopify-Topic(orders/create は orders.create)X-Shopify-Webhook-Id
slackペイロードの event.type(無ければ type)ペイロードの event_id
metaペイロードの object と entry[0].changes[0].field を連結したもの(field が無ければ object)ペイロードの内容(同じペイロードの再送信を重複とみなす)
zoomペイロードの eventペイロードの内容(同じペイロードの再送信を重複とみなす)
standardペイロードの typewebhook-id(または svix-id)
hmac・basic・api_key・noneconfig.event_type_field の項目config.id_header のヘッダー
  • イベントタイプを取得できない場合は config.event_type(既定 inbound)を使います。/ は . に、使用できない文字は _ に置き換え、100 文字までに切り詰めます。
  • 同じ配信 ID のリクエストには、24 時間は最初のメッセージの ID を返します。送信元サービスによる再送信は 1 通のメッセージにまとめ、受信ログでは duplicate になります。
  • JSON のボディは、その値をメッセージの data にします。フォームやテキストのボディは { "content_type": "…", "body": "<ボディの文字列>" } にします。
  • 受信したヘッダーは受信ログで確認できます。エンドポイントへの配信には、そのエンドポイントの署名シークレットで生成した署名を付けます。

受付時のレスポンス

受付時(重複・保留を含む)のレスポンスは、既定で 200 と { "id": "msg_…" }(保留の場合は { "status": "held", "request_id": "sreq_…" })です。レスポンスボディを読み取るサービス(Twilio の TwiML など)向けには、ソースごとに config.response でステータスコード・Content-Type・ボディを指定します。

"config": {
  "response": {
    "status": 200,
    "content_type": "application/xml",
    "body": "<Response></Response>"
  }
}
項目説明
status200〜299(既定 200)。204・205 はボディを空にして返します
content_type既定値は text/plain; charset=utf-8
body4KB まで(既定は空)

URL 確認リクエストへの応答と、拒否時のレスポンスは変わりません。

受信ボディの転送

エンドポイントのペイロード形式(body_format)が raw の場合、ソースで受信したメッセージは、受信したボディをバイト列のまま、受信時の Content-Type で配信します(Content-Type が無い場合は application/octet-stream)。JSON の空白やキーの順序、フォーム、UTF-8 以外の文字コードのボディも変わりません。Webhook Admin の署名(webhook-id・webhook-timestamp・webhook-signature)は、配信するバイト列から生成します。standard のエンドポイントには、従来どおり { type, timestamp, data } を配信します。

config.forward_headers に指定したヘッダーは、受信時の値のままエンドポイントへ引き渡します(20 個まで、小文字で指定)。raw のエンドポイントと組み合わせると、受信側で送信元サービスの署名(stripe-signature など)も検証できます。

"config": {
  "forward_headers": ["stripe-signature"]
}
  • Webhook Admin が付与するヘッダー(署名・Content-Type・User-Agent)と、トランスフォーメーションで追加したヘッダーが優先されます。
  • 認証・Cookie・ボディと接続に関わるヘッダーや、webhook- で始まるヘッダーなど、配信に使うヘッダーは指定できません(422)。
  • トランスフォーメーションには、従来どおり解析済みのペイロード(webhook.payload)を渡します。トランスフォーメーションでペイロードを変更した場合は変更後の JSON を、URL やヘッダーのみを変更した場合は受信したボディをそのまま配信します。
  • トランスフォーメーションに渡せるペイロードは 1MB までです。1MB を超えるペイロードの配信は、トランスフォーメーションを適用せずに失敗となり、再送信しません(配信試行の error は transformation: input_too_large: …)。トランスフォーメーションを解除または修正してから、再送信してください。
  • Webhook 以外のエンドポイントには、UTF-8 として読めるボディはその文字列を、読めないボディは data の JSON を配信します。ポーリングエンドポイントは、従来どおり data の JSON です。
  • 受信したボディがログ保存期間を過ぎて残っていない場合は、data の JSON を配信します。

一時停止

一時停止中のソースは、署名を検証したうえでリクエストを受け付けて保留し、送信元サービスには 200({ "status": "held", "request_id": "sreq_…" }。受付時のレスポンス を設定した場合はそのレスポンス)を返します。送信元サービスでは失敗として扱われません。そのため、失敗時に自動で再送信しないサービスや、失敗が続くとサブスクリプションを停止するサービスでも、一時停止中の Webhook を取りこぼしません。

  • 再開(status: active)すると、保留したリクエストを受信順にメッセージにして配信します。重複判定は受付時と同じです。
  • 再開後に届いたリクエストは直ちに処理するため、保留分の処理が終わるまでは、保留したリクエストと順序が前後することがあります。保留したリクエスト同士は受信順です。
  • 保留件数は、ソースの held と、管理画面のソースの一覧・詳細で確認できます。受信ログでは held と表示されます。
  • 保留したリクエストは、処理した時点で月間配信数に数えます。処理時に月間上限を超えていたリクエストは拒否となり、再処理 できます。
  • プランのログ保存期間を過ぎた保留分は削除されます。

受信は続けたままエンドポイントへの配信のみを停止する場合は、顧客アカウントのエンドポイントを一時停止します。保留したメッセージは再開時に配信します。

再処理

拒否したリクエストは、署名シークレットや設定を修正した後に再処理できます(拒否したリクエストの再処理・管理画面の受信ログの「再処理」・MCP の reprocess_source_request)。現在の署名シークレットと設定で再検証し、成功すれば受信 URL に届いた場合と同じ流れで処理します。

  • 署名の時刻は受信時刻で検証します。署名の時刻から 5 分以内に受信していれば、署名シークレットを後から登録しても検証に成功します。
  • 再処理できるのは、ボディが保存されている拒否済みのリクエスト(reprocessable: true)です。ボディが 10MB を超えて拒否したリクエストと GET のリクエストは対象外です(409)。
  • 受け付けたメッセージは月間配信数に数えます。一時停止中のソースでは保留になります。

月間配信数とログ

  • 受け付けた 1 通を、月間配信数の 1 通として数えます。重複・拒否したリクエスト・URL 確認リクエストと、エンドポイントが無く配信しないメッセージ(no_endpoint)は対象外です。テスト環境のソースは、テスト環境の 1 日の上限に数えます。
  • 受信したリクエストはソースごとの受信ログに記録され、プランのログ保存期間中は確認できます(ソースの受信ログ)。拒否したリクエストの記録は、ソースごとに 1 分あたり 60 件までです。
  • ソースから作成したメッセージは、メッセージの詳細の source に、ソースの ID・名前と受信ログの ID(request_id)が入ります。
  • プランのダウングレードでソース数が上限を超えた場合は、作成順で上限を超えた分のソースが 402 を返します。ソースを削除するか、プランを戻すと受付を再開します。

型

MessageRow    = { id, event_type, consumer: { id, external_id, name }, created_at,
                  status: 'success' | 'retrying' | 'failed' | 'pending' | 'cancelled' | 'no_endpoint',
                  attempts, endpoint_url }
MessageDetail = { id, event_type, consumer, created_at, idempotency_key, payload, deliveries: Delivery[],
                  source: { id, name, request_id } | null }
Delivery      = { id, endpoint_id, url, status: 'pending' | 'success' | 'retrying' | 'failed' | 'cancelled' | 'waiting',
                  attempt_count, next_attempt_at, attempts: AttemptRow[],
                  endpoint_status: 'active' | 'paused' | 'disabled' | null }
AttemptRow    = { id, at, response_status, response_head, duration_ms, error,
                  via: 'direct' | 'relay' | 'poll' | DestinationType, source_ip,
                  transform: 'changed' | 'error' | null, ref: string | null }
                /* error: null | 'timeout' | 'connect_failed' | 'dns_failed' | 'blocked_ip' | 'blocked_url: …'
                   | 'relay_failed' (fixed IP) | 'circuit_open' | 'wait_limit' | 'transformation: <kind>[: <detail>]'
                   | the destination's own reason (e.g. 'kafka: …') */
Consumer      = { id, external_id, name, created_at, endpoint_count }
Endpoint      = { id, consumer_id, url: string | null, description, event_types: string[] | null, fixed_ip,
                  status: 'active' | 'paused' | 'disabled', disabled_reason, failing_since, created_at,
                  retry: RetryPolicy, compat_signature: CompatSignature | null,
                  ordering: 'none' | 'fifo', transformation_updated_at: number | null,
                  type: 'http' | 'polling' | DestinationType, destination: object | null,
                  last_polled_at: number | null, body_format: 'standard' | 'raw' }
DestinationType = 'sqs' | 'eventbridge' | 'pubsub' | 's3' | 'r2' | 'gcs' | 'azure_blob'
                | 'servicebus' | 'kafka' | 'rabbitmq' | 'slack' | 'teams' | 'chatwork' | 'google_chat'
RetryPolicy   = { count: 0 | 1 | 2 | 3 | 5 | 7 | 12,
                  interval: 'progressive' | '1m' | '5m' | '30m' | '1h' | '6h' }
CompatSignature = { header, content: 'body' | 'timestamp_body', encoding: 'hex' | 'base64', prefix }
Recovery      = { id, endpoint_id, since, status: 'running' | 'done' | 'stopped',
                  total, queued, created_at, finished_at }
EventType     = { name, description, archived_at }
PollerToken   = { id, endpoint_id, name, prefix, created_at, last_used_at }
Transformation = { endpoint_id, code, updated_at, enabled: boolean,
                   variables: Record<string, string> | null }
PolledMessage = { id, event_type, timestamp, payload /* body_format: raw なら data */,
                  headers: { 'webhook-id', 'webhook-timestamp', 'webhook-signature' } }
Source        = { id, name, provider: SourceProvider, consumer_id, consumer: { id, external_id, name },
                  status: 'active' | 'paused', url, secret_hint: string | null, config: SourceConfig,
                  held, created_at, updated_at }
SourceProvider = 'stripe' | 'github' | 'shopify' | 'slack' | 'meta' | 'zoom' | 'standard'
               | 'hmac' | 'basic' | 'api_key' | 'none'
SourceConfig  = { event_type?, event_type_field?, id_header?, header?, query?, algorithm?: 'sha256',
                  encoding?: 'hex' | 'base64', prefix?, verify_token?, username?,
                  forward_headers?: string[], response?: { status, content_type, body } }
SourceRequest = { id, at, method: 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'GET',
                  status: 'accepted' | 'duplicate' | 'rejected' | 'held', response_status, reason,
                  message_id, event_type, content_type, size, headers: Record<string, string>,
                  processed_at: number | null, reprocessable: boolean }