Webhooks
Los webhooks permiten que Your AI Connector notifique automáticamente a sus otras herramientas empresariales siempre que ocurra algo importante: la creación de un nuevo contacto, la reserva de una cita o la recepción de un mensaje. En lugar de comprobar manualmente si hay actualizaciones, sus sistemas conectados reciben una notificación instantánea en el momento en que sucede algo.
¿Qué son los webhooks?
Piense en un webhook como un mensaje de texto automático entre dos aplicaciones. Cuando ocurre algo en Your AI Connector (como el registro de un nuevo contacto), la plataforma envía instantáneamente una notificación a otro sistema de su elección. Usted proporciona una dirección web (llamada “URL de webhook”) a la que deben enviarse estas notificaciones; normalmente, esta la proporciona su CRM, plataforma de automatización o desarrollador.
La página de Webhooks solo envía datos FUERA de Your AI Connector. Los webhooks configurados aquí son unidireccionales, desde Your AI Connector hacia tus otras herramientas. Para traer un nuevo cliente potencial u otros datos (desde un formulario web, tu CRM o GoHighLevel), tienes dos opciones. Una Automatización con el activador Webhook te proporciona una dirección web a la que tu formulario o herramienta puede enviar datos, y sus pasos pueden luego crear el contacto, enviar un mensaje y más. O bien, tu sistema realiza una llamada a la API, por ejemplo, la operación Crear un contacto, utilizando tu clave de API; consulta Acceso a la API y Embudos.
Los webhooks solo forman parte de algunos planes. Si su plan no incluye webhooks, la página de Webhooks no estará disponible y no se enviará ningún evento. Todo lo que haya guardado anteriormente permanecerá en su cuenta y comenzará a enviarse de nuevo tan pronto como cambie a un plan que incluya webhooks. Las funciones de su plan aparecen en su página de facturación, y su proveedor puede indicarle a qué plan debe cambiarse.
Nota: La configuración de webhooks implica cierta configuración técnica. Si no se siente cómodo con esto, comparta esta página con su desarrollador o utilice una plataforma de automatización como Zapier, Make o Pabbly, que proporcionan URL de webhook sin necesidad de programación.
Los usos comunes incluyen:
- Sincronizar nuevos contactos con su CRM.
- Activar un flujo de trabajo en Zapier, Make o Pabbly cuando se aplica una etiqueta.
- Notificar a su equipo en Slack cuando se alerta a un humano.
- Actualizar su sistema de calendario cuando se reserva una cita.
- Registrar resúmenes de conversaciones en su base de datos.
Configuración de webhooks
- En la barra lateral izquierda, haga clic en Configuración (icono de engranaje).
- En la barra lateral de Configuración, bajo el grupo Integraciones, haga clic en Webhooks.
En una cuenta sin webhooks configurados todavía, la página se ve así:
- Haz clic en New webhook, en la parte superior derecha. Se abrirá un formulario en la misma página:
- Rellene:
- URL del endpoint: la dirección web a la que Your AI Connector enviará las notificaciones de eventos. La obtendrá de su sistema externo (CRM, plataforma de automatización o servidor personalizado).
- Nombre: una etiqueta que reconocerá más adelante (p. ej., “Alertas de Slack” o “Sincronización con CRM”). Solo para su referencia.
Su URL de webhook debe ser una dirección
https://alcanzable públicamente. Las direccioneshttp://simples,localhosto las direcciones de red privada y las direcciones internas de la plataforma se rechazan al guardar. Para realizar pruebas desde su propia máquina, utilice un túnel público (webhook.site o ngrok) en lugar de localhost.
- En Eventos, haz clic en los eventos que quieres que reciba este webhook: los 24 se enumeran en Los 24 eventos de webhook.
- (Opcional) Activa Reintentar entregas fallidas si quieres que Your AI Connector siga intentándolo ante un fallo temporal; consulta Reintentar entregas fallidas.
- Haz clic en Crear webhook. Aparecerá en la lista debajo del formulario y podrás hacer clic en Probar en su fila en cualquier momento para enviar una carga útil de muestra a tu endpoint.
Permiso necesario. Agregar, editar o probar webhooks requiere el permiso de “edición” de Integraciones (los miembros del equipo con acceso de solo lectura verán un aviso de solo lectura en lugar del formulario).
Firmar un webhook requiere que ya esté guardado primero; abra la fila de un webhook existente para editarlo y el panel Secreto de firma aparecerá en la parte inferior del formulario de edición. Un borrador nuevo y sin guardar aún no tiene opción de firma; consulte Cargas útiles firmadas a continuación.
Un webhook para todas sus cuentas de cliente (Agencias)
Si usted dirige una agencia, no tiene que volver a crear el mismo webhook en cada cuenta de cliente. En la cuenta de agencia, el formulario de webhook tiene un interruptor adicional: Disparar también para todas las cuentas de cliente. Actívelo y este webhook también recibirá los eventos que ocurran en todas las cuentas de cliente bajo su agencia: un solo endpoint, toda la agencia.
Cómo funciona:
- El bloque
userle indica a qué cliente pertenece un evento. Cada notificación ya incluye un bloqueuserque identifica la cuenta en la que ocurrió el evento, por lo que su automatización puede realizar el enrutamiento por cliente. - La configuración de su webhook se aplica en todas partes. Los eventos que seleccionó, el secreto de firma y la configuración de reintento también se utilizan para las entregas de las cuentas de cliente.
- Sin entregas duplicadas. Si una cuenta de cliente tiene su propio webhook apuntando a la misma URL, ese se utilizará para los eventos de dicha cuenta en su lugar; el mismo evento nunca llega dos veces al mismo endpoint.
- Los clientes no lo ven. El webhook no aparece en la página de Webhooks de la cuenta del cliente y los clientes no pueden desactivarlo; es usted quien lo gestiona.
- La fiabilidad se rastrea por cuenta de cliente. Si su endpoint sigue fallando, se desactivará automáticamente para la cuenta cuyas entregas fallaron (consulte Fiabilidad de Webhooks), no para toda la agencia a la vez.
El interruptor solo aparece en cuentas de agencia. También se admite su configuración a través de la API; consulte el campo apply_to_sub_accounts en la API de Webhooks.
Eventos de activación disponibles
Puedes habilitar o deshabilitar cada uno de los 24 eventos de webhook de forma independiente. Cuando se dispara un evento, Your AI Connector envía una notificación a tu URL de webhook con los datos relevantes. Cada evento, su significado y el código event que coloca en la carga útil se enumeran juntos en Los 24 eventos de webhook más abajo en esta página.
Es bueno saberlo: Tarea creada, Tarea actualizada y Tarea completada son totalmente seleccionables y se guardan correctamente. Resumen diario creado también es una incorporación reciente. Consulta Webhook de tarea completada más abajo para ver la estructura de esa carga útil.
Activadores de webhook basados en etiquetas
subscribed_to_tags no limita los eventos de un webhook a una etiqueta. Solo restringe qué etiquetas generan una notificación de resumen de conversación. Para recibir una solicitud cuando se aplica una etiqueta específica, configure una URL de webhook en esa etiqueta en la pestaña Etiquetas del editor de agentes.
El formulario de webhook en sí no tiene un selector de etiquetas, ni al crear un nuevo webhook ni al editar uno, por lo que subscribed_to_tags solo se puede leer o cambiar a través de la API de Webhooks o solicitándolo al equipo de soporte.
Es bueno saberlo: editar un webhook existente que tiene una lista
subscribed_to_tags(cambiarle el nombre, cambiar sus eventos, activar/desactivar reintentos) ya no borra esa lista; dado que el formulario no tiene un selector de etiquetas para enviar de vuelta, guardar desde esta página ahora deja la lista existente intacta. (Esto era un error real antes del 21 de julio de 2026: guardar desde el formulario de webhook solía borrar la lista porque siempre enviaba una lista de etiquetas vacía. Si un webhook perdió su listasubscribed_to_tagsantes de esa fecha, deberá reconfigurarse a través de la API).
Generar resumen para contactos etiquetados
Cuando un webhook tiene una lista subscribed_to_tags, puedes activar Generar resumen. Cuando está habilitado, Your AI Connector genera automáticamente un resumen de la conversación para el contacto cuando se aplica una de esas etiquetas y lo incluye en los datos del webhook: contexto completo sin necesidad de una solicitud separada.
Prueba de su webhook
- Abra Configuración → Integraciones → Webhooks.
- En la fila de su webhook, haga clic en Probar.
- Verifique su sistema externo para confirmar que recibió los datos de prueba.
- Revise el formato de los datos para asegurarse de que su sistema pueda analizarlos correctamente.
Para una prueba completa de extremo a extremo, envíe un mensaje que active uno de sus eventos configurados (una difusión o un mensaje entrante en un canal conectado) y verifique que el webhook se active con los datos reales.
Consejo: Utilice una herramienta como webhook.site o RequestBin durante el desarrollo para inspeccionar los datos brutos del webhook antes de conectar su sistema de producción.
Qué se considera una entrega exitosa
Tanto si haces clic en Test como si el evento se dispara de forma real, enviamos lo mismo:
- Una solicitud POST (nunca GET), con el cuerpo en formato JSON y
Content-Type: application/json. - Los encabezados enumerados en Cargas útiles firmadas. Los encabezados de firma solo se incluyen una vez que hayas configurado un secreto de firma.
Consideramos que la entrega es exitosa cuando:
- Tu endpoint responde con cualquier estado 2xx (200, 201, 204: todos son válidos).
- Responde en un plazo de 30 segundos.
Algunas cosas que sorprenden a los usuarios:
- El cuerpo de la respuesta se ignora. No es necesario que devuelva ningún JSON en particular. Un 200 vacío es suficiente.
- Las redirecciones cuentan como un error. No las seguimos, por lo que un 301 o 302 (incluida una redirección de barra diagonal final, o de http a https) se registra como una entrega fallida. Guarde la URL final, no una que redirija.
- Las cadenas de consulta son totalmente compatibles.
https://your-app.com/hook?token=abc123se envía exactamente como la guardó, por lo que incluir un token en la cadena de consulta funciona igual de bien que ponerlo en la ruta. - Su URL debe ser
https://y estar disponible públicamente. Las direcciones que pertenecen a la propia infraestructura de Your AI Connector son rechazadas, pero sus propios puntos de conexión en Google Cloud Functions, Cloud Run, App Engine, Firebase Hosting o cualquier otro lugar están bien. - Un firewall o una capa de protección contra bots frente a su punto de conexión puede bloquearnos. El caso más común es Cloudflare: si su zona tiene activado el modo Bot Fight o un desafío gestionado, nuestra solicitud recibe una página de desafío “Just a moment…” con un 403 en lugar de llegar a su servidor; y una solicitud de servidor a servidor nunca puede superar un desafío de navegador, por lo que tanto el botón Probar como los eventos reales fallan de la misma manera. El botón Probar le indicará cuándo sucede esto (“Cloudflare está mostrando un desafío de bot a nuestra solicitud”). Soluciónelo en Cloudflare con una regla de Seguridad / WAF que omita los desafíos para su ruta de webhook (o para el agente de usuario
Webhook-Delivery/1.0), luego haga clic en Probar nuevamente. - Si su firewall necesita una lista de permitidos de IP en su lugar (por ejemplo, el plan gratuito de Cloudflare, donde el modo Bot Fight simple no se puede omitir mediante una regla WAF, pero una regla de acceso IP configurada en Permitir se ejecuta antes), podemos ayudarle: cada entrega, ya sea desde el botón Probar o un evento en vivo, se envía desde una dirección IPv4 fija (sin rangos, sin IPv6, sin rotación). Comuníquese con el soporte y le daremos la dirección para incluir en la lista de permitidos. Mantenga la verificación de firma como su comprobación de confianza real, ya que valida cada carga útil independientemente de dónde provenga.
- El resultado de la prueba le indica exactamente lo que respondió su punto de conexión. Una prueba fallida ahora muestra la razón real (el estado HTTP que devolvió su punto de conexión, un tiempo de espera o que no pudimos llegar a la dirección en absoluto) en lugar de un error genérico, y una prueba en un webhook guardado se envía firmada cuando la firma está activada, exactamente igual que un evento en vivo.
Uso de n8n, Make o Zapier (“URL de prueba” vs “URL de producción”)
Las plataformas de automatización suelen ofrecerte dos direcciones de webhook diferentes, y esto suele confundir a los usuarios:
- Una URL de prueba (en n8n contiene
/webhook-test/). Esta solo recibe datos mientras observa activamente el lienzo y acaba de hacer clic en Escuchar evento de prueba (o Probar flujo de trabajo). Captura un solo evento y luego deja de escuchar, por lo que hacer clic en Probar en Your AI Connector varias veces seguidas solo captura el primero, y solo si la ventana de escucha está activa en ese preciso momento. Para probar: primero haga clic en Escuchar evento de prueba en n8n, luego regrese a Your AI Connector y haga clic en Probar una vez. - Una URL de producción (en n8n contiene
/webhook/, sin-test). Esta es la que debe pegar en Your AI Connector para eventos en vivo. Solo funciona una vez que su flujo de trabajo se cambia a Activo. Si el flujo de trabajo no está activo, n8n rechaza la solicitud con un error “404 / webhook no registrado”, aunque Your AI Connector haya enviado los datos correctamente.
En resumen: prueba con la URL de prueba mientras escuchas, pero para que el webhook siga funcionando con contactos reales, guarda la URL de producción en Your AI Connector y asegúrate de que el flujo de trabajo esté Active.
Formato de datos del webhook
Cuando se dispara un webhook, Your AI Connector envía datos estructurados (JSON) a su URL de webhook. Si utiliza una plataforma de automatización como Zapier o Make, esta analiza los datos automáticamente por usted. Si está creando una integración personalizada:
{
"event": "contactCreated",
"contact": { "id": "<contact-id>", "first_name": "Jane", "...": "..." },
"campaign": { "id": "<campaign-id>", "name": "AI Receptionist", "status": "Live" },
"agent": { "id": "<agent-id>", "name": "Front Desk" },
"user": { "id": "<account-id>", "email": "owner@example.com" }
}
| Campo | Descripción |
|---|---|
event |
La cadena exacta del evento que activó la notificación (por ejemplo, contactCreated, booked). Esta no es la etiqueta de visualización que se muestra en la lista de eventos; cada etiqueta y su código correspondiente se encuentran en Los 24 eventos de webhook. |
contact |
El contacto al que se refiere el evento, o null para eventos que no están vinculados a un contacto (como creditsRecharged). |
campaign |
La campaña clásica a la que pertenece el contacto, o null si no hay ninguna. Los contactos gestionados por un agente llegan con null aquí. |
agent |
El agente que gestiona la conversación, o null si no hay ninguno. |
user |
Información básica de identidad de la cuenta propietaria de los datos. |
Lea
agent, nocampaign. Las campañas se han trasladado a Agentes de IA y Difusiones (consulte Las campañas se han trasladado), por lo que sus contactos están con un agente yagentle indica cuál gestionó la conversación. El campocampaigntodavía se envía para que los receptores antiguos sigan funcionando, pero generalmente esnull; solo se completa para un contacto que todavía tiene un enlace a una campaña clásica. No asuma quecampaignsiempre está presente.
El bloque
agentllegó el 15 de agosto de 2026. Se sitúa junto acampaignen los eventos vinculados a una conversación (un chat finalizado, no molestar, una reanudación, una desarchivación, una pausa de IA, un mensaje nuevo, un resumen de conversación y el webhook que puedes configurar en una etiqueta) y contiene elidynamedel agente encargado, onullcuando no hay ningún agente involucrado. Es puramente aditivo: todos los campos que ya recibes permanecen sin cambios, por lo que cualquier receptor que hayas creado antes de esa fecha seguirá funcionando sin necesidad de actualizaciones.
Algunos eventos añaden su propio bloque adicional de nivel superior. Por ejemplo, Cita reservada, Cita cancelada y Cita reprogramada añaden un bloque appointment (consulta Webhook de cita reservada), Nuevo mensaje añade un bloque message completo con el texto (consulta Webhook de nuevo mensaje), y Entregas y Lecturas añaden un bloque message corto solo con el ID y el estado del mensaje (consulta Webhook de entregas y lecturas).
Las Entregas y Lecturas te indican qué mensaje es, pero no qué decía. Contienen un bloque
messagecon elidy elstatusdel mensaje — y eseides el mismomessageIdque devuelve el endpoint de envío de mensajes, por lo que puedes hacer coincidir un recibo de entrega o lectura con el mensaje exacto que enviaste —, pero no el cuerpo del mensaje. Respuestas (Replies) no contiene ningún bloquemessage. Si necesitas las palabras que se enviaron o recibieron, suscríbete a Nuevo mensaje junto con ellos.
Dos cosas que debe saber antes de escribir su receptor. No hay un campo
timestampni un contenedordata. Cada bloque se encuentra en el nivel superior del objeto JSON, como se muestra arriba.
Los 24 eventos de webhook
Los 24 eventos de webhook, con la etiqueta de visualización que marcas en la aplicación y el código event enviado en la carga útil. El código event es una cadena corta que no coincide con la etiqueta de visualización, así que configura tu receptor basándote en el código, no en la etiqueta:
| Etiqueta de visualización (en la aplicación) | Código event en la carga útil |
Qué significa |
|---|---|---|
| Contacto creado | contactCreated |
Se añade un nuevo contacto a tu cuenta (manualmente, mediante importación o vía API). |
| Contacto pausado | contact_paused |
Se pausa una conversación con un contacto (el bot deja de responder). |
| Contacto reanudado | contact_resumed |
Se reanuda una conversación pausada con un contacto. |
| Contacto no molestar | contact_do_not_disturb_changed |
Se activa la configuración de “No molestar” de un contacto. |
| Contacto desarchivado | contact_unarchived |
Un contacto archivado envía un mensaje nuevo, lo que lo devuelve a tu bandeja de entrada activa. |
| Nuevo mensaje | new_message |
Se añade cualquier mensaje a una conversación en cualquier canal, tanto los mensajes que tu contacto te envía como los que tu IA o tu equipo le envían a él. Este es el único evento que contiene el texto real del mensaje (consulta Webhook de nuevo mensaje). |
| Respuestas | replied |
Un contacto responde a un mensaje. |
| Lecturas | read |
Un contacto lee un mensaje (en canales que admiten confirmaciones de lectura). Contiene el ID del mensaje que se leyó; consulta Webhook de entregas y lecturas. |
| Entregas | delivered o undelivered |
Un mensaje se entrega correctamente a un contacto (undelivered cuando la entrega falla). Contiene el ID del mensaje; consulta Webhook de entregas y lecturas. |
| Alerta humana | humanAlerted |
El bot de IA determina que no puede gestionar una conversación y la marca para que un humano la atienda. |
| Chat concluido | chat_concluded |
El bot de IA decide que una conversación ha llegado a su fin (reserva realizada, cliente potencial descalificado, etc.). |
| Cita reservada | booked |
Un contacto reserva una cita a través del sistema de reservas. |
| Cita cancelada | appointment_cancelled |
Una cita se cancela: por la IA en un chat, por ti en la aplicación, a través de la API o en el Google Calendar conectado. Mismo cuerpo que Cita reservada, con appointment.cancelation_reason. Consulta Webhooks de cita cancelada y reprogramada. |
| Cita reprogramada | appointment_rescheduled |
Una cita se mueve a una nueva hora, desde cualquiera de los mismos lugares. Mismo cuerpo que Cita reservada más un bloque previous con la hora de inicio y fin anterior. |
| Créditos gastados | creditsSpent |
Se deducen créditos de tu cuenta. |
| Créditos recargados | creditsRecharged |
Se añaden créditos a tu cuenta mediante recarga automática o compra manual. |
| Saldo de crédito bajo | lowCreditBalance en una entrega de Prueba, Low Credit Balance en una real |
Una advertencia temprana de que tu saldo de crédito ha caído por debajo de tu umbral de alerta (100 créditos a menos que establezcas el tuyo propio). Dirigido a agencias, cuyas subcuentas gastan todas de un mismo fondo. Contiene balance, threshold y account_email en lugar de un bloque de contacto, se envía como máximo una vez cada 24 horas mientras el saldo permanezca bajo, y se reactiva tan pronto como el saldo vuelve a estar por encima del umbral. |
| Tarea creada | taskCreated |
Se crea una tarea. |
| Tarea actualizada | taskUpdated |
Una tarea cambia sin pasar a una etapa de finalización. |
| Tarea completada | taskCompleted |
Una tarea pasa a una etapa configurada como etapa de finalización. |
| Resumen diario creado | dailySummaryCreated |
Se genera tu informe de resumen diario. |
| Canal conectado | channelConnected |
Aún no se envía: se puede seleccionar, pero hoy en día nada lo emite. No construyas nada basado en esto. Destinado a cuando un canal de mensajería termina de conectarse. |
| Difusión iniciada | broadcastStarted |
Una difusión comienza a enviarse (su estado cambia a Enviando). Se dispara una vez por inicio, incluso cuando se reanuda una difusión pausada. Contiene un bloque broadcast en lugar de un bloque de contacto: id, nombre, canal, estado, estado anterior, la lista a la que se dirige (list_id, list_name, is_smart_list), scheduled_at, total_contacts. |
| Difusión completada | broadcastCompleted |
Una difusión finaliza (su estado cambia a Enviado o Fallido). Mismo bloque broadcast más completed_at y, cuando está disponible, completion_summary (total_sent, permanently_failed, unique_replied, failure_rate, had_errors). Usa estos dos para conectar una lista de difusión inteligente a herramientas externas. |
Nunca aparecen dos códigos más en esa lista porque no te suscribes a ellos: contact_tags_updated, enviado por una URL de webhook configurada en una etiqueta individual, y summary_generated, enviado cuando se escribe un resumen de chat para una etiqueta en la lista subscribed_to_tags de un webhook.
Canal conectado aún no se envía. Aparece en la lista de eventos, pero actualmente nada lo emite. No desarrolle basándose en él.
Las notificaciones basadas en etiquetas y tareas utilizan sus propias formas separadas. Consulte Etiquetas de contacto actualizadas y Tarea completada.
Webhook de contacto creado
Se envía cuando se activa el evento Contacto creado (se agrega un nuevo contacto manualmente, mediante importación o mediante API).
Nombre del evento
contactCreated
Formato de carga útil
{
"event": "contactCreated",
"contact": {
"id": "<contact-id>",
"email": "jane@example.com",
"phone_number": "+15551234567",
"first_name": "Jane",
"last_name": "Smith",
"human_alerted": false,
"human_alert_reason": null,
"is_bot_active": true,
"ad_referral": null,
"ad_attribution": null
},
"campaign": {
"id": "<campaign-id>",
"name": "AI Receptionist",
"status": "Live"
},
"agent": {
"id": "<agent-id>",
"name": "Front Desk"
},
"user": {
"id": "<account-id>",
"email": "owner@example.com",
"first_name": "Alex",
"last_name": "Doe"
}
}
| Campo | Descripción |
|---|---|
event |
Siempre contactCreated para este evento. |
contact.id |
El ID único del nuevo contacto. |
contact.email / contact.phone_number |
El correo electrónico y teléfono del contacto, si se conocen (cualquiera de los dos puede estar vacío dependiendo del canal). |
contact.first_name / contact.last_name |
El nombre del contacto, si se conoce. |
contact.human_alerted / contact.human_alert_reason |
Si el contacto está marcado para atención humana y por qué. |
contact.is_bot_active |
Si el bot de IA está activo actualmente en este contacto. |
contact.ad_referral |
El anuncio de Meta del que proviene el contacto (Click-to-WhatsApp, Click-to-Instagram o Click-to-Messenger), o null. Consulte Atribución de anuncios Click-to-WhatsApp. |
contact.ad_attribution |
El clic en el anuncio de su sitio web con el que se relacionó este contacto, o null. Consulte Atribución de clics en anuncios para WhatsApp. |
campaign |
La campaña clásica bajo la cual se creó el contacto, o null (el valor habitual ahora que los contactos son gestionados por agentes). |
agent |
El agente asignado al contacto, o null. |
user |
Información básica de identidad de la cuenta a la que pertenece el contacto. |
La muestra de “Prueba” y un evento real se ven ligeramente diferentes. El botón de prueba envía datos de marcador de posición (John Doe, un bloque de campaña de muestra). Un evento real de Contacto Creado lleva los detalles reales del contacto, y algunos campos pueden estar vacíos dependiendo del canal.
Webhook de nuevo mensaje
Este webhook se activa cada vez que se añade un mensaje a una conversación, en cualquier canal. Cubre ambas direcciones: los mensajes que su contacto le envía a usted, y los mensajes que su agente de IA, su equipo o una difusión les envía a ellos. Es el único webhook que incluye el texto del mensaje, por lo que es el que debe usar cuando desee reflejar las conversaciones en un sistema externo.
Nombre del evento
new_message
Formato de carga útil
{
"event": "new_message",
"contact": {
"id": "<contact-id>",
"email": "jane@example.com",
"phone_number": "+15551234567",
"first_name": "Jane",
"last_name": "Smith",
"human_alerted": false,
"human_alert_reason": null,
"is_bot_active": true,
"ad_referral": null,
"ad_attribution": null
},
"agent": {
"id": "<agent-id>",
"name": "Front Desk"
},
"user": {
"id": "<account-id>",
"email": "owner@example.com",
"first_name": "Alex",
"last_name": "Doe"
},
"message": {
"id": "<message-id>",
"body": "Hi, are you open on Saturday?",
"direction": "inbound",
"status": "received",
"created_at": "2026-07-30T17:27:06.000Z",
"channel": "whatsapp_web",
"media_url": null,
"media_content_type": null
}
}
| Campo | Descripción |
|---|---|
event |
Siempre new_message para este evento. Tenga en cuenta que esta es la cadena exacta enviada; no es la etiqueta de visualización “Nuevo mensaje”. |
contact |
El contacto a cuya conversación pertenece el mensaje. Tiene la misma forma que en Contacto Creado. |
agent |
El agente que gestiona la conversación (id y name), o null si no hay ningún agente involucrado. |
user |
Información básica de identidad de la cuenta propietaria de la conversación. |
message.id |
El ID único del mensaje. |
message.body |
El texto del mensaje. Para un mensaje con un archivo adjunto, el cuerpo comienza con una nota entre corchetes de lo que llegó, seguida de cualquier leyenda, por ejemplo [THE CONTACT UPLOADED AN IMAGE] Here is my CV, [THE CONTACT UPLOADED A DOCUMENT] o [THE CONTACT UPLOADED A VOICE NOTE] - [TRANSCRIPTION: ...]. Las notas de voz y los videos incluyen la transcripción. |
message.direction |
inbound para un mensaje del contacto, outbound para uno enviado por su IA o por su equipo desde la bandeja de entrada, y outbound-api para uno enviado por una difusión (incluida una campaña clásica), un envío de plantilla o la API. |
message.status |
Dónde se encuentra el mensaje en su ciclo de vida: received para entrante, y queued / sent / delivered / read / failed / undelivered para saliente. Este es el estado en el momento en que se creó el mensaje, por lo que un mensaje saliente generalmente llega aquí como queued o sent y llega a delivered después; utilice los eventos de Entregas y Lecturas si necesita esas transiciones posteriores. Llevan el mismo message.id que este bloque, por lo que puede hacer coincidir la transición con este mensaje (consulte Webhook de Entregas y Lecturas). |
message.created_at |
Cuándo se creó el mensaje, en UTC (ISO 8601). |
message.channel |
El canal por el que pasó el mensaje, por ejemplo whatsapp, whatsapp_web, sms, instagram, messenger, telegram, email o custom. |
message.media_url |
Un enlace de descarga para el archivo adjunto al mensaje (imagen, nota de voz, video o documento), o null cuando no hay ninguno. Siempre presente. |
message.media_content_type |
El tipo de archivo, por ejemplo image/jpeg, audio/ogg o application/pdf. null siempre que media_url sea null. |
Todavía no hay un bloque
campaignen esta carga útil. Nuevo mensaje envíacontact,agent,userymessage. El bloqueagentse añadió el 15 de agosto de 2026 y le indica qué agente gestiona la conversación; si necesita más contexto sobre el contacto, búsquelo a través de la API usandocontact.id.
Guarde los archivos adjuntos poco después de que lleguen. El enlace
media_urldeja de funcionar 7 días después de que llegó el mensaje, en todos los canales (WhatsApp Business API, WhatsApp Web, Instagram, Messenger, Telegram, widget de chat y el resto); el archivo en sí permanece. Para obtener un enlace nuevo más tarde, llame a Descargar el archivo adjunto de un mensaje concontacts/{contact.id}/messages/{message.id}. Los campos se agregaron el 13 de septiembre de 2026.
Cuando
media_urlesnullpero el cuerpo indica que llegó un archivo. Algunos archivos adjuntos se almacenan de una manera que no tiene un enlace directo, y una mención compartida de un reel, publicación o historia de Instagram es un enlace a Instagram, no un archivo, por lo que también llegan comonull(el cuerpo nombra lo que se compartió). Para un archivo, llame a Download a message’s attachment con el ID del mensaje para obtener un enlace.
El historial importado no activa este webhook. Cuando un número de WhatsApp Web importa sus conversaciones anteriores, esos mensajes antiguos se guardan sin una notificación de Nuevo mensaje por cada uno.
Los registros internos de la IA no activan este webhook. Junto con los mensajes reales, la plataforma mantiene sus propias filas de contabilidad en una conversación (las llamadas a herramientas de la IA y los registros de turnos internos). Estos nunca se envían; solo recibirá los mensajes que fueron realmente enviados o recibidos.
Webhook de Entregas y Lecturas
Estos dos eventos informan de lo que le sucedió a un mensaje después de salir de Your AI Connector: Entregas se dispara cuando un mensaje llega al contacto (o no logra hacerlo), y Lecturas se dispara cuando el contacto lo abre, en los canales que admiten recibos de lectura.
Ambos contienen un bloque message con el ID del mensaje al que se refiere el evento, para que puedas hacer coincidir la actualización con el mensaje exacto que enviaste.
Nombres de eventos
delivered y undelivered para Entregas, read para Lecturas.
Formato de carga útil
{
"event": "delivered",
"contact": {
"id": "<contact-id>",
"email": "jane@example.com",
"phone_number": "+15551234567",
"first_name": "Jane",
"last_name": "Smith",
"ad_referral": null,
"ad_attribution": null
},
"campaign": {
"id": "<campaign-id>",
"name": "AI Receptionist",
"status": "Live"
},
"agent": {
"id": "<agent-id>",
"name": "Front Desk"
},
"user": {
"id": "<account-id>",
"email": "owner@example.com",
"first_name": "Alex",
"last_name": "Doe"
},
"message": {
"id": "<message-id>",
"status": "delivered"
}
}
| Campo | Descripción |
|---|---|
event |
delivered o undelivered para Entregas, read para Lecturas. |
contact |
El contacto al que se envió el mensaje. |
campaign |
La campaña clásica a la que pertenece el contacto, o null (el valor habitual ahora que los contactos son gestionados por agentes). |
agent |
El agente que gestiona la conversación, o null. |
user |
Información básica de identidad de la cuenta propietaria de los datos. |
message.id |
El ID del mensaje sobre el que trata esta actualización. Es el mismo valor que devuelve el punto final de enviar mensaje como messageId, y el mismo message.id que lleva una notificación de Nuevo mensaje. |
message.status |
El nuevo estado, siempre la misma cadena que event (delivered, undelivered o read). |
Cómo hacer coincidir una actualización con el mensaje que enviaste. Almacena el
messageIdque recibes al enviar un mensaje a través de la API. Cuando llegue una notificación de Entregas o Lecturas, busca ese ID almacenado enmessage.iddentro del payload; ese es tu recibo de entrega o lectura para ese mensaje exacto.
Aquí no hay texto de mensaje. El bloque
messagesolo contiene el ID y el estado. Suscríbete a Nuevo mensaje si también necesitas el cuerpo.
El bloque
messagesolo está presente cuando sabemos de qué mensaje se trataba. En la rara actualización que no podemos vincular a un mensaje almacenado, el bloque se omite por completo en lugar de enviarse vacío; así que verifica quemessageexista antes de leermessage.id.
Una notificación por cambio de estado. Un solo mensaje saliente normalmente produce una notificación de
deliveredy luego, en canales con recibos de lectura, una deread. Un envío fallido produceundelivereden su lugar.
Webhook de cita reservada
Se activa cuando un contacto reserva una cita. Se activa de la misma manera tanto si la IA la reservó durante una conversación, como si usted la reservó manualmente o si llegó a través de la API.
Nombre del evento
booked
Formato de carga útil
{
"event": "booked",
"contact": {
"id": "<contact-id>",
"email": "jane@example.com",
"phone_number": "+15551234567",
"first_name": "Jane",
"last_name": "Smith"
},
"campaign": {
"id": "<campaign-id>",
"name": "AI Receptionist",
"status": "Live"
},
"user": {
"id": "<account-id>",
"email": "owner@example.com"
},
"appointment": {
"appointment_id": "<appointment-id>",
"start_time": "2026-07-20T15:00:00.000Z",
"end_time": "2026-07-20T15:30:00.000Z",
"status": "Confirmed",
"room_name": "Room 1",
"description": "Discovery call",
"summary": "30 min intro",
"google_calendar_event_id": null,
"external_reference": "crm-booking-1042",
"event": {
"id": "<service-id>",
"event_name": "Intro Call",
"slot_duration": 30,
"location": "Zoom",
"meeting_link": "https://...",
"event_type": "online"
}
}
}
| Campo | Descripción |
|---|---|
event |
Siempre booked para este evento. |
contact |
La persona que realizó la reserva. email y phone_number pueden estar vacíos dependiendo del canal. |
appointment.appointment_id |
El ID único de la reserva. |
appointment.start_time / end_time |
Inicio y fin del espacio reservado, en UTC (ISO 8601). |
appointment.status |
El estado actual de la reserva. |
appointment.room_name |
La sala en la que se realizó la reserva, si se utiliza. |
appointment.description / summary |
Detalles de texto libre capturados con la reserva. |
appointment.google_calendar_event_id |
ID de Google Calendar para el evento sincronizado. A menudo es null en el webhook de Reserva de Cita, porque el evento del calendario se crea en el mismo momento en que se envía la notificación; vuelva a obtener la cita mediante su appointment_id un momento después si lo necesita, y espere un null permanente en cuentas sin Google Calendar conectado. |
appointment.external_reference |
El ID de su propio sistema con el que se creó la reserva a través de la API, o null. |
appointment.event |
El servicio que se reservó: nombre, duración del espacio, ubicación, enlace de reunión, tipo. |
google_calendar_event_idsuele sernullen este webhook, y eso es normal. El evento de Google Calendar se crea en el mismo momento en que sale esta notificación, por lo que el ID generalmente aún no está listo. Vuelva a obtener la cita por suappointment_idun momento después si lo necesita. Permanece comonullpermanentemente si la cuenta no tiene Google Calendar conectado, así que no espere por él indefinidamente.
El botón “Probar” envía un bloque
appointmentde muestra con valores ficticios, para que puedas desarrollar basándote en la estructura antes de que llegue una reserva real.
Dos casos en los que este webhook no se activa: citas importadas desde un calendario externo y reservas que provienen de la integración con Formitable.
Webhooks de cita cancelada y reprogramada
Cita cancelada se dispara cuando se cancela una cita, y Cita reprogramada se dispara cuando se mueve a una nueva hora de inicio o fin. Ambos se disparan de la misma manera, ya sea que la IA lo haya hecho durante una conversación, tú lo hayas cambiado en la aplicación, haya llegado a través de la API o alguien haya cambiado el evento en el Google Calendar conectado.
Nombres de eventos
appointment_cancelled y appointment_rescheduled
Formato de carga útil
El cuerpo es el mismo que en Cita reservada, con la cita tal como queda después del cambio. Una cancelación añade appointment.cancelation_reason; una reprogramación añade un bloque previous de nivel superior con las horas anteriores:
{
"event": "appointment_rescheduled",
"contact": { "id": "<contact-id>", "email": "jane@example.com", "phone_number": "+15551234567", "first_name": "Jane", "last_name": "Smith" },
"campaign": null,
"agent": { "id": "<agent-id>", "name": "Front desk" },
"user": { "id": "<account-id>", "email": "owner@example.com" },
"appointment": {
"appointment_id": "<appointment-id>",
"start_time": "2026-07-21T09:00:00.000Z",
"end_time": "2026-07-21T09:30:00.000Z",
"status": "Confirmed",
"room_name": "Room 1",
"description": "Discovery call",
"summary": "30 min intro",
"google_calendar_event_id": "<calendar-event-id>",
"external_reference": "crm-booking-1042",
"cancelation_reason": null,
"event": { "id": "<service-id>", "event_name": "Intro Call", "slot_duration": 30 }
},
"previous": {
"start_time": "2026-07-20T15:00:00.000Z",
"end_time": "2026-07-20T15:30:00.000Z"
}
}
| Campo | Descripción |
|---|---|
event |
appointment_cancelled o appointment_rescheduled. |
appointment.status |
Canceled en una cancelación (un l, el valor que devuelve la API), Confirmed en una reprogramación. |
appointment.cancelation_reason |
El motivo indicado cuando se canceló la cita, o null. |
appointment.start_time / end_time |
La franja horaria después del cambio, en UTC (ISO 8601). |
previous.start_time / previous.end_time |
Solo reprogramación: la franja horaria desde la que se movió la cita. |
campaign / agent |
La campaña y el agente actuales del contacto, o null. |
Un cambio, un evento. Cancelar una cita envía solo Cita cancelada, incluso si su hora cambió en la misma edición. Editar solo el título, las notas o la sala no envía ninguno. Mover la misma cita dos veces envía dos eventos de Cita reprogramada.
Webhook de Conversación Concluida
Se activa cuando la IA decide que una conversación ha llegado a su fin (una reserva realizada, un cliente potencial descalificado, etc.).
Nombre del evento
chat_concluded
Formato de carga útil
La carga útil lleva event, el contact completo, el agent que gestionó el chat y la cuenta user. También lleva conversation_cost, lo que costó esta conversación en créditos, para que un flujo de n8n o Make pueda registrarlo sin una segunda llamada:
{
"event": "chat_concluded",
"contact": { "id": "abc123", "first_name": "Jane", "channel": "whatsapp" },
"agent": { "id": "agent_1", "name": "Sales Agent" },
"user": { "id": "user_1" },
"conversation_cost": {
"credits": 7.5,
"session_id": "sess_9f2",
"started_at": "2026-09-26T09:14:02.000Z",
"outcome": "contained"
}
}
credits: créditos cargados dentro de esta conversación, reembolsos descontados. Se cuenta de la misma manera que el informe de costos de conversación en la API.outcome:contained(la IA lo gestionó sola),handed_off(alguien de su equipo respondió después de la IA, o la IA alertó a un humano) ono_ai.conversation_costse omite cuando la cifra no se puede calcular en ese momento. Trátelo como opcional.
Webhook de actualización de etiquetas de contacto
Se activa cuando se aplica una etiqueta a un contacto, y esa etiqueta tiene una URL de webhook configurada en el agente al que está asignado el contacto.
Nombre del evento
contact_tags_updated
Cuándo se activa
- Se aplica una etiqueta a un contacto que tiene asignado un agente de IA.
- Al menos una de las etiquetas aplicadas tiene una URL de webhook configurada en la pestaña Etiquetas del editor de ese agente.
Un contacto que todavía conserva un enlace a una campaña clásica de antes del cambio a agentes es un caso especial: si las etiquetas de esa campaña tienen URLs de webhook, se utilizan esas; de lo contrario, se utilizan las del agente.
Si se aplican varias etiquetas con diferentes URL de webhook en la misma actualización, se envía una solicitud por cada URL, conteniendo cada una solo las etiquetas que corresponden a esa URL.
Eliminar una etiqueta nunca envía una solicitud. La mayoría de las personas dirigen estas URL a una acción (cobrar un depósito, reservar un espacio, alertar a un representante), por lo que una etiqueta que se elimina de un contacto solía volver a ejecutar esa acción. Ya no puede hacerlo. Una eliminación sigue apareciendo en removed_tags cuando ocurre en la misma actualización que una aplicación que va a la misma URL, por lo que una automatización que lee ambas matrices mantiene la imagen completa; lo que nunca verá es una solicitud causada únicamente por una eliminación. (Cambiado el 12 de agosto de 2026. Antes de esa fecha, las eliminaciones también enviaban una solicitud).
Formato de carga útil
{
"event": "contact_tags_updated",
"contact": {
"id": "<contact-id>",
"email": "jane@example.com",
"phone_number": "+15551234567",
"first_name": "Jane",
"last_name": "Smith",
"human_alerted": false,
"is_bot_active": true,
"ad_referral": {
"ctwa_clid": "ARAbc123...",
"source_id": "120210000000000",
"source_type": "ad",
"source_url": "https://fb.me/xxxx",
"headline": "Get 20% off today",
"body": "Message us now to claim your discount",
"channel": "whatsapp"
},
"ad_attribution": null
},
"added_tags": ["qualified-lead"],
"removed_tags": ["new-lead"],
"agent": {
"id": "<agent-id>",
"name": "Front Desk"
},
"user": {
"email": "owner@example.com",
"first_name": "Alex",
"last_name": "Doe"
}
}
| Campo | Descripción |
|---|---|
event |
Siempre contact_tags_updated para este webhook. |
contact.id |
El ID único del contacto cuyas etiquetas cambiaron. |
contact.email / contact.phone_number |
El correo electrónico/teléfono del contacto, si se conocen. |
contact.first_name / contact.last_name |
El nombre del contacto. |
contact.human_alerted |
Si el contacto está marcado actualmente para atención humana. |
contact.is_bot_active |
Si el bot de IA está activo actualmente en la conversación de este contacto. |
contact.ad_referral |
Presente solo cuando el contacto le contactó a través de un anuncio de Meta (Click-to-WhatsApp, Click-to-Instagram o Click-to-Messenger) o una referencia de publicación de WhatsApp. null en caso contrario. Consulte Atribución de anuncios Click-to-WhatsApp. |
contact.ad_attribution |
Presente solo cuando el contacto se relacionó con un clic en un anuncio que llevó a su sitio web, registrado por el script de clics en anuncios. null en caso contrario. |
added_tags |
Matriz de nombres de etiquetas aplicadas en esta actualización. Nunca vacía: una aplicación es lo que activa la solicitud. |
removed_tags |
Matriz de nombres de etiquetas eliminadas en la misma actualización, si las hay. Una eliminación por sí sola no envía nada. |
agent |
El agente que gestiona la conversación del contacto (id y name), o null si no hay ningún agente involucrado. Añadido el 15 de agosto de 2026. |
user |
Información básica de identidad de la cuenta a la que pertenece el contacto. |
Probar un webhook de etiqueta
Junto al campo de URL del webhook en la pestaña Etiquetas, hay un botón Probar. Envía una carga útil de muestra a esa URL inmediatamente, para que pueda confirmar que su automatización la recibe antes de esperar a una conversación real.
La prueba envía la misma forma de contact_tags_updated que se muestra arriba, utilizando un contacto de marcador de posición, con la etiqueta que está probando en added_tags y un removed_tags vacío. Lo que su automatización ve en la prueba es lo que verá en producción.
Dos cosas que debe saber:
- Guarda la etiqueta primero. La prueba busca la etiqueta por su nombre guardado, por lo que una etiqueta nueva o un cambio de nombre no guardado aún no se pueden probar. El botón permanece desactivado hasta que el nombre en pantalla coincida con el guardado.
- Una prueba fallida no cuenta en contra de tu webhook. Las pruebas nunca contribuyen al apagado automático tras fallos repetidos descrito en Fiabilidad del webhook.
Si la prueba falla, el mensaje le indica lo que respondió su punto final (por ejemplo, un 404 o un 500), lo cual suele ser suficiente para detectar una URL incorrecta o un flujo de trabajo que no está activado.
Webhook de tarea completada
Solo como referencia. Los webhooks de tareas (como datos) están documentados aquí para desarrolladores; los eventos Tarea creada, Tarea actualizada y Tarea completada se pueden seleccionar en la lista de eventos estándar en el formulario de webhook como cualquier otro evento; consulta Eventos de activación disponibles y Los 24 eventos de webhook.
Esta carga útil se envía cuando una tarea pasa a una etapa marcada como etapa de finalización. Una tarea que se mueve entre etapas que no son de finalización envía el formato taskUpdated en su lugar.
Nombre del evento
taskCompleted
Cuándo se activa
- Se actualiza una tarea.
- Su valor
stagecambió en comparación con su valor anterior. - La nueva etapa está configurada como una etapa de finalización en la configuración de etapas de tareas de la cuenta.
Formato de carga útil
{
"event": "taskCompleted",
"contact": {
"email": "jane@example.com",
"phone_number": "+15551234567",
"first_name": "Jane",
"last_name": "Smith",
"human_alerted": false,
"human_alert_reason": null
},
"user": {
"email": "owner@example.com",
"first_name": "Alex",
"last_name": "Doe"
},
"message": {
"id": "<task-id>",
"title": "Follow up with Jane",
"description": "Confirm pricing and send proposal",
"type": "follow_up",
"priority": "high",
"stage": "<stage-id>",
"due_date": "2026-01-20T15:00:00Z",
"source": "ai",
"source_detail": "<source-detail>",
"campaign_id": "<campaign-id>",
"linked_human_alert": "<human-alert-id>",
"tags": ["qualified-lead"],
"notes": "Customer requested a callback"
}
}
| Campo | Descripción |
|---|---|
event |
Siempre taskCompleted para este webhook. Se envía la misma estructura de carga útil que taskUpdated cuando una tarea cambia sin entrar en una etapa de finalización. |
contact |
El contacto vinculado a la tarea, si existe. null cuando no está vinculado. |
contact.human_alert_reason |
El motivo por el que se marcó el contacto para atención humana, si corresponde. |
user |
Información de identidad básica de la cuenta propietaria de la tarea. |
message.id |
El ID único de la tarea. |
message.title / description |
El título y la descripción de la tarea. |
message.type |
El tipo de tarea (por ejemplo, follow_up, call, custom). |
message.priority |
La prioridad de la tarea (low, medium, high). |
message.stage |
El ID de la etapa en la que se encuentra la tarea actualmente. |
message.due_date |
La fecha de vencimiento de la tarea, si está configurada. |
message.source |
Qué creó la tarea: manual, human_alert, ai_tool, api, automation, daily_summary, chat o chat_composer. |
message.source_detail |
Detalles adicionales sobre la fuente. |
message.campaign_id |
El ID de la campaña clásica vinculada, o null. |
message.linked_human_alert |
El ID de la alerta humana vinculada, si existe. |
message.tags |
Etiquetas aplicadas a la tarea. |
message.notes |
Notas de formato libre sobre la tarea. |
Desactivar un webhook (o eliminarlo)
Cada webhook tiene un interruptor de encendido/apagado, justo en su fila. Desactivarlo (off) detiene la recepción de eventos, pero mantiene todo lo que configuró: la URL, los eventos y cualquier secreto de firma. Vuelva a activarlo y continuará desde donde lo dejó; nada de lo que haya ocurrido mientras estaba desactivado se entregará posteriormente.
Úselo cuando desee que las entregas se detengan por un tiempo: su endpoint se está reconstruyendo, está depurando una integración ruidosa o está pausando una automatización.
Eliminar un webhook (el icono de la papelera en su fila) lo elimina definitivamente, incluido su secreto de firma. Si solo desea que las entregas se detengan, desactívelo en su lugar; la eliminación es para cuando haya terminado por completo con el endpoint.
Esto no es lo mismo que desactivar un webhook automáticamente. Si desactivamos su webhook tras fallos repetidos (consulte Fiabilidad de los Webhooks), el interruptor de arriba no lo volverá a activar. Una vez que su endpoint esté corregido, edite el webhook y guárdelo con una URL distinta (cualquier cambio de URL lo reactiva), o llame al endpoint de reactivación a través de la API, o póngase en contacto con el soporte técnico y lo reactivaremos por usted.
Cargas útiles firmadas (verificar que un webhook realmente provino de nosotros)
Cualquiera que conozca la URL de su webhook podría enviarle una solicitud falsa. Si actúa sobre los webhooks automáticamente (actualizando la facturación, creando registros en el CRM), activar la firma le permite verificar que cada solicitud provino realmente de nosotros.
La firma es opcional y está desactivada de forma predeterminada, y se activa por cada webhook desde la vista de edición de dicho webhook (abra la fila de un webhook guardado).
Activación de la firma
- Abra el webhook (Configuración → Integraciones → Webhooks → haga clic en la fila de su webhook).
- En la sección Secreto de firma, haga clic en Generar.
- Copie el secreto (comienza con
whsec_) y guárdelo en su sistema receptor. Trátelo como una contraseña.
Puede volver y revelar, copiar, rotar o desactivar el secreto en cualquier momento desde este mismo panel.
Lo que enviamos
Una vez activada la firma, cada entrega para ese webhook lleva estos dos encabezados HTTP adicionales:
| Encabezado | Significado |
|---|---|
X-Webhook-Signature |
La firma, en el formato v1=<hex>. |
X-Webhook-Timestamp |
Cuándo lo enviamos, como una marca de tiempo Unix en segundos. |
Estos tres están en cada entrega, firmada o no:
| Encabezado | Significado |
|---|---|
X-Webhook-Delivery |
Un ID único para este evento. Permanece igual en los reintentos, por lo que es sobre lo que debe realizar la deduplicación. |
X-Webhook-Attempt |
Qué intento es este (1 es el primer intento). |
X-Webhook-Event |
El nombre del evento, para que pueda enrutarlo sin leer el cuerpo. |
Cómo verificar
La firma es un HMAC-SHA256 de la cadena <timestamp>.<raw request body>, utilizando su secreto de firma como clave.
Verifique contra el cuerpo de la solicitud sin procesar: los bytes exactos que recibió. Si su framework analiza el JSON y lo vuelve a serializar antes de comprobarlo, los bytes pueden cambiar y la firma no coincidirá.
Ejemplo en Node.js:
const crypto = require("crypto");
function verify(rawBody, headers, secret) {
const timestamp = headers["x-webhook-timestamp"];
const signature = headers["x-webhook-signature"]; // "v1=<hex>"
// Reject anything older than 5 minutes so a captured request can't be replayed later.
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const expected = crypto.createHmac("sha256", secret).update(`${timestamp}.${rawBody}`).digest("hex");
return crypto.timingSafeEqual(Buffer.from(signature.replace("v1=", "")), Buffer.from(expected));
}
Ejemplo en Python:
import hashlib, hmac, time
def verify(raw_body: bytes, headers, secret: str) -> bool:
timestamp = headers["X-Webhook-Timestamp"]
signature = headers["X-Webhook-Signature"].replace("v1=", "")
# Reject anything older than 5 minutes so a captured request can't be replayed later.
if abs(time.time() - int(timestamp)) > 300:
return False
expected = hmac.new(secret.encode(), f"{timestamp}.".encode() + raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(signature, expected)
Compare las firmas con una función de tiempo constante (
timingSafeEqual/compare_digest), no con==. No cuesta nada y evita una clase sutil de ataque.
Rotación del secreto
Haga clic en Rotar para reemplazar el secreto. El cambio es inmediato: la siguiente entrega se firma únicamente con el nuevo secreto. Si su endpoint está activo, acepte tanto el secreto antiguo como el nuevo durante unos minutos mientras implementa el nuevo.
Desactivar la firma simplemente evita que se envíen los encabezados de firma.
Reintento de entregas fallidas
De forma predeterminada, una entrega que falla no se vuelve a intentar; si su sistema no está disponible en ese momento, se pierde el evento.
Active Reintentar entregas fallidas en un webhook (en el formulario de creación/edición) y seguiremos intentándolo:
| Intento | Cuándo |
|---|---|
| 1 | Inmediatamente |
| 2 | 1 minuto después |
| 3 | 5 minutos después |
| 4 | 30 minutos después |
| 5 | 2 horas después |
Eso abarca aproximadamente 2 horas y 40 minutos, por lo que un webhook puede sobrevivir a una ventana de mantenimiento o a una breve interrupción de su parte.
Qué se reintenta: problemas temporales: su servidor devuelve un error 5xx, un tiempo de espera agotado o un error de conexión.
Qué no se reintenta: si su endpoint rechaza la solicitud en sí (cualquier 4xx), no reintentamos; enviar la misma solicitud de nuevo solo produciría el mismo rechazo.
Qué eventos se reintentan: todos los eventos, desde el 24 de septiembre de 2026. Esto cubre los webhooks de etiquetas (contact_tags_updated), los tres eventos de tareas, el resumen diario, el webhook de resumen, Nuevo mensaje, Chat concluido, Contacto pausado, Contacto reanudado, Contacto en modo no molestar, Contacto desarchivado, Saldo de crédito bajo, los eventos de difusión, y los eventos de contacto y actividad: Contacto creado, Cita reservada, Humano alertado, Respuestas, Lecturas, Entregas, Créditos gastados y Créditos recargados. Antes de esa fecha, Nuevo mensaje, Chat concluido, Contacto pausado, Contacto reanudado, Contacto en modo no molestar, Contacto desarchivado y el webhook de resumen se enviaban una vez independientemente del interruptor. Cada evento lleva X-Webhook-Delivery, por lo que una regla de deduplicación los cubre a todos.
Active los reintentos solo si su endpoint es idempotente. Los reintentos significan que el mismo evento puede llegar más de una vez. Utilice el encabezado
X-Webhook-Deliverypara reconocer una repetición: permanece igual en cada intento para un mismo evento, por lo que puede ignorar de forma segura un ID que ya haya procesado.
Los reintentos interactúan con la desactivación automática tras fallos repetidos (consulte Fiabilidad de los webhooks) de la forma que usted desea: el contador de fallos cuenta una entrega completa, solo después de que se hayan agotado todos los reintentos, no cada intento individual.
Fiabilidad del Webhook
- Your AI Connector envía webhooks a través de una conexión segura (HTTPS). Asegúrese de que la dirección web que proporcione utilice HTTPS.
- Si su sistema devuelve un error, la entrega se considera fallida.
- Supervise el tiempo de actividad de su sistema receptor para evitar perder eventos.
- Para flujos de trabajo críticos, active Reintento de entregas fallidas y considere también un mecanismo de respaldo.
Los webhooks se desactivan automáticamente tras fallos repetidos. Si la URL de su webhook falla repetidamente (aproximadamente 5 errores seguidos, o 3 seguidos en caso de errores de configuración), Your AI Connector dejará de enviar eventos a esa URL automáticamente. Para reactivarlo una vez que su endpoint funcione correctamente: edite el webhook y guárdelo con una URL distinta (cualquier cambio de URL lo reactiva), o utilice el endpoint de reactivación a través de la API; guardar de nuevo con la misma URL no es suficiente. El equipo de soporte también puede reactivarlo por usted.
Solución de problemas
| Problema | Solución |
|---|---|
| El webhook no se dispara | Primero, compruebe que el webhook no esté desactivado en su fila. Luego, confirme que los eventos correctos estén seleccionados y que su URL sea accesible desde Internet. |
| El evento de prueba funciona pero los eventos reales no | Asegúrese de que el tipo de evento específico esté habilitado. Si esperaba una solicitud cuando se aplica una etiqueta, tenga en cuenta que subscribed_to_tags no limita los eventos de un webhook a una etiqueta; solo restringe qué etiquetas producen una notificación de resumen de conversación. Para obtener una solicitud cuando se aplica una etiqueta específica, configure una URL de webhook en esa etiqueta en la pestaña Etiquetas del editor del agente. Consulte Webhook de actualización de etiquetas de contacto. |
| No llega nada a n8n / Make / Zapier | Probablemente esté utilizando la URL de prueba de la plataforma, que solo escucha un único evento justo después de hacer clic en “Escuchar evento de prueba”. Para eventos en vivo, guarde la URL de producción y cambie el flujo de trabajo a Activo. |
| Recibiendo eventos duplicados | Compruebe si hay varios webhooks apuntando a la misma URL. Si Reintentar entregas fallidas está activado, se espera una repetición siempre que su punto final haya aceptado un evento pero no haya respondido a tiempo; elimine duplicados en X-Webhook-Delivery. |
| La verificación de firma siempre falla | Casi siempre se debe a que el cuerpo se volvió a serializar antes de la verificación. Verifique contra el cuerpo de la solicitud sin procesar, firme <timestamp>.<body> y confirme que está utilizando el secreto actual si lo rotó recientemente. |
| Los reintentos no ocurren | Los reintentos están desactivados a menos que se habiliten en ese webhook específico. No reintentamos respuestas 4xx. |
El bloque campaign siempre es null |
Esperado: los contactos permanecen con un agente de IA en lugar de una campaña. Lea el bloque agent en su lugar. Consulte Formato de datos de webhook. |
| Los datos están vacíos o mal formados | Verifique que su sistema receptor acepte JSON. Compruebe los registros de su servidor en busca de errores de análisis. |
| La URL del webhook devuelve errores | Pruebe su URL con una herramienta como Postman o webhook.site. |
| El webhook dejó de dispararse por completo después de una interrupción | Los fallos repetidos desactivan automáticamente un webhook. Guardar de nuevo no lo vuelve a activar: arregle su punto final y luego contacte al soporte. |
| Guardar o probar da un error de permiso | Necesita el permiso de “edición” de Integraciones. Pídale al propietario de la cuenta que se lo otorgue. |
La lista subscribed_to_tags de un webhook volvió vacía |
subscribed_to_tags no limita los eventos de un webhook a una etiqueta; solo restringe qué etiquetas producen una notificación de resumen de conversación. La edición desde el formulario de webhook ya no borra esa lista (corregido el 21 de julio de 2026). Si un webhook perdió su lista antes de esa fecha, configure subscribed_to_tags nuevamente a través de la API de Webhooks; consulte Disparadores de webhook basados en etiquetas. |
Próximos pasos
- Integración con GoHighLevel: utilice webhooks para integrar Your AI Connector con GHL.
- Acceso a la API: combine webhooks con la API para obtener automatizaciones potentes.
- Uso de etiquetas para clasificar contactos: configure etiquetas que activen sus webhooks.