Webhook イベントリファレンス
Webhook で送信されるリクエストの仕様を説明します。送信先の設定方法は Webhook を参照してください。
リクエスト仕様
イベントは登録された URL へ HTTP POST で送信されます。
| 項目 | 値 |
|---|---|
| HTTP メソッド | POST |
Content-Type | application/json |
X-Waroom-Timestamp | リクエスト送信時刻(UNIX タイムスタンプ、秒) |
X-Waroom-Signature | リクエストボディの署名(v1= + HMAC-SHA256 の 16 進数文字列) |
ペイロードの共通構造
リクエストボディはすべてのイベントで共通の構造を持ちます。
{
"spec_version": "v1",
"id": "019eb5c7-aff9-778b-bc81-884d00d3e961",
"source": "incident",
"type": "com.waroom.incident.incident.created",
"data_content_type": "application/json",
"data": { ... }
}
| フィールド | 型 | 説明 |
|---|---|---|
spec_version | String | ペイロード仕様のバージョン。現在は v1 |
id | String | イベントごとに一意な UUID |
source | String | イベントの発生元リソース(incident, runbook, incident_slack_channel, ping_request) |
type | String | イベントの種類。イベント一覧 を参照 |
data_content_type | String | data の形式。application/json 固定 |
data | Object | イベントごとのデータ。構造は イベント一覧 を参照 |
署名を検証する
受信したリクエストが Waroom から送信されたものであることを検証するために、X-Waroom-Signature ヘッダーの検証を推奨します。
署名は、送信先の追加時に発行されたシークレットトークンを鍵として、以下の文字列を HMAC-SHA256 でハッシュ化したものです。
v1:{X-Waroom-Timestamp の値}:{リクエストボディ}
検証は次の手順で行います。
X-Waroom-Timestampヘッダーの値とリクエストボディ(加工していない生の文字列)をv1:{timestamp}:{body}の形式で連結する- シークレットトークンを鍵として HMAC-SHA256 の 16 進数文字列を計算する
- 先頭に
v1=を付けた文字列がX-Waroom-Signatureヘッダーの値と一致することを確認する
Ruby での検証例:
require 'openssl'
require 'rack/utils'
def verify_signature(secret_token, timestamp, signature, body)
expected = 'v1=' + OpenSSL::HMAC.hexdigest('SHA256', secret_token, "v1:#{timestamp}:#{body}")
Rack::Utils.secure_compare(expected, signature)
end
タイミング攻撃を避けるため、署名の比較には通常の文字列比較ではなく定数時間比較(Ruby の Rack::Utils.secure_compare など)を使用してください。
イベント一覧
com.waroom.incident.incident.created
インシデントが作成されたときに送信されます。非公開インシデントの場合は送信されません。
{
"spec_version": "v1",
"id": "019eb5c7-aff9-778b-bc81-884d00d3e961",
"source": "incident",
"type": "com.waroom.incident.incident.created",
"data_content_type": "application/json",
"data": {
"uuid": "b083335c-f608-40a2-8571-99d78cf305ee",
"title": "決済 API のレイテンシ悪化",
"status": "detected",
"severity": "high",
"service": {
"name": "Payment"
},
"commander": {
"nickname": "alice"
},
"created_at": "2026-06-11T17:23:42+09:00",
"updated_at": "2026-06-11T17:23:42+09:00"
}
}
data の構造:
| フィールド | 型 | 説明 |
|---|---|---|
uuid | String | インシデントの UUID |
title | String | インシデントのタイトル |
status | String | ステータス(detected, investigating, fixing, resolved, close) |
severity | String | 重要度(critical, high, low, info, unknown) |
service.name | String | サービス名 |
commander | Object / null | インシデントコマンダー。未設定の場合は null |
commander.nickname | String | インシデントコマンダーのニックネーム |
created_at | String | 作成日時(ISO 8601、日本時間) |
updated_at | String | 更新日時(ISO 8601、日本時間) |
com.waroom.incident.incident.updated
インシデントのステータス・重要度・インシデントコマンダーのいずれかが変更されたときに送信されます。それ以外のフィールド(タイトルなど)の変更では送信されません。
data の構造は com.waroom.incident.incident.created と同じです。
com.waroom.incident.slack_channel.created
インシデント対応用の Slack チャネルが作成されたときに送信されます。
{
"spec_version": "v1",
"id": "019eb5c7-b0a1-7c2d-9e3f-1a2b3c4d5e6f",
"source": "incident_slack_channel",
"type": "com.waroom.incident.slack_channel.created",
"data_content_type": "application/json",
"data": {
"name": "incident-20260611-payment",
"key": "C0123456789",
"is_private": false,
"incident": {
"uuid": "b083335c-f608-40a2-8571-99d78cf305ee",
"title": "決済 API のレイテンシ悪化",
"status": "detected",
"severity": "high",
"service": {
"name": "Payment"
},
"commander": null,
"created_at": "2026-06-11T17:23:42+09:00",
"updated_at": "2026-06-11T17:23:42+09:00"
}
}
}
data の構造:
| フィールド | 型 | 説明 |
|---|---|---|
name | String | Slack チャネル名 |
key | String | Slack チャネルの ID |
is_private | Boolean | プライベートチャネルかどうか |
incident | Object | 関連するインシデント。構造は com.waroom.incident.incident.created の data と同じ |
com.waroom.runbook.runbook.executed / com.waroom.runbook.runbook.skipped
インシデントに紐づくランブックのステップが完了になったとき(executed)、またはスキップされたとき(skipped)に送信されます。
{
"spec_version": "v1",
"id": "019eb5c7-c1b2-7d3e-8f4a-2b3c4d5e6f7a",
"source": "runbook",
"type": "com.waroom.runbook.runbook.executed",
"data_content_type": "application/json",
"data": {
"part_type": "precheck",
"status": "done",
"position": 1,
"incident": {
"uuid": "b083335c-f608-40a2-8571-99d78cf305ee",
"title": "決済 API のレイテンシ悪化",
"status": "investigating",
"severity": "high",
"service": {
"name": "Payment"
},
"commander": null,
"created_at": "2026-06-11T17:23:42+09:00",
"updated_at": "2026-06-11T17:25:10+09:00"
}
}
}
data の構造:
| フィールド | 型 | 説明 |
|---|---|---|
part_type | String | ステップの種類(generic, overview, dashboard, precheck, resolution) |
status | String | ステップの状態(done, skipped) |
position | Number | ランブック内でのステップの位置 |
incident | Object | 関連するインシデント。構造は com.waroom.incident.incident.created の data と同じ |
com.waroom.test.webhook.sent
テスト配信を実行したときに送信されます。data は空のオブジェクトです。
{
"spec_version": "v1",
"id": "019eb9ec-63fa-7027-8f2a-e4d40c7319c7",
"source": "ping_request",
"type": "com.waroom.test.webhook.sent",
"data_content_type": "application/json",
"data": {}
}
リトライと再送
配信は以下の場合に失敗と判定されます。
- 受信エンドポイントが 2xx 以外のステータスコードを返した
- 3 秒以内にレスポンスが返らなかった(タイムアウト)
失敗した配信は、間隔をあけて自動でリトライされます。リトライを含めて最大 4 回試行し、すべて失敗した場合はその配信は「失敗」となります。
「失敗」となった配信は、配信履歴から手動で再送できます。
[配信履歴から失敗した配信を再送しているスクリーンショット]
受信側実装の注意点
- レスポンスは即座に返す: 受信後の処理に時間がかかると、タイムアウト(3 秒)により失敗と判定され、同じイベントがリトライで再送されます。重い処理はレスポンスを返した後に非同期で行ってください
- 重複受信に備える: リトライや再送により、同じイベントが複数回届くことがあります。ペイロードの
idはイベントごとに一意なので、idを使って重複を検知できます - 順序に依存しない: リトライにより、イベントが発生順と異なる順序で届くことがあります