Webhookをサブスクライブする
ポーリングせずに、主要なイベントが発生したときに通知を受け取ります。
セッションは長時間実行されるインタラクションです。ほとんどのリアルタイムのインタラクションはSSEイベントストリームを通じて行われますが、「webhook」(Webhook)は主要な状態変化を通知します。
Webhookイベントは、完全なオブジェクトではなく、イベントの type と id を返します。Webhookイベントを受信したら、GET 呼び出しでオブジェクトを直接取得する必要があります。これにより、リトライ時に古いデータが配信されることを防ぎ、すべての配信を小さく保ちます。
サポートされているイベントタイプ
これらのイベントの一部は、セッションのイベントストリーム上の対応するイベントとは異なる名前が付けられています。たとえば、ストリームの session.status_idle と session.status_running は、Webhookイベントの session.status_idled と session.status_run_started に対応します。
| イベント | トリガー |
|---|---|
session.status_run_started | エージェントの実行が開始されました。これはセッションのステータスが running に遷移するたびにトリガーされます。 |
session.status_idled | エージェントが入力を待機しています。たとえば、ツール権限の承認や新しいユーザーメッセージなどです。 |
session.budget_reached | セッションが予算に達し、一時停止しました。設定した予算値ごとに最大1回発火します。予算を変更すると再び有効になります。 |
session.status_rescheduled | 一時的なエラーが発生し、セッションが自動的にリトライしています。 |
session.status_terminated | 回復不能なエラーのため、またはアーカイブされたために、セッションが終了しました。 |
session.thread_created | 新しいマルチエージェントスレッドが開かれました。コーディネーターによって呼び出された追加のエージェントが作業を開始しているか、セッションのアドバイザーに相談が行われています。 |
session.thread_idled | マルチエージェントインタラクション内のエージェントが入力を待機しています。 |
session.thread_terminated | マルチエージェントスレッドが終了しました。スレッドがアーカイブされたか、リトライを使い果たしたためです。コーディネーターが生成した子スレッドが作業を完了した場合は terminated ではなく idle になります(アドバイザースレッドは相談が完了すると終了します)。子スレッドに対してのみ発火します。セッション全体のアーカイブを含むプライマリスレッドの終了は、session.status_terminated としてのみ通知されます。 |
session.outcome_evaluation_ended | 単一のイテレーションに対する成果評価が完了しました。 |
session.updated | セッションのプロパティが変更されました(たとえば、名前や設定が更新されました)。 |
session.deleted | セッションが完全に削除されました。取得できるオブジェクトは残っていないため、イベント自体を最終的なものとして扱ってください。 |
エンドポイントを登録する
Claude Consoleの Manage > Webhooks にアクセスしてください。
Webhookエンドポイントは以下で構成されます。
- URL: 公開解決可能なホスト名を持つ、ポート443のHTTPSである必要があります。
- イベントタイプ: このエンドポイントが受信する
data.type値のリスト。エンドポイントはサブスクライブしているイベントのみを受信します。 - 署名シークレット: 作成時に生成される、
whsec_プレフィックス付きの32バイトのシークレット。一度しか表示されないため、Webhook配信を検証するために安全に保管してください。
署名を検証する
すべての配信には webhook-id、webhook-timestamp、webhook-signature ヘッダーが含まれます。SDKの unwrap() ヘルパーを使用すると、署名の検証とイベントの解析を1ステップで行えます。署名が無効な場合、またはペイロードが5分以上古い場合は例外をスローします。
ANTHROPIC_WEBHOOK_SIGNING_KEY に、エンドポイント作成時に表示された whsec_ プレフィックス付きのシークレットを設定してください。
from flask import Flask, request
import anthropic
client = anthropic.Anthropic() # reads ANTHROPIC_WEBHOOK_SIGNING_KEY from env
app = Flask(__name__)
@app.route("/webhook", methods=["POST"])
def webhook():
try:
# unwrap() は署名が無効またはペイロードが古い場合に例外を送出します
event = client.beta.webhooks.unwrap(
request.get_data(as_text=True),
headers=dict(request.headers),
)
except Exception:
return "invalid signature", 400
if event.data.type == "session.status_idled":
print("session idled:", event.data.id)
# その他のイベントタイプを処理
return "", 200イベントを処理する
ボディを解析し、data.type で分岐し、IDでリソースを取得します。確認応答として任意の 2xx を返してください。それ以外のレスポンスはエンドポイントに対して不利にカウントされます。3xx はエンドポイントを即座に無効化し(リダイレクトは決して追従されません)、その他の失敗はリトライされます。リトライと自動無効化のルールについては配信の動作を参照してください。
すべてのイベントペイロードは同じ構造を持ち、イベントタイプ、識別子、およびイベントが発生した時刻のタイムスタンプを含みます。
{
"type": "event",
"id": "whe_9d5c1f7e...",
"created_at": "2026-03-18T14:05:22Z",
"data": {
"type": "session.status_idled",
"id": "sesn_01XYZ...",
"organization_id": "8a3d2f1e-...",
"workspace_id": "c7b0e4d9-..."
}
}if event.data.type == "session.status_idled":
session = client.beta.sessions.retrieve(event.data.id)
notify_user(session)
return "", 204トップレベルの event.id は配信ごとではなくイベントごとに一意です。同じ event.id を2回受信した場合、それはリトライであり、破棄して構いません。
配信の動作
-
重複: エンドポイントは同じイベントを複数回受信する可能性があり、すべての試行で同じトップレベルの
event.id(webhook-idヘッダーと同じ値)が配信されます。これを使って重複排除してください。 -
サブスクリプションのスコープ: イベントは、発行された時点でそのタイプをサブスクライブしているエンドポイントにのみ配信されます。どのエンドポイントもそのタイプをサブスクライブしていない間に発行されたイベントは決して配信されず、後からサブスクライブしてもバックフィルされないため、必要になる前にイベントタイプをサブスクライブしてください。
-
順序は保証されません。 イベントは発生した順序で配信されるわけではありません。成果が先に生成されていたとしても
session.status_idledがsession.outcome_evaluation_endedより先に到着する可能性があり、同じリソースに対する.deletedイベントが.archivedイベントより先に到着することもあります。イベントの到着順ではなく、取得したリソースに基づいて状態を管理してください。 -
リトライ: 各エンドポイントとイベントについて、Anthropicは5秒から120秒の間のジッター付き指数バックオフで最大3回の配信を試行します(このセクションの後半で説明する自動無効化をトリガーするレスポンスは決してリトライされません)。すべての試行で同じ
event.idが配信されます。最後の試行が失敗すると、イベントは破棄されます。後で配信するためにキューに入れられることはなく、失われたことを示すシグナルもありません。Webhookは永続的なログではないため、すべての遷移を観測する必要がある場合は、APIを通じてリソースを一覧取得または取得して整合性を取ってください。 -
タイムスタンプ:
webhook-timestampヘッダーは配信試行が署名されるときに付与され、リトライごとに再生成されるため、リトライがSDKの鮮度チェックで拒否されることはありません。これはイベントの時刻ではなく配信試行の時刻です。イベントが発生した時刻にはイベントペイロードのcreated_atを使用してください。 -
自動無効化: エンドポイントは、次の3つのケースで機械可読な
disabled_reasonとともに自動的にdisabledに設定されます。- エンドポイントが
3xxレスポンスを返した場合。リダイレクトは決して追従されません。これは最初の試行で即座にエンドポイントを無効化し、理由はauto-disabled: endpoint URL returned a redirect (3xx)となります。エンドポイントが移動した場合は、ConsoleでURLを更新し、エンドポイントを再度有効化してください。 - Anthropicが接続した際に、エンドポイントのURLが非公開IPアドレスに解決された場合。これはエンドポイントを即座に無効化し、理由は
auto-disabled: endpoint URL resolved to an invalid addressとなります。 - エンドポイントへの配信が一定期間継続して失敗した場合。理由は
auto-disabled after sustained delivery failuresとなります。トリガーとなるのは配信回数ではなく、エンドポイントが中断なく失敗し続けている時間の長さです。1回の2xxでウィンドウがリセットされるため、1つの不安定なイベントでエンドポイントが無効化されることはありません。
3つすべて元に戻すことができます。問題を解決した後、Consoleでエンドポイントを再度有効化してください。エンドポイントが無効化されていた間に発行されたイベントは再送されません。
- エンドポイントが
Was this page helpful?