Webhooks
Envía eventos firmados en tiempo real a servicios externos.
Los webhooks envían notificaciones firmadas cuando cambian los leads, formularios, conversaciones o escalaciones. Requieren un plan Hobby o superior con facturación activa.
Configurar un endpoint
Abre Configuración → Webhooks en un agente, elige uno o más eventos, ingresa un endpoint público con HTTPS y crea las suscripciones. Agentkit mantiene un único secreto de firma para todas las filas de eventos del mismo endpoint. Los propietarios de la cuenta pueden revelarlo o rotarlo desde la tarjeta del endpoint.
Los nombres de eventos admitidos son:
lead_createdform_submission(alias heredado de lead)custom_form_submittedconversation_startedconversation_endedescalation_created
conversation_ended se emite después de 30 minutos sin un mensaje. Su transcripción es una instantánea inmutable de un máximo de 200 mensajes, con cada mensaje limitado a 2000 caracteres. Las conversaciones que ocurren solo en el Playground o que no tienen mensajes del usuario no se envían. El análisis de la transcripción es null por ahora.
Estructura del evento
Todos los eventos usan la misma estructura estable:
{
"event": "conversation_started",
"eventId": "evt_91d0a3ce-5a9d-4b67-a454-bafb9484281a",
"timestamp": "2026-07-14T13:05:02.000Z",
"data": {
"conversationId": "0b8e43d2-6cdf-42a8-8df1-a17f082df99f",
"conversationReferenceId": "a1b2c3d4e5f6a7b8",
"chatbotId": "d21c2aca-52d7-4056-a7d6-805713d3d39c",
"source": "widget",
"startedAt": "2026-07-14T13:05:02.000Z"
}
}
Usa eventId como tu clave de idempotencia. La entrega se garantiza al menos una vez, pero no se garantiza el orden. El mismo ID de evento, la marca de tiempo de ocurrencia y los bytes JSON se reutilizan en los reintentos.
Verificar firmas
Las entregas incluyen:
X-Agentkit-Event: conversation_started X-Agentkit-Event-Id: evt_91d0a3ce-5a9d-4b67-a454-bafb9484281a X-Agentkit-Signature: t=1784043902,v1=<hex-hmac-sha256>
Lee el cuerpo de la solicitud como texto UTF-8 sin procesar. Analiza t y v1, calcula HMAC-SHA256 con el secreto del endpoint sobre los bytes exactos de t + "." + rawBody, y compara los resúmenes con una función de tiempo constante. No parsees ni reserialices el JSON antes de la verificación. Rechaza las marcas de tiempo obsoletas según tu política de repetición.
import { createHmac, timingSafeEqual } from 'node:crypto';
const expected = createHmac('sha256', process.env.AGENTKIT_WEBHOOK_SECRET!)
.update(`${timestamp}.${rawBody}`, 'utf8')
.digest('hex');
const valid = timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(v1, 'hex'));
Fiabilidad y resultados
Devuelve un estado 2xx en un plazo de 10 segundos. Una respuesta que no sea 2xx, un tiempo de espera agotado o un error de red se reintenta cinco veces después de la solicitud inicial (normalmente seis intentos en total) con el backoff de QStash. La página de configuración muestra los últimos 20 resultados finales.
Un evento agotado incrementa la racha de fallos una sola vez, sin importar los intentos o las devoluciones de llamada duplicadas. Una suscripción se desactiva automáticamente solo después de al menos 10 eventos agotados consecutivos que abarquen al menos siete días. Los propietarios reciben una notificación que se puede reintentar y pueden volver a habilitarla después de la reparación. Un evento exitoso reinicia la racha.
Las URLs de endpoint deben usar HTTP o HTTPS, deben ser públicas y no pueden apuntar a localhost, rangos de IP privados/link-local, ni endpoints de metadatos en la nube. La producción requiere HTTPS. En el momento de la entrega, Agentkit resuelve el nombre de host una sola vez, exige que todas las direcciones resueltas sean públicas y fija la conexión a esas direcciones, de modo que el DNS rebinding no puede redirigir una entrega a una dirección interna.
Activación de la programación
El código de barrido de conversaciones inactivas se envía deshabilitado. Un operador puede revisarlo y ejecutar pnpm --filter chatbots setup:idle-conversation-webhooks después del despliegue. El comando crea la programación de QStash de 15 minutos; fusionar el código no la crea ni la habilita.