Las sesiones son interacciones de larga duración. Si bien la mayoría de las interacciones en tiempo real ocurren a través del flujo de eventos SSE, los webhooks te notifican sobre cambios de estado importantes.
Los eventos de webhook devuelven el type y el id del evento, no el objeto completo. Cuando recibes un evento de webhook, necesitas obtener el objeto directamente con una llamada GET. Esto evita entregar datos obsoletos en los reintentos y mantiene cada entrega pequeña.
| Evento | Disparador |
|---|---|
session.status_run_started | La ejecución del agente se inició. Esto se dispara en cada transición del estado de la sesión a running. |
session.status_idled | El agente está esperando entrada, por ejemplo una aprobación de permiso de herramienta o un nuevo mensaje del usuario. |
session.status_rescheduled | Ocurrió un error transitorio y la sesión está reintentando automáticamente. |
session.status_terminated | La sesión terminó, ya sea por un error o por finalización. |
session.thread_created | Se abrió un nuevo hilo multiagente, lo que significa que un agente adicional llamado por el coordinador está iniciando trabajo. |
session.thread_idled | Un agente en una interacción multiagente está esperando entrada. |
session.thread_terminated | Un hilo multiagente terminó, ya sea porque el agente hijo completó su trabajo o porque el hilo fue archivado. Se dispara solo para hilos hijos; el final del hilo principal se manifiesta como session.status_terminated. |
session.outcome_evaluation_ended | La evaluación de resultados para una sola iteración se completó. |
session.updated | Las propiedades de la sesión cambiaron (por ejemplo, se actualizó su nombre o configuración). |
session.deleted | Sesión eliminada permanentemente. No queda ningún objeto que obtener, así que trata el evento en sí como definitivo. |
Visita Manage > Webhooks en Console.
Un endpoint de webhook consta de:
data.type que este endpoint recibe. Un endpoint solo recibe los eventos a los que está suscrito.whsec_ generado en el momento de la creación. Se muestra solo una vez, así que guárdalo de forma segura para verificar las entregas de webhook.Cada entrega lleva los encabezados webhook-id, webhook-timestamp y webhook-signature. Usa el helper unwrap() del SDK para verificar la firma y analizar el evento en un solo paso. Lanza una excepción si la firma es inválida o si el payload tiene más de cinco minutos de antigüedad.
Establece ANTHROPIC_WEBHOOK_SIGNING_KEY con el secreto con prefijo whsec_ que se muestra al crear el endpoint.
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() lanza una excepción si la firma es inválida o el payload está obsoleto
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)
# maneja otros tipos de eventos
return "", 200Analiza el cuerpo, haz un switch sobre data.type y obtén el recurso por ID. Devuelve cualquier 2xx para confirmar la recepción. Cualquier otra respuesta cuenta en contra del endpoint: un 3xx lo deshabilita inmediatamente (las redirecciones nunca se siguen), mientras que otras fallas se reintentan; consulta Comportamiento de entrega para las reglas de reintento y deshabilitación automática.
Cada payload de evento tiene la misma estructura, incluido el tipo de evento, el identificador y la marca de tiempo de cuándo ocurrió el evento.
{
"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 "", 204El event.id de nivel superior es único por evento, no por entrega. Si recibes el mismo event.id dos veces, es un reintento y puedes descartarlo.
Duplicados: Un endpoint puede recibir el mismo evento más de una vez, y cada intento entrega el mismo event.id de nivel superior (el mismo valor que el encabezado webhook-id). Deduplica usando ese valor.
Alcance de la suscripción: Un evento se entrega solo a los endpoints suscritos a su tipo en el momento en que se emite. Un evento emitido mientras ningún endpoint está suscrito a su tipo nunca se entrega, y suscribirse más tarde no lo recupera retroactivamente, así que suscríbete a un tipo de evento antes de necesitarlo.
El orden no está garantizado. Los eventos no se entregan en el orden en que ocurrieron: session.status_idled puede llegar antes que session.outcome_evaluation_ended incluso si el resultado se produjo primero, y un evento .deleted puede llegar antes que el evento .archived para el mismo recurso. Basa tu estado en el recurso que obtienes, no en el orden en que llegan los eventos.
Reintentos: Para cada endpoint y evento, Anthropic realiza hasta tres intentos de entrega (una respuesta que dispara la deshabilitación automática, descrita más adelante en esta sección, nunca se reintenta) con retroceso exponencial con jitter entre 5 y 120 segundos. Cada intento entrega el mismo event.id. Después de que falla el último intento, el evento se descarta: no se pone en cola para una entrega posterior y no hay ninguna señal de que se perdió. Los webhooks no son un registro duradero, así que si necesitas observar cada transición, reconcilia listando u obteniendo el recurso a través de la API.
Marcas de tiempo: El encabezado webhook-timestamp se estampa cuando se firma un intento de entrega y se regenera en cada reintento, por lo que los reintentos no son rechazados por la verificación de frescura del SDK. Es el reloj del intento de entrega, no del evento: usa el created_at del payload del evento para saber cuándo ocurrió el evento.
Deshabilitación automática: Un endpoint se establece automáticamente en disabled con un disabled_reason legible por máquina en tres casos:
3xx. Las redirecciones nunca se siguen; esto deshabilita el endpoint inmediatamente, en el primer intento, con la razón auto-disabled: endpoint URL returned a redirect (3xx). Si tu endpoint se mueve, actualiza la URL en Console y vuelve a habilitar el endpoint.auto-disabled: endpoint URL resolved to an invalid address.auto-disabled after sustained delivery failures. El disparador es cuánto tiempo ha estado fallando el endpoint sin interrupción, no un conteo de entregas. Un solo 2xx reinicia la ventana, por lo que un evento intermitente no puede deshabilitar el endpoint.Los tres son reversibles: vuelve a habilitar el endpoint en Console después de resolver el problema. Los eventos emitidos mientras el endpoint estaba deshabilitado no se reproducen.
Was this page helpful?