ログイン

Webhook イベントリファレンス

Webhook で送信されるリクエストの仕様を説明します。送信先の設定方法は Webhook を参照してください。

リクエスト仕様

イベントは登録された URL へ HTTP POST で送信されます。

項目
HTTP メソッドPOST
Content-Typeapplication/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_versionStringペイロード仕様のバージョン。現在は v1
idStringイベントごとに一意な UUID
sourceStringイベントの発生元リソース(incident, runbook, incident_slack_channel, ping_request)
typeStringイベントの種類。イベント一覧 を参照
data_content_typeStringdata の形式。application/json 固定
dataObjectイベントごとのデータ。構造は イベント一覧 を参照

署名を検証する

受信したリクエストが Waroom から送信されたものであることを検証するために、X-Waroom-Signature ヘッダーの検証を推奨します。

署名は、送信先の追加時に発行されたシークレットトークンを鍵として、以下の文字列を HMAC-SHA256 でハッシュ化したものです。

v1:{X-Waroom-Timestamp の値}:{リクエストボディ}

検証は次の手順で行います。

  1. X-Waroom-Timestamp ヘッダーの値とリクエストボディ(加工していない生の文字列)を v1:{timestamp}:{body} の形式で連結する
  2. シークレットトークンを鍵として HMAC-SHA256 の 16 進数文字列を計算する
  3. 先頭に 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 の構造:

フィールド説明
uuidStringインシデントの UUID
titleStringインシデントのタイトル
statusStringステータス(detected, investigating, fixing, resolved, close)
severityString重要度(critical, high, low, info, unknown)
service.nameStringサービス名
commanderObject / nullインシデントコマンダー。未設定の場合は null
commander.nicknameStringインシデントコマンダーのニックネーム
created_atString作成日時(ISO 8601、日本時間)
updated_atString更新日時(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 の構造:

フィールド説明
nameStringSlack チャネル名
keyStringSlack チャネルの ID
is_privateBooleanプライベートチャネルかどうか
incidentObject関連するインシデント。構造は com.waroom.incident.incident.createddata と同じ

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_typeStringステップの種類(generic, overview, dashboard, precheck, resolution)
statusStringステップの状態(done, skipped)
positionNumberランブック内でのステップの位置
incidentObject関連するインシデント。構造は com.waroom.incident.incident.createddata と同じ

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 を使って重複を検知できます
  • 順序に依存しない: リトライにより、イベントが発生順と異なる順序で届くことがあります