Webhooks (Server)
Esta página describe lo que tu aplicación recibe en los webhooks configurados cuando Sendeasy procesa eventos de canal y mensaje.
Alcances: general y por canal
Los webhooks tienen dos alcances posibles:
- General: recibe eventos de todos los canales de la empresa. Piénsalo como el webhook "global" de la cuenta.
- Por canal específico: recibe eventos solo del canal al que está vinculado.
Ambos alcances coexisten. Para cada evento, Sendeasy dispara la unión: todos los webhooks generales activos de la empresa más el/los webhook(s) por canal de ese canal. Configura cuantos quieras de cada alcance.
Ejemplo: la empresa tiene 2 instancias de WhatsApp y 1 casilla de Email. Puedes configurar:
- 1 webhook en URL A → solo recibe eventos del WhatsApp Ventas.
- 1 webhook en URL B → solo recibe eventos del WhatsApp Soporte.
- 1 webhook en URL C → solo recibe eventos del Email Soporte.
Configura desde Configuración → Integraciones.
Flujo resumido
- Sendeasy procesa un evento de canal/mensaje.
- El payload se normaliza al contrato público.
- Sendeasy busca todos los webhooks
enabled=truevinculados al canal origen del evento. - Para cada webhook encontrado, hace
POSTa la URL configurada con el payload en el body. Si hay bearer token configurado, va en el headerAuthorization.
Payload base
| Campo | Tipo | Descripción |
|---|---|---|
event | string | nombre del evento |
channel | string | tipo de canal: "whatsapp", "email" o "sms" |
data | object | payload específico del evento |
channelId | string | number | identificador del canal — UUID (WhatsApp) o id numérico (Email/SMS) |
{
"event": "messages.upsert",
"channel": "whatsapp",
"data": {},
"channelId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Eventos por canal
WhatsApp (channel: "whatsapp" o "waba")
connection.update
{ "state": "open" }
Valores comunes: open, close.
messages.upsert / messages.set / send.message
{
"key": {
"remoteJid": "5511999999999@s.whatsapp.net",
"fromMe": false,
"id": "3EB0XXXXXX"
},
"message": { "conversation": "Hola, necesito ayuda" },
"messageTimestamp": "1634567890",
"pushName": "Cliente"
}
messages.update
{ "keyId": "3EB0XXXXXX", "fromMe": true, "status": 3 }
status: 1 (sent), 2 (delivered), 3 (read).
messages.delete
{ "id": "3EB0XXXXXX", "fromMe": false, "remoteJid": "5511999999999@s.whatsapp.net" }
call
{ "id": "CALL_ID_123", "from": "5511999999999@s.whatsapp.net", "status": "reject" }
WABA — messaging y message_status
{
"event": "message_status",
"channel": "whatsapp",
"data": { "messageId": "wamid.HBg...", "status": "read", "timestamp": "1713800010" },
"channelId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Email (channel: "email")
Disparado cuando la casilla vinculada al webhook recibe un email.
{
"event": "messaging",
"channel": "email",
"channelId": 7,
"data": {
"email": {
"direction": "inbound",
"mailbox": "soporte@empresa.com",
"from": { "email": "cliente@dominio.com", "name": "Cliente" },
"to": ["soporte@empresa.com"],
"subject": "Consulta sobre el pedido #1234",
"text": "Hola, quería saber...",
"html": "<p>...</p>",
"messageId": "<abc@dominio.com>",
"receivedAt": "2026-04-28T13:45:00.000Z"
}
}
}
SMS (channel: "sms")
Disparado cuando el número vinculado al webhook recibe un SMS.
{
"event": "messaging",
"channel": "sms",
"channelId": 15,
"data": {
"sms": {
"direction": "inbound",
"from": "+5511999999999",
"body": "Confirmar cita",
"providerPayload": { "...": "raw provider data" }
}
}
}
Buenas prácticas de consumo
- Trata el procesamiento como asíncrono e implementa retry con backoff.
- Usa idempotencia por
event+ identificadores (key.id,keyId,data.email.messageId, …). - Almacena el payload bruto para troubleshooting.
- Valida el header
Authorizationcuando esté configurado en el webhook. - Configura timeouts cortos (≤ 5s) — si Sendeasy no recibe respuesta en 5s, el webhook se considera fallido y el evento se descarta (no hay retry automático).
Dónde gestionar
Los webhooks se configuran y activan en Configuración → Integraciones en la plataforma.