Información general sobre webhooks
Los webhooks permiten que ChatLab notifique a tus sistemas en el instante en que ocurre algo en tus chatbots. En lugar de hacer consultas continuas a la Management API o exportar datos de forma manual, registras un endpoint HTTPS y ChatLab le envía una petición HTTP POST firmada en tiempo real - cuando un visitante deja un lead, envía un formulario de contacto, califica una conversación, solicita atención humana o cuando se ejecuta una acción de IA.
Usos habituales:
- enviar nuevos leads directamente a tu CRM en el mismo segundo en que se capturan
- notificar a tu equipo en Slack cuando un visitante solicita chat en vivo
- transferir calificaciones y resúmenes de conversaciones a tus propias herramientas de analítica
- monitorizar ejecuciones de acciones de IA y generar alertas ante errores
Disponibilidad: tu cuenta debe incluir la función Webhooks.
Dónde configurarlo: en la aplicación de administración, abre Account settings -> Webhooks (Configuración de la cuenta -> Webhooks) (justo al lado de la sección de Management API). Los webhooks funcionan a nivel de cuenta: un único endpoint puede recibir eventos de todos tus bots o de un bot seleccionado.
Configurar un endpoint
- Abre Account settings -> Webhooks y haz clic en Add endpoint (Añadir endpoint).
- Completa el formulario del endpoint:
- Name (Nombre) - una etiqueta para tu propia referencia, por ejemplo "Sincronización con CRM" o "Alertas de Slack".
- URL - la dirección HTTPS a la que ChatLab enviará los eventos mediante POST.
- Events (Eventos) - selecciona qué tipos de eventos recibe este endpoint (consulta el catálogo a continuación). Selecciona solo lo que necesites; los eventos de gran volumen como
ai_action.executedpueden generar mucho tráfico. - Bot filter (Filtro de bot) (opcional) - selecciona un bot, o All bots (Todos los bots) para todos los bots de tu cuenta.
- Custom form filter (Filtro de formulario personalizado) (opcional) - enruta los envíos de un formulario personalizado a este endpoint. Solo filtra el evento
custom_form.submitted; cualquier otro evento al que te suscribas (leads, solicitudes de contacto, conversaciones, chat en vivo, acciones de IA) se entrega con independencia de esta configuración.
- Guarda los cambios. El secreto del endpoint se muestra exactamente una vez en el cuadro de diálogo de confirmación: cópialo ahora y guárdalo de forma segura. Lo necesitarás para verificar firmas (consulta la sección Seguridad más abajo). El texto sin cifrar no se puede recuperar después.
Cada endpoint también dispone de:
- Interruptor para activar/desactivar - pausa las entregas sin eliminar el endpoint. Los endpoints desactivados descartan los eventos sin avisar (no se ponen en cola para después).
- Send sample event (Enviar evento de prueba) - envía una petición de prueba firmada a tu URL para que puedas verificar tu receptor de extremo a extremo. Puedes elegir el tipo de evento y editar los valores de muestra antes de enviarlo, de modo que tu controlador reciba datos realistas. La prueba llega como una entrega habitual con el
eventTypecorrespondiente a tu selección (o comowebhook.testpara una comprobación básica de conectividad). - Roll secret (Renovar secreto) - genera un nuevo secreto e invalida el anterior. Utiliza esta opción si sospechas que el secreto se ha filtrado. El nuevo secreto también se muestra una sola vez. Para realizar una rotación controlada, pausa el endpoint, renueva y copia el nuevo secreto, actualiza el receptor y, a continuación, vuelve a activarlo y envía un evento de prueba. Los eventos generados durante la pausa no se ponen en cola. Planifica esta interrupción antes de renovarlo.
- Delivery log (Registro de entregas) - una lista de entregas recientes por endpoint con marca de tiempo, tipo de evento, estado HTTP devuelto por tu servidor y tiempo de respuesta. Las entregas fallidas y las pausas del interruptor de circuito se muestran aquí. El registro se conserva durante 14 días.
Envoltura de eventos
Cada entrega es un HTTP POST con Content-Type: application/json. El cuerpo siempre tiene la misma envoltura; el objeto data es específico de cada tipo de evento:
{
"eventId": "9f1c1c8e-6a2b-4b9e-9d2f-3f8a1e2b4c5d",
"eventType": "lead.created",
"timestamp": "2026-08-13T14:22:31Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": { }
}
eventId- único por evento. Utilízalo para deduplicar si tu procesamiento debe ser idempotente.eventType- uno de los tipos documentados a continuación; también se envía en el encabezadoX-ChatLab-Event.timestamp- hora UTC en formato ISO 8601 en la que se preparó la envoltura de la entrega.botId/botName- el bot al que pertenece el evento.conversationId/sessionId- el contexto de la conversación, cuando proceda.
Catálogo de eventos
lead.created
Se activa cuando un visitante envía sus datos de contacto, ya sea a través del formulario de captación de leads, el formulario previo de live chat o un formulario personalizado utilizado para la captación de leads.
{
"eventId": "9f1c1c8e-6a2b-4b9e-9d2f-3f8a1e2b4c5d",
"eventType": "lead.created",
"timestamp": "2026-08-13T14:22:31Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"email": "jane.doe@example.com",
"name": "Jane Doe",
"phone": "+1 555 0123",
"source": "LEAD_COLLECTION_FORM",
"formCodeName": "lead_form",
"formName": "Lead form",
"fields": [
{"name": "email", "value": "jane.doe@example.com", "type": "email"},
{"name": "company", "value": "Acme Inc.", "type": "text"},
{"name": "topics", "value": ["Billing", "Delivery"], "type": "multichoice"},
{"name": "attachment", "value": "https://api.chatlab.com/aichat/customform/download?key=...&token=...", "type": "file"}
],
"pageUrl": "https://acme.com/pricing"
}
}
source- cómo se capturaron los datos de contacto:LEAD_COLLECTION_FORM(formulario de captación de leads),LIVE_CHAT_FORM(formulario previo de live chat),CONVERSATION(la IA recopiló los datos durante la conversación),ADMIN_DATA_UPDATEoUPDATE_CLIENT_CONTEXT(editado desde ChatLab). Los envíos del formulario de soporte humano nunca activan este evento; en su lugar activancontact_form.submitted.email,name,phone- los datos de contacto asignados al registro del lead.- Cuando se utiliza un formulario personalizado para captar leads, cada campo definido en ese formulario se incluye en
fields, en el orden del formulario, yformCodeName/formNameidentifican el formulario. Con el formulario de captación de leads clásico, ambos sonnullyfieldses un array vacío. - Cada entrada en
fieldses{name, value, type}.namees el nombre técnico del campo, que no cambia aunque se editen las etiquetas; utilízalo para el mapeo en tu CRM. - Para los campos
multichoice,valuees un array de las opciones seleccionadas. Los campos de casilla de verificación son entradas individuales con valores"true"/"false". - Para los campos
file,valuees un enlace de descarga al archivo subido; el webhook nunca incluye el contenido del archivo. pageUrl- la página en la que se encontraba el visitante al realizar el envío.
contact_form.submitted
Se activa cuando un visitante envía el formulario de contacto para soporte humano o un formulario personalizado utilizado para el contacto humano.
{
"eventId": "3a7b9c2d-1e4f-4a6b-8c0d-5e2f7a9b1c3d",
"eventType": "contact_form.submitted",
"timestamp": "2026-08-13T14:25:02Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"email": "jane.doe@example.com",
"message": "I need help with my last invoice.",
"source": "CUSTOM_FORM",
"formCodeName": "contact_form",
"formName": "Contact form",
"fields": [
{"name": "email", "value": "jane.doe@example.com", "type": "email"},
{"name": "order_number", "value": "A-10293", "type": "text"},
{"name": "message", "value": "I need help with my last invoice.", "type": "textarea"}
]
}
}
email- la dirección que dejó el visitante y a la que tu equipo de soporte debe responder.source-CUSTOM_FORMcuando el formulario de contacto se basa en un formulario personalizado,CONTACT_FORMpara el formulario integrado.formCodeName/formName- identifican el formulario personalizado detrás de la solicitud; ambos sonnullpara el formulario integrado.- Cuando se utiliza un formulario personalizado, se incluye cada campo definido en él en
fields(mismo formato{name, value, type}que enlead.created). Con el formulario de contacto integrado solo se completanemailymessage,fieldses un array vacío y los identificadores del formulario sonnull. message- el campo de mensaje mapeado, o todos los valores completados unidos si el formulario no define un campo de mensaje.
custom_form.submitted
Se activa con cada envío de un formulario personalizado, independientemente de su finalidad. Ten en cuenta que los formularios destinados a la captación de leads o al contacto humano también activan su evento específico lead.created / contact_form.submitted. Suscríbete a uno u otro según si necesitas la vista genérica o la especializada, en lugar de duplicar acciones de negocio. Ambas familias de eventos tienen identificadores de evento distintos; conversationId junto con timestamp no es un identificador de envío fiable.
{
"eventId": "6c1d8e3f-2a5b-4c7d-9e0f-1a4b6c8d0e2f",
"eventType": "custom_form.submitted",
"timestamp": "2026-08-13T14:27:45Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"formCodeName": "warranty_claim",
"formName": "Warranty claim",
"fields": [
{"name": "order_number", "value": "A-10293", "type": "text"},
{"name": "issue", "value": "Damaged on arrival", "type": "textarea"},
{"name": "photo", "value": "https://api.chatlab.com/aichat/customform/download?key=...&token=...", "type": "file"}
],
"purpose": "STANDALONE"
}
}
formCodeName- el nombre técnico estable del formulario, que no cambia aunque renombres el formulario; utilízalo para enrutar los envíos en tu propio sistema.formNamees la etiqueta visible que se muestra a los visitantes.fieldsutiliza las mismas entradas{name, value, type}quelead.created: los valores de selección múltiple son arrays y los valores de archivos son enlaces de descarga.purpose-STANDALONE,LEAD_COLLECTIONoHUMAN_CONTACT, según cómo esté configurado el formulario en el chatbot.
conversation.started
Se activa cuando un visitante envía el primer mensaje de una nueva conversación.
{
"eventId": "8e2f0a4b-3c6d-4e8f-a1b2-2c5d7e9f1a3b",
"eventType": "conversation.started",
"timestamp": "2026-08-13T14:20:11Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"firstMessage": "Do you ship to Canada?",
"chatSource": "WIDGET",
"byAdmin": false,
"countryCode": "PL",
"ipAddress": "83.12.44.7"
}
}
firstMessage- el texto exacto del mensaje inicial del visitante.nullsi la conversación se abrió sin contenido de mensaje.chatSource- el canal por el que llegó la conversación:WIDGET,WHATSAPP,MESSENGER,VOICE,VOICE_PHONE,API,BOOKING,AIRBNBoIDOBOOKING.byAdmin-truecuando la conversación procede de la vista previa del chatbot dentro del panel de administración de ChatLab y no de un visitante real. Utilízalo para excluir tus propias pruebas de tu CRM.countryCode- código de país ISO determinado a partir de la dirección IP del visitante,nullcuando no se pudo determinar.ipAddress- la dirección IP del visitante detectada por ChatLab,nullcuando no esté disponible. Debe tratarse como dato personal según el RGPD y almacenarse solo si cuentas con una base legal para ello.
conversation.rated
Se activa cuando un visitante envía una valoración positiva o negativa de la conversación (consulta Valoración de conversaciones).
{
"eventId": "1b4c6d8e-5f0a-4b2c-8d3e-4f7a9b1c3d5e",
"eventType": "conversation.rated",
"timestamp": "2026-08-13T14:31:09Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"rating": "POSITIVE"
}
}
rating-POSITIVEoNEGATIVE. Al borrar una valoración no se activa el evento, por lo que nunca recibirás un valor neutro.
conversation.summarized
Se activa cuando ChatLab genera un resumen de una conversación finalizada.
{
"eventId": "4d7e9f1a-6b2c-4d4e-9f0a-5b8c0d2e4f6a",
"eventType": "conversation.summarized",
"timestamp": "2026-08-13T14:45:00Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"summary": "Visitor asked about shipping to Canada and delivery times. The bot confirmed availability and quoted 5-7 business days. Visitor left satisfied.",
"language": "en_US"
}
}
summary- el texto del resumen generado. La generación de resúmenes es asíncrona y depende de la configuración de resúmenes del bot y de la cola de procesamiento; no asumas un tiempo de entrega fijo.language- la configuración regional interna del bot enviada para el resumen, por ejemploen_US; no asumas que coincide con el idioma de la conversación del visitante.
client.summarized
Se activa cuando ChatLab actualiza el perfil de IA de un cliente. El perfil se reconstruye a partir del perfil anterior y del resumen de la conversación recién finalizada, y puede generarse después de conversation.summarized. El orden de entrega no está garantizado. La carga útil incluye un correo electrónico cuando se conoce, pero ChatLab también puede almacenar clientes sin correo electrónico.
{
"eventId": "b5d8f1a3-7c2e-4d9b-a6f0-1e3c5a7b9d2f",
"eventType": "client.summarized",
"timestamp": "2026-08-18T09:12:04Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"clientEmail": "jane.doe@example.com",
"client": {
"email": "jane.doe@example.com",
"name": "Jane Doe",
"phone": "+1 555 0123",
"countryCode": "PL",
"ipAddress": "83.12.44.7"
},
"clientSummary": "Returning customer interested in international shipping. Asked about delivery times to Canada twice and about return costs once."
}
}
clientEmail- el identificador para vincular al cliente con tu propio CRM. Esnullpara visitantes anónimos que nunca dejaron una dirección, y el evento se activa igualmente para ellos; omite estas entregas si tu integración depende del correo electrónico.client- el registro de contacto que ChatLab guarda de esta persona:email,name,phone,countryCodeeipAddress. Cada clave está siempre presente; los valores desconocidos sonnull.clientSummary- el texto completo del perfil en texto plano, no una diferencia. Reemplaza el resumen anterior por completo, por lo que debes guardarlo sobrescribiendo en lugar de añadirlo al final.- El perfil solo se reconstruye para bots con la memoria del chat activada, y únicamente para conversaciones que hayan estado inactivas el tiempo suficiente para generar el resumen; este evento suele llegar unos minutos después de terminar la conversación, no de forma inmediata.
live_chat.requested
Se activa cuando la IA transfiere la conversación a live chat, ya sea porque el visitante solicitó hablar con una persona o porque el bot determinó que era necesaria la intervención humana.
{
"eventId": "7a0b2c4d-8e3f-4a5b-b0c1-6d9e1f3a5b7c",
"eventType": "live_chat.requested",
"timestamp": "2026-08-13T14:33:20Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"requestedBy": "AI"
}
}
requestedBy- actualmente siempre esAI, ya que la transferencia siempre la inicia la acción de live chat del bot, incluso cuando el visitante la pide directamente con sus propias palabras. Trátalo como un enumerado abierto: gestiona valores desconocidos en lugar de validar estrictamente soloAI.- Este evento cubre la acción de la IA al solicitar la transferencia, no todas las formas en las que un visitante puede abrir el chat en vivo. No confirma que un operador se haya conectado.
live_chat.started
Se activa cuando se crea la sesión de live chat tras enviar el formulario de transferencia del visitante. Esto ocurre antes de que un operador necesariamente se una o responda; no lo consideres una confirmación de atención humana.
{
"eventId": "0c3d5e7f-9a4b-4c6d-a1b2-7e0f2a4b6c8d",
"eventType": "live_chat.started",
"timestamp": "2026-08-13T14:33:55Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {}
}
dataestá vacío de forma intencionada. Todo lo que necesitas está en el sobre:botIdidentifica el chatbot yconversationId/sessionIdvinculan el evento a la conversación. Puedes recibirlo sin unlive_chat.requestedprevio, por ejemplo, si el visitante utilizó el control de chat en vivo del widget.
live_chat.ended
Se activa cuando finaliza la sesión de live chat.
{
"eventId": "2e5f7a9b-0c5d-4e7f-b2c3-8f1a3b5c7d9e",
"eventType": "live_chat.ended",
"timestamp": "2026-08-13T14:52:41Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"durationSeconds": 1126
}
}
durationSeconds- duración transcurrida de la sesión de live chat, contada desde la creación de la sesión, incluido el tiempo de espera de un operador. Este campo se omite en el caso excepcional de que una sesión finalice sin haberse iniciado nunca.
ai_action.executed
Se activa cada vez que el bot ejecuta una acción de IA: una llamada de integración gestionada o una función de API personalizada. Este es un evento de alto volumen: un bot de e-commerce activo puede ejecutar cientos de acciones al día, y una sola intervención del visitante puede activar varias. Suscríbete a él en un endpoint dedicado o asegúrate de que tu receptor pueda procesar ese volumen.
{
"eventId": "5f8a0b2c-1d6e-4f8a-c3d4-9a2b4c6d8e0f",
"eventType": "ai_action.executed",
"timestamp": "2026-08-13T14:21:03Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"actionName": "search_products",
"status": "SUCCESS",
"durationMs": 842,
"errorMessage": null
}
}
actionName- el nombre de la acción ejecutada tal como lo ve la IA, por ejemplosearch_productspara una integración gestionada o el nombre que hayas asignado a una acción de API personalizada.status-SUCCESSoERROR.durationMs- el tiempo que tardó la acción, en milisegundos. Resulta útil para detectar integraciones lentas antes de que los visitantes se quejen.errorMessage- el motivo del fallo, completado solo cuandostatusesERROR;nullen caso contrario.
webhook.test
Se envía mediante el botón Send sample event (Enviar evento de prueba) al realizar una comprobación básica de conectividad. Se firma exactamente igual que un evento real.
{
"eventId": "9b2c4d6e-3f8a-4b0c-d5e6-0b3c5d7e9f1a",
"eventType": "webhook.test",
"timestamp": "2026-08-13T14:10:00Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"message": "Test delivery from ChatLab"
}
}
message- texto fijo, siempre idéntico. Los campos del sobre contienen valores de muestra, por lo que nunca debes procesar una entrega dewebhook.testcomo datos reales.- Es el único tipo de evento al que no puedes suscribirte en un endpoint: se envía bajo demanda desde el panel de administración y siempre llega al endpoint seleccionado, independientemente de los eventos que este escuche.
Seguridad: verificación de entregas
Cada entrega incluye cuatro encabezados:
| Encabezado | Valor |
|---|---|
X-ChatLab-Signature |
sha256=<hex hmac> - firma HMAC-SHA256 de la carga útil |
X-ChatLab-Timestamp |
Marca de tiempo Unix en segundos de cuando se firmó la entrega |
X-ChatLab-Event |
El tipo de evento, p. ej. lead.created |
X-ChatLab-Delivery |
ID único de entrega, idéntico al eventId del cuerpo |
La firma se calcula como un HMAC-SHA256 sobre la cadena {timestamp}.{rawBody} utilizando el secreto de tu endpoint, donde {timestamp} es el valor de X-ChatLab-Timestamp y {rawBody} es el cuerpo de la solicitud en formato sin procesar (raw). Verifica siempre contra los bytes sin procesar: volver a serializar un JSON ya analizado modificará la secuencia de bytes e invalidará la firma.
Para protegerte contra ataques de repetición, rechaza las entregas cuyo encabezado X-ChatLab-Timestamp tenga más de 5 minutos de antigüedad.
Node.js
const crypto = require('crypto');
function verifyChatLabSignature(req, secret) {
const signature = req.headers['x-chatlab-signature'];
const timestamp = req.headers['x-chatlab-timestamp'];
if (typeof signature !== 'string' || typeof timestamp !== 'string') return false;
if (!/^\d+$/.test(timestamp) || !Number.isSafeInteger(Number(timestamp))) return false;
if (!Buffer.isBuffer(req.rawBody)) return false;
// Reject stale deliveries (older than 5 minutes)
const ageSeconds = Math.abs(Date.now() / 1000 - Number(timestamp));
if (ageSeconds > 300) return false;
// rawBody must be the raw request body bytes, not re-serialized JSON.
// With Express: app.use(express.json({ verify: (req, res, buf) => { req.rawBody = buf; } }))
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(timestamp + '.')
.update(req.rawBody)
.digest('hex');
const a = Buffer.from(signature);
const b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
PHP
<?php
function verifyChatLabSignature(string $secret): bool
{
$signature = $_SERVER['HTTP_X_CHATLAB_SIGNATURE'] ?? '';
$timestamp = $_SERVER['HTTP_X_CHATLAB_TIMESTAMP'] ?? '';
if ($signature === '' || $timestamp === '' || !ctype_digit($timestamp)) {
return false;
}
// Reject stale deliveries (older than 5 minutes)
if (abs(time() - (int) $timestamp) > 300) {
return false;
}
$rawBody = file_get_contents('php://input');
$expected = 'sha256=' . hash_hmac('sha256', $timestamp . '.' . $rawBody, $secret);
return hash_equals($expected, $signature);
}
Si la verificación falla, responde con 401 y descarta la carga útil. Nunca proceses entregas no verificadas: cualquiera que descubra tu URL podría enviarle peticiones POST con JSON arbitrario.
Comportamiento de entrega
Ten en cuenta estas reglas de entrega antes de empezar a trabajar con webhooks:
- Responde rápido. Tu endpoint debe responder en un plazo de 3 segundos o la entrega se considerará fallida. Verifica la firma, añade el evento a la cola de forma persistente y confirma con un código
2xxdentro de ese margen. Ejecuta las llamadas al CRM y los procesos de negocio más lentos de forma asíncrona. - Disparo único sin reintentos (at-most-once). Los endpoints activos que coincidan reciben como máximo un intento de entrega - no hay reintentos. Los endpoints pausados y los circuitos abiertos pueden llegar a suprimir incluso ese intento. Si tu endpoint está caído, agota el tiempo de espera o devuelve un estado que no sea 2xx, ese evento se pierde y no volverá a enviarse. Los webhooks son notificaciones, no un almacén de datos replicado: usa los endpoints de conversación de Bot Talk API o las exportaciones de leads para conciliar los datos retenidos siempre que sea posible. Management API cubre la configuración del bot y los datos de uso, no un archivo completo de eventos. Algunos eventos no se pueden reconstruir a través de estas interfaces.
- Disyuntor (circuit breaker). Tras 5 entregas fallidas consecutivas para un par de endpoint/bot, las entregas para ese par se pausan durante 5 minutos. Los eventos que ocurran durante la pausa se descartan y el registro de entregas mostrará entradas
CIRCUIT_OPENpara identificar los intentos suprimidos. Las entregas omitidas por un circuito abierto no cuentan para la desactivación automática. - Desactivación automática. La comprobación se ejecuta en el momento exacto en que falla una entrega, nunca mediante un temporizador. Si una entrega falla y no ha habido ninguna entrega correcta durante 7 días - calculados desde el último envío correcto, o desde la fecha de creación del endpoint si nunca ha tenido éxito - el endpoint se desactiva y recibes una notificación por correo electrónico. Una sola respuesta
2xxen cualquier momento reinicia ese contador. Un endpoint que no recibe tráfico nunca se desactiva, porque no se produce ningún fallo. Vuelve a activarlo desde Account settings (Ajustes de la cuenta) una vez que tu receptor esté arreglado; el contador de fallos y la marca de desactivación automática se restablecen al volver a activarlo, y los eventos perdidos mientras estaba apagado no se vuelven a procesar. - 410 Gone. Si tu endpoint responde con el estado HTTP
410 Gone, ChatLab lo desactiva de inmediato. Utiliza esto para retirar un endpoint mediante programación desde el lado receptor. - Idempotencia. No se prevén entregas duplicadas en condiciones normales de funcionamiento, pero si tu procesamiento debe ser estrictamente idempotente, elimina duplicados usando
eventId(también disponible en la cabeceraX-ChatLab-Delivery).
No se garantiza el orden de entrega. Almacena el ID del evento y haz que el procesamiento de tu lógica de negocio sea idempotente. Mantén tus propias políticas de retención y control de acceso para las cargas útiles de los webhooks, que pueden contener datos personales y enlaces de descarga de archivos.
Los ejemplos de firma utilizan Node.js crypto y la función hash_equals de PHP. Captura el cuerpo sin procesar de la solicitud (raw request body) antes de parsearlo.
Límites
- Hasta 10 endpoints de webhook por cuenta.
- Retención del registro de entregas: 14 días. Las entradas más antiguas se eliminan automáticamente.
Artículos relacionados
- Captación de leads - el formulario detrás de
lead.created - Formulario de contacto de soporte humano - el formulario detrás de
contact_form.submitted - Live Chat - el flujo detrás de los eventos
live_chat.* - Valoración de conversaciones - los votos positivos/negativos detrás de
conversation.rated - AI Actions - las integraciones detrás de
ai_action.executed - Chat API - callbacks del widget en el navegador (contraparte del lado del cliente para webhooks)
- Management API - API REST para la gestión de bots y datos de uso