概要
Webhook は Qoder Cloud Agents が提供するイベント駆動型のプッシュ機構です。Agent や Session などのリソースにライフサイクルの変化が生じると、システムは構造化されたイベントを HTTP POST で開発者が登録した URL に配信します。ポーリングは不要です。 主な特徴:- イベント駆動型プッシュ — リソースの状態変化時に能動的に通知し、クライアント側のポーリングは不要
- envelope 構造 — 統一された
BetaWebhookEvent { id, created_at, data, type:"event" }フォーマット - 配信セマンティクス — 少なくとも 1 回(at-least-once)の保証、HMAC-SHA256 署名検証、指数バックオフによるリトライ
- ワイルドカード購読 —
*を使用してすべてのイベントタイプを購読でき、連携を簡素化
| シナリオ | 説明 |
|---|---|
| 非同期タスク完了通知 | Session の完了時に下流のワークフローをトリガーする |
| Agent 設定の監査 | Agent の作成/更新/削除操作を追跡する |
| マルチ Agent オーケストレーション | Thread の状態変化に応じてサブタスクのスケジューリングを駆動する |
| 運用監視とアラート | 連続失敗回数がしきい値を超えたときにアラートを発する |
ドメインタイプ
このセクションでは Webhook イベントのデータ構造を定義します。各イベントタイプのdata フィールドは、リソース ID、イベントタイプ、およびイベント固有の追加フィールドを含む統一されたオブジェクト形式に従います。
Session ライフサイクルイベント
Webhook Session Created Event Data
-
WebhookSessionCreatedEventData object { id, type }-
id: stringイベントをトリガーした Session ID。 -
type: "session.created""session.created"
POST /sessionsにより Session が作成された直後にこのイベントを送信します。
-
Webhook Session Updated Event Data
-
WebhookSessionUpdatedEventData object { id, type }-
id: stringイベントをトリガーした Session ID。 -
type: "session.updated""session.updated"
-
Webhook Session Archived Event Data
-
WebhookSessionArchivedEventData object { id, type }-
id: stringイベントをトリガーした Session ID。 -
type: "session.archived""session.archived"
-
Webhook Session Deleted Event Data
-
WebhookSessionDeletedEventData object { id, type }-
id: stringイベントをトリガーした Session ID。 -
type: "session.deleted""session.deleted"
-
Session ステータスイベント
Webhook Session Status Run Started Event Data
-
WebhookSessionStatusRunStartedEventData object { id, type }-
id: stringイベントをトリガーした Session ID。 -
type: "session.status_run_started""session.status_run_started"
-
Webhook Session Status Idled Event Data
-
WebhookSessionStatusIdledEventData object { id, type }-
id: stringイベントをトリガーした Session ID。 -
type: "session.status_idled""session.status_idled"
-
Session Thread イベント
マルチ Agent 協調シナリオに適用されます。Thread イベントは基本フィールドに加えてsession_thread_id フィールドを持ち、特定の実行スレッドを識別します。
Webhook Session Thread Created Event Data
-
WebhookSessionThreadCreatedEventData object { id, type, session_thread_id }-
id: stringイベントをトリガーした Session ID。 -
type: "session.thread_created""session.thread_created"
-
session_thread_id: string関連付けられた Session Thread ID。
-
Webhook Session Thread Idled Event Data
-
WebhookSessionThreadIdledEventData object { id, type, session_thread_id }-
id: stringイベントをトリガーした Session ID。 -
type: "session.thread_idled""session.thread_idled"
-
session_thread_id: string関連付けられた Session Thread ID。
-
Webhook Session Thread Terminated Event Data
-
WebhookSessionThreadTerminatedEventData object { id, type, session_thread_id }-
id: stringイベントをトリガーした Session ID。 -
type: "session.thread_terminated""session.thread_terminated"
-
session_thread_id: string関連付けられた Session Thread ID。
-
Agent ライフサイクルイベント
Agent イベントは基本フィールドに加えてversion フィールドを持ち、Agent の設定バージョン番号を示します。
Webhook Agent Created Event Data
-
WebhookAgentCreatedEventData object { id, type, version }-
id: stringイベントをトリガーした Agent ID。 -
type: "agent.created""agent.created"
POST /agentsにより Agent が作成された後にこのイベントを送信します。 -
version: integerAgent のバージョン番号。初回作成時は1に設定されます。
-
Webhook Agent Updated Event Data
-
WebhookAgentUpdatedEventData object { id, type, version }-
id: stringイベントをトリガーした Agent ID。 -
type: "agent.updated""agent.updated"
versionは更新のたびにインクリメントされます。 -
version: integerAgent のバージョン番号。
-
Webhook Agent Archived Event Data
-
WebhookAgentArchivedEventData object { id, type, version }-
id: stringイベントをトリガーした Agent ID。 -
type: "agent.archived""agent.archived"
-
version: integerAgent のバージョン番号。
-
Webhook Agent Deleted Event Data
-
WebhookAgentDeletedEventData object { id, type, version }-
id: stringイベントをトリガーした Agent ID。 -
type: "agent.deleted""agent.deleted"
-
version: integerAgent のバージョン番号。
-
Webhook エンドポイント API
Webhook エンドポイントを管理するための CRUD エンドポイントです。これらを使用して、Webhook エンドポイントの作成、照会、更新、削除を行うほか、テストイベントの送信やエンドポイントの有効化/無効化の制御を行います。 Base URL:| リージョン | アドレス |
|---|---|
| Global | https://api.qoder.com/api/v1/cloud |
| CN | https://api.qoder.com.cn/api/v1/cloud |
POST /webhook_endpoints
新しい Webhook エンドポイントを作成します。 リクエストパラメータ:| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
url | string | はい | イベント配信を受信する HTTP または HTTPS URL(本番環境では HTTPS を強く推奨) |
description | string | いいえ | 管理目的のエンドポイント説明 |
events | string[] | はい | 購読するイベントタイプのリスト。* ワイルドカードに対応 |
201 Created
Note: signing_secret は作成時に一度だけ返されます。安全に保管してください。以降の照会系エンドポイントではこのフィールドは返されません。
ステータスコード:
| コード | 説明 |
|---|---|
| 201 | 作成成功 |
| 400 | 無効なリクエストパラメータ(URL の形式不正、無効なイベントタイプなど) |
| 401 | 認証エラー、無効または期限切れのトークン |
| 422 | セマンティックエラー(URL の重複登録など) |
GET /webhook_endpoints
現在のアカウント配下のすべての Webhook エンドポイントを一覧表示します。 リクエストパラメータ: なし レスポンス:200 OK
| フィールド | 型 | 説明 |
|---|---|---|
id | string | エンドポイントの一意識別子 |
url | string | イベントを受信する URL |
description | string | エンドポイントの説明 |
events | string[] | 購読中のイベントタイプ |
active | boolean | 有効かどうか |
signing_secret_version | integer | 署名シークレットのバージョン番号 |
consecutive_fail | integer | 連続配信失敗回数 |
last_success_at | string | 最後に配信が成功した時刻(RFC 3339) |
last_failure_at | string | 最後に配信が失敗した時刻(RFC 3339)。失敗記録がない場合は null |
created_at | string | 作成時刻(RFC 3339) |
updated_at | string | 最終更新時刻(RFC 3339) |
GET /webhook_endpoints/{id}
特定の Webhook エンドポイントの詳細を取得します。 パスパラメータ:| パラメータ | 型 | 説明 |
|---|---|---|
id | string | Webhook エンドポイント ID |
200 OK
一覧エンドポイントの要素と同じ構造の単一のエンドポイントオブジェクトを返します。
ステータスコード:
| コード | 説明 |
|---|---|
| 200 | 成功 |
| 404 | エンドポイントが見つからない |
PUT /webhook_endpoints/{id}
特定の Webhook エンドポイントの設定を更新します。 パスパラメータ:| パラメータ | 型 | 説明 |
|---|---|---|
id | string | Webhook エンドポイント ID |
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
url | string | いいえ | イベント配信 URL を更新する |
description | string | いいえ | エンドポイント説明を更新する |
events | string[] | いいえ | 購読するイベントタイプを更新する |
200 OK
更新後の完全なエンドポイントオブジェクトを返します。
ステータスコード:
| コード | 説明 |
|---|---|
| 200 | 更新成功 |
| 400 | 無効なリクエストパラメータ |
| 404 | エンドポイントが見つからない |
DELETE /webhook_endpoints/{id}
Webhook エンドポイントを永久に削除します。未配信のイベントはすべて破棄されます。 パスパラメータ:| パラメータ | 型 | 説明 |
|---|---|---|
id | string | Webhook エンドポイント ID |
204 No Content
ステータスコード:
| コード | 説明 |
|---|---|
| 204 | 削除成功 |
| 404 | エンドポイントが見つからない |
POST /webhook_endpoints/{id}/test
指定したエンドポイントにテストイベントを送信し、接続性と署名検証ロジックを確認します。 パスパラメータ:| パラメータ | 型 | 説明 |
|---|---|---|
id | string | Webhook エンドポイント ID |
202 Accepted
| フィールド | 型 | 説明 |
|---|---|---|
event_id | integer | テストイベントの内部 ID |
delivery_rows | integer | イベントが公開されたメッセージパーティション数 |
| コード | 説明 |
|---|---|
| 202 | テストイベント送信済み |
| 404 | エンドポイントが見つからない |
POST /webhook_endpoints/{id}/enable
無効化された Webhook エンドポイントを有効化します。有効化されると、エンドポイントはイベント配信の受信を再開します。 パスパラメータ:| パラメータ | 型 | 説明 |
|---|---|---|
id | string | Webhook エンドポイント ID |
200 OK
有効化後のエンドポイントオブジェクト(active: true)を返します。
ステータスコード:
| コード | 説明 |
|---|---|
| 200 | 有効化成功 |
| 404 | エンドポイントが見つからない |
POST /webhook_endpoints/{id}/disable
Webhook エンドポイントを無効化します。無効化されると、エンドポイントはイベント配信の受信を停止しますが、削除はされません。 パスパラメータ:| パラメータ | 型 | 説明 |
|---|---|---|
id | string | Webhook エンドポイント ID |
200 OK
無効化後のエンドポイントオブジェクト(active: false)を返します。
ステータスコード:
| コード | 説明 |
|---|---|
| 200 | 無効化成功 |
| 404 | エンドポイントが見つからない |
GET /webhook_events
監査やトラブルシューティングのために Webhook イベント配信レコードを一覧表示します。 リクエストパラメータ: なし レスポンス:200 OK
配信ステータス、タイムスタンプなどの情報を含むイベント一覧を返します。
例:
GET /webhook_events/{id}
単一の Webhook イベントの詳細情報を取得します。 パスパラメータ:| パラメータ | 型 | 説明 |
|---|---|---|
id | string | Webhook イベント ID |
200 OK
ステータスコード:
| コード | 説明 |
|---|---|
| 200 | 成功 |
| 404 | イベントが見つからない |
エラーレスポンス形式
すべてのエンドポイントは、エラー発生時に統一されたエラー構造を返します:| フィールド | 型 | 説明 |
|---|---|---|
error.message | string | 人間が読めるエラー説明 |
error.type | string | エラーカテゴリ(例: invalid_request_error、not_found_error) |
request_id | string | サポートチームでのトラブルシューティング用のリクエストトレース ID |
type | string | 固定値 "error" |
注意: 認証層(Token が無効または欠落している場合など)が返す 401 レスポンスは、ゲートウェイから直接返されるため、上記の業務エラー構造に従わない場合があります。
Webhook 配信
配信方法
システムは、以下の形式で HTTP POST により登録済み URL にイベントを配信します:- Method:
POST - Content-Type:
application/json - Body: JSON envelope 構造(envelope 構造を参照)
リクエストヘッダー
各配信には以下の HTTP ヘッダーが含まれます:| ヘッダー | 説明 |
|---|---|
Content-Type | application/json |
User-Agent | QoderCloudAgents-Webhook/1.0 |
Webhook-Signature | t=<unix_epoch>,v1=<hmac_sha256_hex> 形式の HMAC-SHA256 署名 |
署名検証
イベントの真正性とデータの完全性を確保するため、各配信には HMAC-SHA256 署名が付与されます。開発者はイベントを処理する前に署名を検証する必要があります。 署名形式:signing_secret— エンドポイント作成時に返されるシークレット(whsec_プレフィックス)t— 署名時の Unix タイムスタンプ(秒)raw_body— リクエストボディの生のバイト内容(パース前)
Webhook-Signatureヘッダーからtとv1を抽出する- リプレイ攻撃を防ぐため、タイムスタンプが許容ウィンドウ内(推奨 600 秒)であることを確認する
signing_secretを使用して"<t>.<raw_body>"の HMAC-SHA256 を計算する- 結果を
v1とタイミングセーフな比較で照合する
署名検証のコード例
Node.js:リトライ戦略
配信が失敗した場合、システムは指数バックオフでリトライを行います:| 試行 | 遅延 | 説明 |
|---|---|---|
| 1 回目 | 即時 | 初回配信 |
| 2 回目 | 1 秒 | 1 回目のリトライ |
| 3 回目 | 5 秒 | 2 回目のリトライ |
| 4 回目 | 30 秒 | 最後のリトライ |
レスポンスコードの処理
| レスポンスコード範囲 | 処理 |
|---|---|
| 2xx | 配信成功、イベントは配信済みとしてマークされる |
| 4xx | リトライなし、イベントは破棄済みとしてマークされる(クライアントエラーは開発者が修正すべき) |
| 5xx | リトライをトリガーする(一時的なサーバー障害) |
| Timeout | リトライをトリガーする(デフォルトのタイムアウトは 30 秒) |
自動デグレード
エンドポイントのconsecutive_fail カウントが 20 を超えると、システムはデグレード警告をトリガーします。開発者はこのメトリクスを監視し、失敗が継続する場合は以下を確認してください:
- エンドポイント URL が到達可能か
- SSL 証明書が有効か
- サーバーが正常に応答しているか
- 署名検証ロジックにバグがないか
サポート対象のイベントタイプ(完全な一覧)
イベントタイプ概要
| イベントタイプ | ステータス | 追加 data フィールド | トリガー条件 |
|---|---|---|---|
session.created | ✅ 実装済み | — | POST /sessions が Session を正常に作成 |
session.updated | ✅ 実装済み | — | Session メタデータが変更された |
session.archived | ✅ 実装済み | — | Session がアーカイブされた |
session.deleted | ✅ 実装済み | — | Session が永久に削除された |
session.status_run_started | ✅ 実装済み | — | Agent が実行を開始 |
session.status_idled | ✅ 実装済み | — | ターン完了、アイドルに復帰 |
session.thread_created | ✅ 実装済み | session_thread_id | 新しい Session Thread が作成された |
session.thread_idled | ✅ 実装済み | session_thread_id | Thread の実行が終了、アイドルに移行 |
session.thread_terminated | ✅ 実装済み | session_thread_id | Thread が終了された |
agent.created | ✅ 実装済み | version | POST /agents が Agent を作成 |
agent.updated | ✅ 実装済み | version | Agent 設定が更新された |
agent.archived | ✅ 実装済み | version | Agent がアーカイブされた |
agent.deleted | ✅ 実装済み | version | Agent が削除された |
session.pending | 🔜 許可リスト登録済み | — | Session がスケジューリング待ち |
session.running | 🔜 許可リスト登録済み | — | Session が実行中 |
session.idled | 🔜 許可リスト登録済み | — | Session がアイドルに移行 |
session.requires_action | 🔜 許可リスト登録済み | — | Session が人的介入を必要とする |
session.status_run_failed | 🔜 許可リスト登録済み | — | 実行が失敗した |
session.status_terminated | 🔜 許可リスト登録済み | — | Session が終了された |
session.status_rescheduled | 🔜 許可リスト登録済み | — | Session が再スケジュールされた |
session.status_paused_pending_input | 🔜 許可リスト登録済み | — | ユーザー入力待ちで一時停止 |
session.status_paused_pending_approval | 🔜 許可リスト登録済み | — | 承認待ちで一時停止 |
session.status_paused_user_intervention | 🔜 許可リスト登録済み | — | 人的介入待ちで一時停止 |
session.outcome_evaluation_started | 🔜 許可リスト登録済み | — | 成果評価が開始された |
session.outcome_evaluation_ended | 🔜 許可リスト登録済み | — | 成果評価が終了した |
vault.created | 🔜 許可リスト登録済み | — | Vault が作成された |
vault.deleted | 🔜 許可リスト登録済み | — | Vault が削除された |
vault.updated | 🔜 許可リスト登録済み | — | Vault が更新された |
vault_credential.created | 🔜 許可リスト登録済み | — | 認証情報が作成された |
vault_credential.updated | 🔜 許可リスト登録済み | — | 認証情報が更新された |
vault_credential.deleted | 🔜 許可リスト登録済み | — | 認証情報が削除された |
vault_credential.shared | 🔜 許可リスト登録済み | — | 認証情報が共有された |
vault_credential.revoked | 🔜 許可リスト登録済み | — | 認証情報が取り消された |
deployment.created | 📋 計画中 | — | Deployment が作成された |
deployment.updated | 📋 計画中 | — | Deployment が更新された |
deployment.archived | 📋 計画中 | — | Deployment がアーカイブされた |
deployment.deleted | 📋 計画中 | — | Deployment が削除された |
deployment.paused | 📋 計画中 | — | Deployment が一時停止された |
deployment.unpaused | 📋 計画中 | — | Deployment が再開された |
deployment_run.started | 📋 計画中 | — | Deployment 実行が開始された |
deployment_run.failed | 📋 計画中 | — | Deployment 実行が失敗した |
deployment_run.succeeded | 📋 計画中 | — | Deployment 実行が成功した |
environment.created | 📋 計画中 | — | Environment が作成された |
environment.updated | 📋 計画中 | — | Environment が更新された |
environment.archived | 📋 計画中 | — | Environment がアーカイブされた |
environment.deleted | 📋 計画中 | — | Environment が削除された |
memory_store.created | 📋 計画中 | — | Memory store が作成された |
memory_store.archived | 📋 計画中 | — | Memory store がアーカイブされた |
memory_store.deleted | 📋 計画中 | — | Memory store が削除された |
特殊なイベントタイプ
| イベントタイプ | 説明 |
|---|---|
* | ワイルドカード — すべてのイベントタイプを購読します。すべてのイベントを受信するには、エンドポイント作成時に ["*"] を使用します |
webhook.test | 内部テストイベント。POST /webhook_endpoints/{id}/test を介してトリガーされます |
ステータスラベル
| ラベル | 意味 |
|---|---|
| ✅ 実装済み | システム内に完全なイベントトリガーポイントが存在し、正常に購読・受信できる |
| 🔜 許可リスト登録済み | イベントタイプが検証用の許可リストに登録済み(events フィールドで使用可能)だが、トリガーポイントはまだ存在しない |
| 📋 計画中 | API 設計レベルで定義されているが、まだ許可リストに登録されていないイベントタイプ |
envelope 構造
すべての Webhook イベントは、統一された envelope 構造にラップされて配信されます。基本 envelope 構造
Thread イベントの envelope
Thread イベントはdata 内に追加の session_thread_id フィールドを含みます:
Agent イベントの envelope
Agent イベントはdata 内に追加の version フィールドを含みます:
フィールドの説明
| フィールド | 型 | 説明 |
|---|---|---|
id | string | イベントの一意識別子。形式: whevt_ + 一意識別子。イベントの冪等性キーから決定的に生成される |
created_at | string | イベント作成時刻、RFC 3339 UTC 形式 |
type | string | 固定値 "event"、これがイベント envelope であることを示す |
data | object | トリガーとなったリソース情報を含むイベントペイロード |
data.id | string | イベントをトリガーしたリソースの ID(Session ID または Agent ID) |
data.type | string | イベントタイプ文字列(例: "session.created"、"agent.updated") |
data.session_thread_id | string | (Thread イベントのみ)関連付けられた Session Thread ID |
data.version | integer | (Agent イベントのみ)Agent の設定バージョン番号 |
冪等性の処理
envelope 内のid フィールドは重複排除キーとして使用できます。配信セマンティクスは少なくとも 1 回(at-least-once)であるため、同じイベントが複数回配信される可能性があります。受信側は以下を行うべきです:
idを重複排除の一意キーとして使用する- 処理前に
idがすでに消費済みかどうかを確認する - イベント処理ロジックが冪等であることを保証する
計画中のイベント(近日提供予定)
以下のイベントタイプは API 設計レベルで整合済みで、それぞれのリソース機能の提供開始に合わせてロールアウトされます。具体的な時期は製品要件によって異なります。deployment.*(Deployment ライフサイクル、6 イベント)
| イベントタイプ | トリガー条件 |
|---|---|
deployment.created | 新しい Deployment が作成された |
deployment.updated | Deployment 設定が更新された |
deployment.archived | Deployment がアーカイブされた |
deployment.deleted | Deployment が削除された |
deployment.paused | Deployment が一時停止された(新しい実行のトリガーを停止) |
deployment.unpaused | Deployment が再開された(実行のトリガーを再開) |
deployment_run.*(Deployment 実行ステータス、3 イベント)
| イベントタイプ | トリガー条件 |
|---|---|
deployment_run.started | Deployment 実行が実行を開始する |
deployment_run.failed | Deployment 実行が失敗した |
deployment_run.succeeded | Deployment 実行が正常に完了した |
environment.*(Environment 管理、4 イベント)
| イベントタイプ | トリガー条件 |
|---|---|
environment.created | ランタイム Environment が作成された |
environment.updated | Environment 設定が更新された |
environment.archived | Environment がアーカイブされた |
environment.deleted | Environment が削除された |
memory_store.*(Memory Store、3 イベント)
| イベントタイプ | トリガー条件 |
|---|---|
memory_store.created | Memory Store インスタンスが作成された |
memory_store.archived | Memory Store がアーカイブされた |
memory_store.deleted | Memory Store が削除された |
vault.*(Vault、3 イベント)
| イベントタイプ | トリガー条件 |
|---|---|
vault.created | Vault が作成された |
vault.updated | Vault 設定が更新された |
vault.deleted | Vault が削除された |
vault_credential.*(認証情報管理、5 イベント)
| イベントタイプ | トリガー条件 |
|---|---|
vault_credential.created | Vault に新しい認証情報が追加された |
vault_credential.updated | 認証情報が更新された |
vault_credential.deleted | 認証情報が削除された |
vault_credential.shared | 認証情報が他の Agent と共有された |
vault_credential.revoked | 認証情報の共有権限が取り消された |
付録 A: クイックスタートガイド
ステップ 1: Webhook エンドポイントを作成する
ステップ 2: signing_secret を保存する
作成レスポンスからsigning_secret を取得し、後の署名検証のために安全に保管します。
ステップ 3: 受信側を実装する
サービス内に Webhook 受信エンドポイントを実装し、以下を確実に行ってください:Webhook-Signature署名を検証する- イベントの
idを使用して冪等な重複排除を行う - 受信を確認するために
200 OKを返す - ビジネスロジックを非同期に処理する(タイムアウトを回避する)
ステップ 4: テストイベントを送信する
ステップ 5: 検証して本番稼働する
テストイベントが正しく受信されることを確認したら、本番運用の準備が整います。付録 B: ベストプラクティス
| プラクティス | 説明 |
|---|---|
| 署名検証 | 常に Webhook-Signature を検証し、無効なリクエストを拒否する |
| 冪等処理 | イベントの id を使用して重複排除を行い、重複消費を防ぐ |
| 高速応答 | 受信側は 5 秒以内に 2xx を返し、時間のかかるロジックは非同期に実行する |
| タイムスタンプ検証 | 許容ウィンドウ外のイベントを拒否し、リプレイ攻撃を防ぐ |
| 正確な購読 | 必要なイベントタイプのみを購読し、不要なネットワークオーバーヘッドを削減する |
| 監視とアラート | consecutive_fail メトリクスを監視し、配信の異常を速やかに検知する |