Les sessions sont des interactions de longue durée. Alors que la plupart des interactions en temps réel passent par le flux d'événements SSE, les webhooks vous notifient des changements d'état majeurs.
Les événements webhook renvoient le type et l'id de l'événement, et non l'objet complet. Lorsque vous recevez un événement webhook, vous devez récupérer l'objet directement avec un appel GET. Cela évite de livrer des données obsolètes lors des nouvelles tentatives et garantit que chaque livraison reste légère.
| Événement | Déclencheur |
|---|---|
session.status_run_started | L'exécution de l'agent a démarré. Cet événement se déclenche à chaque transition du statut de la session vers running. |
session.status_idled | L'agent attend une entrée, par exemple une approbation de permission d'outil ou un nouveau message utilisateur. |
session.budget_reached | La session a atteint son budget et s'est mise en pause. Se déclenche au plus une fois pour chaque valeur de budget que vous définissez ; modifier le budget le réarme. |
session.status_rescheduled | Une erreur transitoire s'est produite et la session effectue automatiquement une nouvelle tentative. |
session.status_terminated | La session s'est terminée, soit en raison d'une erreur irrécupérable, soit parce qu'elle a été archivée. |
session.thread_created | Un nouveau thread multi-agent s'est ouvert : un agent supplémentaire appelé par le coordinateur commence son travail, ou l'advisor de la session est consulté. |
session.thread_idled | Un agent dans une interaction multi-agent attend une entrée. |
session.thread_terminated | Un thread multi-agent s'est terminé, soit parce que le thread a été archivé, soit parce qu'il a épuisé ses tentatives. Un thread enfant créé par le coordinateur qui termine son travail passe à l'état idle, et non terminated (un thread advisor se termine une fois sa consultation achevée). Se déclenche uniquement pour les threads enfants ; la fin du thread principal, y compris l'archivage de la session entière, n'apparaît que sous la forme de session.status_terminated. |
session.outcome_evaluation_ended | L'évaluation des résultats pour une seule itération est terminée. |
session.updated | Les propriétés de la session ont changé (par exemple, son nom ou sa configuration a été mis à jour). |
session.deleted | Session supprimée définitivement. Il n'y a plus d'objet à récupérer, considérez donc l'événement lui-même comme final. |
Rendez-vous dans Manage > Webhooks dans la Claude Console.
Un point de terminaison webhook se compose de :
data.type que ce point de terminaison reçoit. Un point de terminaison ne reçoit que les événements auxquels il est abonné.whsec_, généré à la création. Il n'est affiché qu'une seule fois, stockez-le donc de manière sécurisée pour vérifier les livraisons webhook.Chaque livraison comporte les en-têtes webhook-id, webhook-timestamp et webhook-signature. Utilisez la fonction d'aide unwrap() du SDK pour vérifier la signature et analyser l'événement en une seule étape. Elle lève une exception si la signature est invalide ou si la charge utile date de plus de 5 minutes.
Définissez ANTHROPIC_WEBHOOK_SIGNING_KEY avec le secret préfixé par whsec_ affiché lors de la création du point de terminaison.
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ève une exception si la signature est invalide ou si la charge utile est périmée
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)
# gérer les autres types d'événements
return "", 200Analysez le corps, effectuez un branchement sur data.type, et récupérez la ressource par son ID. Renvoyez n'importe quel code 2xx pour accuser réception. Toute autre réponse est comptabilisée contre le point de terminaison : un 3xx le désactive immédiatement (les redirections ne sont jamais suivies), tandis que les autres échecs font l'objet de nouvelles tentatives ; consultez Comportement de livraison pour les règles de nouvelle tentative et de désactivation automatique.
Chaque charge utile d'événement a la même structure, incluant le type d'événement, l'identifiant et l'horodatage du moment où l'événement s'est produit.
{
"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 "", 204Le event.id de niveau supérieur est unique par événement, et non par livraison. Si vous recevez le même event.id deux fois, il s'agit d'une nouvelle tentative et vous pouvez l'ignorer.
Doublons : Un point de terminaison peut recevoir le même événement plusieurs fois, et chaque tentative livre le même event.id de niveau supérieur (la même valeur que l'en-tête webhook-id). Dédupliquez sur cette base.
Portée de l'abonnement : Un événement n'est livré qu'aux points de terminaison abonnés à son type au moment où il est émis. Un événement émis alors qu'aucun point de terminaison n'est abonné à son type n'est jamais livré, et s'abonner ultérieurement ne le rattrape pas rétroactivement ; abonnez-vous donc à un type d'événement avant d'en avoir besoin.
L'ordre n'est pas garanti. Les événements ne sont pas livrés dans l'ordre où ils se sont produits : session.status_idled peut arriver avant session.outcome_evaluation_ended même si le résultat a été produit en premier, et un événement .deleted peut arriver avant l'événement .archived pour la même ressource. Basez votre état sur la ressource que vous récupérez, et non sur l'ordre d'arrivée des événements.
Nouvelles tentatives : Pour chaque point de terminaison et chaque événement, Anthropic effectue jusqu'à trois tentatives de livraison (une réponse qui déclenche la désactivation automatique, décrite plus loin dans cette section, ne fait jamais l'objet d'une nouvelle tentative) avec un délai exponentiel aléatoire compris entre 5 et 120 secondes. Chaque tentative livre le même event.id. Après l'échec de la dernière tentative, l'événement est abandonné : il n'est pas mis en file d'attente pour une livraison ultérieure et aucun signal n'indique qu'il a été perdu. Les webhooks ne constituent pas un journal durable ; si vous devez observer chaque transition, effectuez une réconciliation en listant ou en récupérant la ressource via l'API.
Horodatages : L'en-tête webhook-timestamp est apposé au moment où une tentative de livraison est signée et est régénéré à chaque nouvelle tentative, de sorte que les nouvelles tentatives ne sont pas rejetées par la vérification de fraîcheur du SDK. Il s'agit de l'horloge de la tentative de livraison, et non de celle de l'événement : utilisez le champ created_at de la charge utile de l'événement pour savoir quand l'événement s'est produit.
Désactivation automatique : Un point de terminaison est automatiquement défini sur disabled avec un disabled_reason lisible par machine dans trois cas :
3xx. Les redirections ne sont jamais suivies ; cela désactive le point de terminaison immédiatement, dès la première tentative, avec la raison auto-disabled: endpoint URL returned a redirect (3xx). Si votre point de terminaison change d'adresse, mettez à jour l'URL dans la Console et réactivez le point de terminaison.auto-disabled: endpoint URL resolved to an invalid address.auto-disabled after sustained delivery failures. Le déclencheur est la durée pendant laquelle le point de terminaison a échoué sans interruption, et non un nombre de livraisons. Un seul 2xx réinitialise la fenêtre, de sorte qu'un événement isolé instable ne peut pas désactiver le point de terminaison.Ces trois cas sont réversibles : réactivez le point de terminaison dans la Console après avoir résolu le problème. Les événements émis pendant que le point de terminaison était désactivé ne sont pas rejoués.
Was this page helpful?