訂閱 webhook
在重大事件發生時收到通知,無需輪詢。
工作階段(session)是長時間執行的互動。雖然大多數即時互動是透過 SSE 事件串流進行,但「webhook」(網路鉤子)會在發生重大狀態變更時通知您。
Webhook 事件會傳回事件的 type 和 id,而非完整物件。當您收到 webhook 事件時,需要透過 GET 呼叫直接擷取該物件。這可避免在重試時傳遞過時的資料,並讓每次傳遞都保持精簡。
支援的事件類型
其中部分事件的名稱與工作階段事件串流上對應的事件不同。例如,串流中的 session.status_idle 和 session.status_running 分別對應 session.status_idled 和 session.status_run_started webhook 事件。
| 事件 | 觸發條件 |
|---|---|
session.status_run_started | 代理程式開始執行。每當工作階段狀態轉換為 running 時都會觸發。 |
session.status_idled | 代理程式正在等待輸入,例如工具權限核准或新的使用者訊息。 |
session.budget_reached | 工作階段已達到其預算並暫停。對於您設定的每個預算值最多觸發一次;變更預算會重新啟用此事件。 |
session.status_rescheduled | 發生暫時性錯誤,工作階段正在自動重試。 |
session.status_terminated | 工作階段已終止,原因可能是發生無法復原的錯誤,或是已被封存。 |
session.thread_created | 開啟了新的多代理程式執行緒:由工作階段所執行的代理程式呼叫的額外代理程式開始工作,或正在諮詢工作階段的顧問。此事件也會針對工作流程執行的每個執行緒觸發,本表中的另外兩個執行緒事件亦同。 |
session.thread_idled | 多代理程式互動中的某個代理程式正在等待輸入。 |
session.thread_terminated | 多代理程式執行緒已終止,原因可能是執行緒已被封存,或已用盡其重試次數。完成工作的子代理程式會進入 idle,而非 terminated(顧問執行緒會在其諮詢完成後終止,而工作流程執行的執行緒會在伺服器於執行結束時將其封存後終止)。僅針對子執行緒觸發;主要執行緒的結束(包括封存整個工作階段)只會以 session.status_terminated 呈現。 |
session.outcome_evaluation_ended | 單次迭代的結果評估已完成。 |
session.updated | 工作階段屬性已變更(例如其名稱或設定已更新)。 |
session.deleted | 工作階段已永久刪除。已沒有可擷取的物件,因此請將事件本身視為最終結果。 |
| 事件 | 觸發條件 |
|---|---|
vault.created | Vault 已建立。 |
vault.archived | Vault 已封存。每個底層憑證也會發出一個 vault_credential.archived 事件。 |
vault.deleted | Vault 已刪除。每個底層憑證也會發出一個 vault_credential.deleted 事件。已沒有可擷取的物件,因此請將事件本身視為最終結果。 |
vault_credential.created | 憑證已建立。 |
vault_credential.archived | 憑證已封存,可能是直接封存,或是因 vault 封存所致。 |
vault_credential.deleted | 憑證已刪除,可能是直接刪除,或是因 vault 刪除所致。已沒有可擷取的物件,因此請將事件本身視為最終結果。 |
vault_credential.refresh_failed | 無法重新整理 mcp_oauth 憑證(重新整理權杖無效,或 OAuth 伺服器發生無法復原的錯誤)。 |
這些事件追蹤您工作區中代理程式資源的生命週期,與工作階段事件串流上傳遞的代理程式事件不同。
| 事件 | 觸發條件 |
|---|---|
agent.created | 代理程式已建立。 |
agent.updated | 已發布新版本的代理程式。未建立新版本的更新不會觸發此事件。 |
agent.archived | 代理程式已封存。 |
agent.deleted | 代理程式已永久刪除。已沒有可擷取的物件,因此請將事件本身視為最終結果。 |
| 事件 | 觸發條件 |
|---|---|
deployment.created | 排程部署已建立。 |
deployment.updated | 部署屬性已變更(例如其排程已更新)。 |
deployment.paused | 部署已暫停,可能是應要求暫停,或是在排程執行因無法復原的錯誤(例如子代理程式已封存或環境已封存)而失敗時自動暫停。可復原的失敗(包括速率限制)不會暫停部署。請參閱失敗行為。 |
deployment.unpaused | 部署已取消暫停,恢復其排程。 |
deployment.archived | 部署已封存,可能是直接封存,或是因其代理程式已封存所致。如果代理程式改為被刪除,排程部署會在其下一次排程執行時封存;沒有排程的部署不會自動封存。 |
deployment.deleted | 部署已永久刪除。已沒有可擷取的物件,因此請將事件本身視為最終結果。 |
| 事件 | 觸發條件 |
|---|---|
deployment_run.started | 排程執行已開始。只有排程執行會發出 deployment_run 事件;手動執行則不會。 |
deployment_run.succeeded | 排程執行已建立其工作階段。此事件帶有與該執行的 deployment_run.started 事件相同的 data.id(執行 ID)。若要追蹤工作階段的工作,請訂閱其工作階段事件(工作階段事件分頁),或擷取部署執行以取得其 session_id。 |
deployment_run.failed | 排程執行未建立工作階段。此事件帶有與該執行的 deployment_run.started 事件相同的 data.id。請擷取部署執行以取得錯誤詳細資訊。 |
| 事件 | 觸發條件 |
|---|---|
environment.created | 環境已建立。 |
environment.updated | 環境已更新,且至少有一個欄位變更。無實際變更的更新不會發出任何事件。 |
environment.archived | 環境已封存。重新封存已封存的環境不會發出任何事件。 |
environment.deleted | 環境已刪除,包括刪除已封存的環境。已沒有可擷取的物件,因此請將事件本身視為最終結果。 |
環境的工作項目不會發出任何 webhook 事件。
| 事件 | 觸發條件 |
|---|---|
memory_store.created | 記憶儲存區已建立,可能是由您建立,或是由 Anthropic 營運的程序複製您現有的某個儲存區而建立。 |
memory_store.archived | 記憶儲存區已封存。重新封存已封存的儲存區不會發出任何事件。 |
memory_store.deleted | 記憶儲存區已刪除,包括刪除已封存的儲存區。刪除儲存區會連帶刪除其記憶和記憶版本,但不會針對每個記憶發出事件;單一的 memory_store.deleted 事件即為訊號。已沒有可擷取的物件,因此請將事件本身視為最終結果。 |
個別的記憶和記憶版本不會發出任何 webhook 事件。
註冊端點
在 Claude Console 中,前往 Webhooks 頁面(platform.claude.com/settings/workspaces/default/webhooks)。每個端點屬於一個工作區。請在側邊欄的工作區選擇器中選取您要的工作區。
Webhook 端點包含:
- URL: 必須是使用連接埠 443 的 HTTPS,且主機名稱可公開解析。
- 事件類型: 此端點接收的
data.type值清單。端點只會接收其已訂閱的事件。 - 簽署密鑰: 建立時產生的 32 位元組、以
whsec_為前綴的密鑰。它只會顯示一次,因此請妥善保存,以便驗證 webhook 傳遞。
驗證簽章
每次傳遞都帶有 webhook-id、webhook-timestamp 和 webhook-signature 標頭。使用 SDK 的 unwrap() 輔助函式,即可一步完成簽章驗證並解析事件。如果簽章無效或酬載超過 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:
# 若簽章無效或 payload 已過期,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 兩次,那就是重試,您可以將其捨棄。
傳遞行為
-
重複: 端點可能會多次收到相同的事件,且每次嘗試都會傳遞相同的頂層
event.id(與webhook-id標頭的值相同)。請依此進行去重複。 -
訂閱範圍: 事件只會傳遞給在其發出當下已訂閱該類型的端點。在沒有任何端點訂閱其類型時發出的事件永遠不會被傳遞,之後再訂閱也不會回補,因此請在需要之前就訂閱事件類型。
-
不保證順序。 事件不會依其發生的順序傳遞:即使結果先產生,
session.status_idled也可能在session.outcome_evaluation_ended之前抵達,而同一資源的.deleted事件也可能在.archived事件之前抵達。請依據您擷取的資源來驅動您的狀態,而非依據事件抵達的順序。 -
重試: 對於每個端點和事件,Anthropic 最多會進行三次傳遞嘗試(觸發自動停用的回應永遠不會重試,詳見本節稍後說明),並在 5 到 120 秒之間採用帶有隨機抖動的指數退避。每次嘗試都會傳遞相同的
event.id。最後一次嘗試失敗後,事件即被捨棄:它不會被排入佇列以供稍後傳遞,也不會有任何訊號表示它已遺失。Webhook 並非持久性日誌,因此如果您需要觀察每一次轉換,請透過 API 列出或擷取資源來進行核對。 -
時間戳記:
webhook-timestamp標頭是在簽署傳遞嘗試時加上的,且每次重試都會重新產生,因此重試不會被 SDK 的新鮮度檢查拒絕。它是傳遞嘗試的時鐘,而非事件的時鐘:請使用事件酬載的created_at來得知事件發生的時間。 -
自動停用: 在以下三種情況下,端點會自動設為
disabled,並附上機器可讀的disabled_reason:- 端點傳回
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。觸發條件是端點持續不間斷失敗的時間長度,而非傳遞次數。單一2xx即會重設時間窗口,因此單一不穩定的事件無法停用端點。
這三種情況都可以復原:在解決問題後,於 Console 中重新啟用端點即可。端點停用期間發出的事件不會重新傳送。
- 端點傳回
Was this page helpful?