Webhooks abonnieren
Lass dich ohne Polling benachrichtigen, wenn wichtige Ereignisse eintreten.
Sessions sind lang laufende Interaktionen. Während die meisten Echtzeit-Interaktionen über den SSE-Event-Stream stattfinden, benachrichtigen dich Webhooks über wichtige Zustandsänderungen.
Webhook-Events geben den Event-type und die id zurück, nicht das vollständige Objekt. Wenn du ein Webhook-Event empfängst, musst du das Objekt direkt mit einem GET-Aufruf abrufen. Dadurch wird vermieden, dass bei Wiederholungen veraltete Daten zugestellt werden, und jede Zustellung bleibt klein.
Unterstützte Event-Typen
Einige dieser Events sind anders benannt als die entsprechenden Events im Event-Stream der Session. Beispielsweise entsprechen session.status_idle und session.status_running des Streams den Webhook-Events session.status_idled und session.status_run_started.
| Event | Auslöser |
|---|---|
session.status_run_started | Die Agent-Ausführung wurde gestartet. Dies wird bei jedem Übergang des Session-Status zu running ausgelöst. |
session.status_idled | Der Agent wartet auf Eingabe, zum Beispiel auf die Genehmigung einer Tool-Berechtigung oder eine neue Benutzernachricht. |
session.budget_reached | Die Session hat ihr Budget erreicht und wurde pausiert. Wird höchstens einmal pro von dir gesetztem Budgetwert ausgelöst; eine Änderung des Budgets aktiviert es erneut. |
session.status_rescheduled | Ein vorübergehender Fehler ist aufgetreten und die Session versucht es automatisch erneut. |
session.status_terminated | Die Session wurde beendet, entweder aufgrund eines nicht behebbaren Fehlers oder weil sie archiviert wurde. |
session.thread_created | Ein neuer Multiagent-Thread wurde geöffnet: Ein zusätzlicher, vom Koordinator aufgerufener Agent beginnt mit der Arbeit, oder der Advisor der Session wird konsultiert. |
session.thread_idled | Ein Agent in einer Multiagent-Interaktion wartet auf Eingabe. |
session.thread_terminated | Ein Multiagent-Thread wurde beendet, entweder weil der Thread archiviert wurde oder weil er seine Wiederholungsversuche ausgeschöpft hat. Ein vom Koordinator erzeugter Kind-Thread, der seine Arbeit abschließt, wechselt zu idle, nicht zu terminated (ein Advisor-Thread wird beendet, sobald seine Konsultation abgeschlossen ist). Wird nur für Kind-Threads ausgelöst; das Ende des primären Threads, einschließlich der Archivierung der gesamten Session, erscheint nur als session.status_terminated. |
session.outcome_evaluation_ended | Die Ergebnisbewertung für eine einzelne Iteration wurde abgeschlossen. |
session.updated | Session-Eigenschaften haben sich geändert (zum Beispiel wurde ihr Name oder ihre Konfiguration aktualisiert). |
session.deleted | Die Session wurde dauerhaft gelöscht. Es gibt kein Objekt mehr zum Abrufen, behandle daher das Event selbst als endgültig. |
Einen Endpunkt registrieren
Besuche Manage > Webhooks in der Claude Console.
Ein Webhook-Endpunkt besteht aus:
- URL: Muss HTTPS auf Port 443 mit einem öffentlich auflösbaren Hostnamen sein.
- Event-Typen: Die Liste der
data.type-Werte, die dieser Endpunkt empfängt. Ein Endpunkt empfängt nur Events, die er abonniert hat. - Signing Secret: Ein 32 Byte langes Secret mit dem Präfix
whsec_, das bei der Erstellung generiert wird. Es wird nur einmal angezeigt, speichere es daher sicher, um Webhook-Zustellungen zu verifizieren.
Die Signatur verifizieren
Jede Zustellung trägt die Header webhook-id, webhook-timestamp und webhook-signature. Verwende den unwrap()-Helper des SDK, um die Signatur zu verifizieren und das Event in einem Schritt zu parsen. Er wirft einen Fehler, wenn die Signatur ungültig ist oder die Payload älter als 5 Minuten ist.
Setze ANTHROPIC_WEBHOOK_SIGNING_KEY auf das bei der Endpunkt-Erstellung angezeigte Secret mit dem Präfix 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() löst eine Exception aus, wenn die Signatur ungültig oder die Payload veraltet ist
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)
# andere Event-Typen behandeln
return "", 200Ein Event verarbeiten
Parse den Body, verzweige anhand von data.type und rufe die Ressource per ID ab. Gib einen beliebigen 2xx-Status zurück, um den Empfang zu bestätigen. Jede andere Antwort zählt gegen den Endpunkt: Ein 3xx deaktiviert ihn sofort (Weiterleitungen werden nie befolgt), während andere Fehler wiederholt werden; siehe Zustellverhalten für die Regeln zu Wiederholungen und automatischer Deaktivierung.
Jede Event-Payload hat dieselbe Struktur, einschließlich des Event-Typs, der Kennung und des Zeitstempels, wann das Event aufgetreten ist.
{
"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 "", 204Die event.id auf oberster Ebene ist pro Event eindeutig, nicht pro Zustellung. Wenn du dieselbe event.id zweimal empfängst, handelt es sich um eine Wiederholung und du kannst sie verwerfen.
Zustellverhalten
-
Duplikate: Ein Endpunkt kann dasselbe Event mehr als einmal empfangen, und jeder Versuch liefert dieselbe
event.idauf oberster Ebene (denselben Wert wie derwebhook-id-Header). Dedupliziere anhand dieses Werts. -
Abonnement-Umfang: Ein Event wird nur an Endpunkte zugestellt, die seinen Typ in dem Moment abonniert haben, in dem es ausgegeben wird. Ein Event, das ausgegeben wird, während kein Endpunkt seinen Typ abonniert hat, wird nie zugestellt, und ein späteres Abonnieren füllt es nicht nachträglich auf. Abonniere daher einen Event-Typ, bevor du ihn benötigst.
-
Die Reihenfolge ist nicht garantiert. Events werden nicht in der Reihenfolge zugestellt, in der sie aufgetreten sind:
session.status_idledkann vorsession.outcome_evaluation_endedeintreffen, selbst wenn das Ergebnis zuerst erzeugt wurde, und ein.deleted-Event kann vor dem.archived-Event für dieselbe Ressource eintreffen. Leite deinen Zustand aus der abgerufenen Ressource ab, nicht aus der Reihenfolge, in der Events eintreffen. -
Wiederholungen: Für jeden Endpunkt und jedes Event unternimmt Anthropic bis zu drei Zustellversuche (eine Antwort, die die weiter unten in diesem Abschnitt beschriebene automatische Deaktivierung auslöst, wird nie wiederholt) mit exponentiellem Backoff mit Jitter zwischen 5 und 120 Sekunden. Jeder Versuch liefert dieselbe
event.id. Nachdem der letzte Versuch fehlgeschlagen ist, wird das Event verworfen: Es wird nicht für eine spätere Zustellung in eine Warteschlange gestellt, und es gibt kein Signal, dass es verloren gegangen ist. Webhooks sind kein dauerhaftes Protokoll. Wenn du also jeden Übergang beobachten musst, gleiche den Zustand ab, indem du die Ressource über die API auflistest oder abrufst. -
Zeitstempel: Der
webhook-timestamp-Header wird gesetzt, wenn ein Zustellversuch signiert wird, und bei jeder Wiederholung neu erzeugt, sodass Wiederholungen nicht von der Aktualitätsprüfung des SDK abgelehnt werden. Er ist die Uhr für den Zustellversuch, nicht für das Event: Verwendecreated_ataus der Event-Payload, um zu bestimmen, wann das Event aufgetreten ist. -
Automatische Deaktivierung: Ein Endpunkt wird in drei Fällen automatisch auf
disabledgesetzt, mit einem maschinenlesbarendisabled_reason:- Der Endpunkt gibt eine
3xx-Antwort zurück. Weiterleitungen werden nie befolgt; dies deaktiviert den Endpunkt sofort, beim ersten Versuch, mit dem Grundauto-disabled: endpoint URL returned a redirect (3xx). Wenn dein Endpunkt umzieht, aktualisiere die URL in der Console und aktiviere den Endpunkt erneut. - Die URL des Endpunkts wird zu einer nicht öffentlichen IP-Adresse aufgelöst, wenn Anthropic eine Verbindung herstellt. Dies deaktiviert den Endpunkt sofort, mit dem Grund
auto-disabled: endpoint URL resolved to an invalid address. - Zustellungen an den Endpunkt schlagen über einen längeren Zeitraum ununterbrochen fehl, mit dem Grund
auto-disabled after sustained delivery failures. Der Auslöser ist, wie lange der Endpunkt ohne Unterbrechung fehlgeschlagen ist, nicht eine Anzahl von Zustellungen. Ein einzelner2xx-Status setzt das Zeitfenster zurück, sodass ein einzelnes unzuverlässiges Event den Endpunkt nicht deaktivieren kann.
Alle drei sind umkehrbar: Aktiviere den Endpunkt in der Console erneut, nachdem du das Problem behoben hast. Events, die ausgegeben wurden, während der Endpunkt deaktiviert war, werden nicht erneut zugestellt.
- Der Endpunkt gibt eine
Was this page helpful?