Skip to main content

Estructura de Payloads

Cada evento tiene una estructura de payload específica. Esta página documenta los más importantes.

message.received

El payload de message.received usa una estructura híbrida: el campo message contiene el mensaje exactamente como lo envía Meta, más IDs propios de Whaapy y extras de valor agregado.

Campos Base

Estos campos siempre están presentes:
CampoTipoDescripción
whaapy_message_idstringID interno del mensaje en Whaapy
conversation_idstringID de la conversación en Whaapy
contact_idstringID del contacto en Whaapy
messageobjectMensaje original de Meta (estructura idéntica a la API de Meta)
contact_namestringNombre del contacto (si está disponible)

Campos Extras (Valor Agregado)

Estos campos aparecen según el tipo de mensaje:
CampoTipoCuándo apareceDescripción
media_urlstringimage, video, audio, document, stickerURL con token (24h) para descargar media
transcriptionstringaudioTexto transcrito de la nota de voz
¿Por qué estructura híbrida? El campo message usa exactamente el formato de Meta, permitiéndote reutilizar código existente. Los extras de Whaapy (media_url, transcription) te ahorran llamadas adicionales a la API.

Ejemplos por Tipo de Mensaje

{
  "event": "message.received",
  "timestamp": "2025-01-15T10:30:00.000Z",
  "businessId": "uuid",
  "data": {
    "whaapy_message_id": "msg-uuid",
    "conversation_id": "conv-uuid",
    "contact_id": "contact-uuid",
    "message": {
      "from": "5215512345678",
      "id": "wamid.HBgNNTIxNTUxMjM0NTY3OA==",
      "timestamp": "1705312200",
      "type": "text",
      "text": {
        "body": "Hola, necesito ayuda"
      }
    },
    "contact_name": "Juan Pérez"
  }
}

Sobre media_url vs message.*.id

message.image.id (Meta)

ID de media de Meta. Requiere llamada adicional a su API para obtener la URL de descarga.

media_url (Whaapy)

URL lista para descargar con token incluido. Sin llamadas adicionales.
Limitaciones:
  • Token válido: 24 horas
  • Expiración de media: WhatsApp elimina media después de 30 días
Para referencia del formato Meta, consulta la documentación oficial.

message.sent

Cuando tu negocio envía un mensaje (manual o por IA).
{
  "event": "message.sent",
  "timestamp": "2025-01-15T10:31:00.000Z",
  "businessId": "uuid",
  "data": {
    "message_id": "msg-uuid",
    "conversation_id": "conv-uuid",
    "to": "+5215512345678",
    "contact_name": "Juan Pérez",
    "type": "text",
    "content": "¡Hola! ¿En qué puedo ayudarte?",
    "sent_by_ai": true,
    "timestamp": "2025-01-15T10:31:00.000Z",
    "provider": "meta"
  }
}
CampoTipoDescripción
message_idstringID del mensaje en Whaapy
conversation_idstringID de la conversación
tostringNúmero de destino
typestringTipo de mensaje (text, image, template, etc.)
contentstringContenido del mensaje
sent_by_aibooleantrue si fue enviado por el agente de IA

conversation.created

Cuando se inicia una nueva conversación.
{
  "event": "conversation.created",
  "timestamp": "2025-01-15T10:30:00.000Z",
  "businessId": "uuid",
  "data": {
    "conversation_id": "conv-uuid",
    "contact_id": "contact-uuid",
    "phone_number": "+5215512345678",
    "contact_name": "Juan Pérez",
    "timestamp": "2025-01-15T10:30:00.000Z"
  }
}

conversation.assigned

Cuando una conversación se asigna a un agente humano.
{
  "event": "conversation.assigned",
  "timestamp": "2025-01-15T10:32:00.000Z",
  "businessId": "uuid",
  "data": {
    "conversation_id": "conv-uuid",
    "phone_number": "+5215512345678",
    "contact_name": "Juan Pérez",
    "assigned_to": "agent-uuid",
    "assigned_by": "admin-uuid",
    "method": "manual",
    "timestamp": "2025-01-15T10:32:00.000Z"
  }
}
CampoTipoDescripción
assigned_tostringUUID del agente asignado
assigned_bystringUUID de quien asignó
methodstringmanual o auto

broadcast.completed

Cuando un envío masivo termina.
{
  "event": "broadcast.completed",
  "timestamp": "2025-01-15T11:00:00.000Z",
  "businessId": "uuid",
  "data": {
    "broadcast_id": "bc-uuid",
    "name": "Promoción Enero",
    "total_recipients": 500,
    "sent_count": 495,
    "failed_count": 5,
    "success_rate": 99,
    "completed_at": "2025-01-15T11:00:00.000Z"
  }
}

message.delivered

Cuando WhatsApp confirma que el mensaje fue entregado al dispositivo del usuario.
{
  "event": "message.delivered",
  "timestamp": "2026-01-15T10:31:05.000Z",
  "businessId": "uuid",
  "data": {
    "message_id": "msg-uuid",
    "wamid": "wamid.HBgNNTIxNTUxMjM0NTY3OA==",
    "conversation_id": "conv-uuid",
    "to": "+5215512345678",
    "contact_name": "Juan Pérez",
    "status": "delivered",
    "timestamp": "2026-01-15T10:31:05.000Z"
  }
}
CampoTipoDescripción
message_idstringID del mensaje en Whaapy
wamidstringID del mensaje en WhatsApp
statusstringSiempre delivered

message.read

Cuando el usuario abre y lee el mensaje (doble check azul).
{
  "event": "message.read",
  "timestamp": "2026-01-15T10:35:00.000Z",
  "businessId": "uuid",
  "data": {
    "message_id": "msg-uuid",
    "wamid": "wamid.HBgNNTIxNTUxMjM0NTY3OA==",
    "conversation_id": "conv-uuid",
    "to": "+5215512345678",
    "contact_name": "Juan Pérez",
    "status": "read",
    "timestamp": "2026-01-15T10:35:00.000Z"
  }
}
El evento message.read solo se recibe si el usuario tiene habilitada la confirmación de lectura en WhatsApp.

message.failed

Cuando un mensaje no se pudo enviar.
{
  "event": "message.failed",
  "timestamp": "2026-01-15T10:31:00.000Z",
  "businessId": "uuid",
  "data": {
    "message_id": "msg-uuid",
    "conversation_id": "conv-uuid",
    "to": "+5215512345678",
    "contact_name": "Juan Pérez",
    "status": "failed",
    "error": {
      "code": "131047",
      "title": "Re-engagement message",
      "message": "La ventana de conversación de 24 horas ha expirado",
      "details": "More than 24 hours have passed since the customer last replied"
    },
    "timestamp": "2026-01-15T10:31:00.000Z"
  }
}
CampoTipoDescripción
error.codestringCódigo de error de WhatsApp
error.titlestringTítulo corto del error
error.messagestringDescripción del error en español
error.detailsstringDetalles técnicos (en inglés)
Los códigos de error más comunes son 131047 (ventana cerrada), 131051 (número no válido), y 131026 (usuario bloqueó el número).

conversation.unassigned

Cuando una conversación es desasignada de un agente.
{
  "event": "conversation.unassigned",
  "timestamp": "2026-01-15T11:00:00.000Z",
  "businessId": "uuid",
  "data": {
    "conversation_id": "conv-uuid",
    "phone_number": "+5215512345678",
    "contact_name": "Juan Pérez",
    "previous_agent": "agent-uuid",
    "unassigned_by": "admin-uuid",
    "reason": "manual",
    "timestamp": "2026-01-15T11:00:00.000Z"
  }
}
CampoTipoDescripción
previous_agentstringUUID del agente que tenía la conversación
unassigned_bystringUUID de quien desasignó (null si fue automático)
reasonstringmanual, timeout, o reassigned

conversation.closed

Cuando una conversación es marcada como cerrada.
{
  "event": "conversation.closed",
  "timestamp": "2026-01-15T12:00:00.000Z",
  "businessId": "uuid",
  "data": {
    "conversation_id": "conv-uuid",
    "phone_number": "+5215512345678",
    "contact_name": "Juan Pérez",
    "closed_by": "agent-uuid",
    "reason": "resolved",
    "duration_minutes": 45,
    "message_count": 12,
    "timestamp": "2026-01-15T12:00:00.000Z"
  }
}
CampoTipoDescripción
closed_bystringUUID de quien cerró (null si fue automático)
reasonstringresolved, spam, timeout, manual
duration_minutesnumberDuración total de la conversación
message_countnumberNúmero total de mensajes

contact.created

Cuando se crea un nuevo contacto (primera vez que alguien escribe).
{
  "event": "contact.created",
  "timestamp": "2026-01-15T10:30:00.000Z",
  "businessId": "uuid",
  "data": {
    "contact_id": "contact-uuid",
    "phone_number": "+5215512345678",
    "name": "Juan Pérez",
    "wa_id": "5215512345678",
    "source": "inbound_message",
    "timestamp": "2026-01-15T10:30:00.000Z"
  }
}
CampoTipoDescripción
sourcestringinbound_message, import, manual

contact.updated

Cuando se actualizan los datos de un contacto.
{
  "event": "contact.updated",
  "timestamp": "2026-01-15T14:00:00.000Z",
  "businessId": "uuid",
  "data": {
    "contact_id": "contact-uuid",
    "phone_number": "+5215512345678",
    "name": "Juan Carlos Pérez",
    "previous_name": "Juan Pérez",
    "updated_by": "agent-uuid",
    "updated_fields": ["name", "email", "tags"],
    "timestamp": "2026-01-15T14:00:00.000Z"
  }
}
CampoTipoDescripción
updated_bystringUUID de quien actualizó
updated_fieldsstring[]Lista de campos modificados
previous_namestringNombre anterior (si cambió)

contact.deleted

Cuando se elimina un contacto.
{
  "event": "contact.deleted",
  "timestamp": "2026-01-15T15:00:00.000Z",
  "businessId": "uuid",
  "data": {
    "contact_id": "contact-uuid",
    "phone_number": "+5215512345678",
    "name": "Juan Pérez",
    "deleted_by": "admin-uuid",
    "reason": "gdpr_request",
    "timestamp": "2026-01-15T15:00:00.000Z"
  }
}
CampoTipoDescripción
deleted_bystringUUID de quien eliminó
reasonstringgdpr_request, spam, manual, cleanup
Al eliminar un contacto, también se eliminan todas sus conversaciones y mensajes. Esta acción es irreversible.

broadcast.sent

Cuando un broadcast comienza a enviarse.
{
  "event": "broadcast.sent",
  "timestamp": "2026-01-15T10:00:00.000Z",
  "businessId": "uuid",
  "data": {
    "broadcast_id": "bc-uuid",
    "name": "Promoción Enero",
    "template_name": "promo_enero_2026",
    "total_recipients": 500,
    "started_at": "2026-01-15T10:00:00.000Z",
    "created_by": "admin-uuid"
  }
}
CampoTipoDescripción
template_namestringNombre del template usado
total_recipientsnumberNúmero de destinatarios
created_bystringUUID de quien creó el broadcast

broadcast.failed

Cuando un broadcast falla antes de completarse.
{
  "event": "broadcast.failed",
  "timestamp": "2026-01-15T10:05:00.000Z",
  "businessId": "uuid",
  "data": {
    "broadcast_id": "bc-uuid",
    "name": "Promoción Enero",
    "template_name": "promo_enero_2026",
    "total_recipients": 500,
    "sent_count": 150,
    "failed_count": 350,
    "error": {
      "code": "rate_limit_exceeded",
      "message": "Se excedió el límite de mensajes por minuto"
    },
    "failed_at": "2026-01-15T10:05:00.000Z"
  }
}
CampoTipoDescripción
sent_countnumberMensajes enviados antes del fallo
failed_countnumberMensajes que no se enviaron
error.codestringCódigo de error
error.messagestringDescripción del error
Si un broadcast falla parcialmente, los mensajes ya enviados no se revierten. Puedes crear un nuevo broadcast con los contactos pendientes.

Próximos Pasos