# Webhook multicanal: ¿WhatsApp, email y SMS en uno solo?

> Cada respuesta de WhatsApp, email y SMS en un solo webhook JSON firmado, desde tu número, tu buzón y tu móvil. 1 handler en lugar de 3 formatos.

Source: https://unlimitedmessaging.app/es/articles/one-webhook-whatsapp-email-sms

Webhook multicanal

# Cada respuesta, en cada canal,  
_en un solo webhook._

WhatsApp desde tu número, email desde tu buzón, SMS desde tu móvil: un solo endpoint los recibe todos en el mismo sobre JSON firmado. Un handler alimenta tu bandeja, tu agente de IA o tu CRM.

[Crear una cuenta gratis](https://app.unlimitedmessaging.app)[Ver planes de pago](https://unlimitedmessaging.app/es/pricing)

La respuesta corta

## ¿Puede un solo webhook recibir WhatsApp, email y SMS?

Sí. Unlimited Messaging envía cada mensaje entrante de tu número de WhatsApp vinculado, tu buzón conectado y la SIM de tu móvil Android a una sola URL, como el mismo evento, message.received, firmado según [Standard Webhooks](https://www.standardwebhooks.com). El sobre nunca cambia; data.channel.type indica WHATSAPP, EMAIL o SMS. Los webhooks están en los planes de pago Medium y Max.

Montada con proveedores separados, la misma bandeja exige tres integraciones. La Cloud API de Meta envía JSON anidado firmado con X-Hub-Signature-256 tras una verificación hub.challenge. Twilio envía SMS y WhatsApp como parámetros form-encoded firmados con HMAC-SHA1\. SendGrid Inbound Parse envía multipart/form-data para un nombre de host cuyo MX has movido. Tres parsers, tres verificaciones de firma, tres ideas distintas de lo que es una conversación.

Aquí los canales son servicios junto a una sola API, y esa API anuncia cada mensaje igual: id, direction, content, sender, sentAt, la conversación (un chat o grupo de WhatsApp, la raíz de un hilo de email, un número SMS) y la cuenta por la que llegó. El email añade subject, html y attachments; WhatsApp añade archivos, grupos, reacciones y ediciones. Las reglas de entrega también son comunes: responder 2xx en menos de 10 segundos, 8 intentos en algo más de 3 días, deduplicar por eventId.

Las respuestas salen desde las mismas identidades. replyToMessageId responde en el mismo chat de WhatsApp o hilo de email; una respuesta SMS indica la SIM. Tus clientes ven tu número y tu dirección, nunca los de un proveedor.

Relacionado: [enviar email y WhatsApp en una sola petición a la API](https://unlimitedmessaging.app/es/articles/email-whatsapp-single-api-request) y [reunir las ventas por WhatsApp y email en una sola bandeja](https://unlimitedmessaging.app/es/articles/sales-whatsapp-email-one-inbox).

![Ilustración: dos servidores que intercambian eventos webhook.](https://unlimitedmessaging.app/_next/image?url=%2Fassets%2Farticles%2Fcovers%2Fone-webhook-whatsapp-email-sms-es.png&w=3840&q=75)

Definición
Webhook multicanal

Un único endpoint HTTP que recibe los mensajes entrantes de varios canales (WhatsApp, email, SMS) en un mismo formato, con un campo que indica el canal, para que un solo handler atienda todas las conversaciones.

También buscado como webhook de mensajería unificada, webhook omnicanal o API de bandeja omnicanal.

[Fuente: especificación Standard Webhooks↗](https://www.standardwebhooks.com)

Los eventos

## ¿Cómo es el payload del webhook multicanal?

El mismo evento message.received en cada canal. Lo que cambia es data.channel.type y algunos campos propios del canal.

1. 01  
### Común a todos los canales  
type, eventId, occurredAt; data.message con id, externalId, direction, fromMe, content, sentAt, receivedAt, sender, senderId; data.channel con type, account (id, name) y conversation (id, isGroup, address).
2. 02  
### WHATSAPP  
Archivos (mediaUrl, mediaType, mimeType), ubicaciones, respuestas citadas (replyTo), grupos (participant, conversation.participants), más message.reaction, message.edited y message.deleted.
3. 03  
### EMAIL  
subject, html (no fiable, hay que sanearlo), attachments (hasta 20 por email), conversation.id igual a la raíz del hilo y replyTo al mensaje respondido.
4. 04  
### SMS  
Solo texto. conversation.id es null, así que agrupa por sender. Mensajes recibidos después de iniciar sesión en la app Android.
5. 05  
### Alrededor de los mensajes  
message.sent y message.status siguen lo que envías en los tres canales; account.status\_changed avisa de un número, buzón o SIM que se cae.

Tres canales, un sobreJSON

```
// WhatsApp
{ "type": "message.received", "eventId": "whd_6f1c...", "occurredAt": "2026-11-09T10:00:01.000Z",
  "data": {
    "message": { "id": "msg_0e55...", "direction": "IN", "content": "Is my order ready?",
                 "sender": "+447700900123", "senderName": "Lea", "sentAt": "2026-11-09T10:00:00.000Z" },
    "channel": { "type": "WHATSAPP", "account": { "id": "acc_373b...", "name": "Support" },
                 "conversation": { "id": "447700900123@s.whatsapp.net", "isGroup": false,
                                   "address": "+447700900123" } } } }

// Email: same envelope, plus subject, html and attachments
{ "type": "message.received", "eventId": "whd_9a4f...", "occurredAt": "2026-11-09T14:05:12.000Z",
  "data": {
    "message": { "id": "msg_3f8a...", "direction": "IN", "content": "Signed quote attached.",
                 "sender": "claire@example.com", "subject": "Re: Quote #1042",
                 "html": "<p>Signed quote attached.</p>", "attachments": [ { "filename": "quote.pdf" } ] },
    "channel": { "type": "EMAIL", "account": { "id": "acc_8b2e...", "name": "sales@yourcompany.example" },
                 "conversation": { "id": "quote-1042.20261108@yourcompany.example", "isGroup": false,
                                   "address": "claire@example.com" } } } }

// SMS: text only, no conversation id
{ "type": "message.received", "eventId": "whd_2b9e...", "occurredAt": "2026-11-09T08:42:06.000Z",
  "data": {
    "message": { "id": "msg_7d2c...", "direction": "IN", "content": "Running 10 min late, sorry!",
                 "sender": "+447700900456", "sentAt": "2026-11-09T08:42:03.000Z" },
    "channel": { "type": "SMS", "account": { "id": "acc_5e8d...", "name": "Front desk SIM" },
                 "conversation": { "id": null, "isGroup": false, "address": "+447700900456" } } } }
```

Cuerpos message.received recortados, a partir del esquema publicado, uno por canal. El evento completo lleva todos los campos listados a la izquierda.

Puesta en marcha

## ¿Cómo escribir un solo handler para todos los canales?

Vincula los tres canales una vez, registra un endpoint y diferencia solo donde un canal cambia de verdad.

1. 01  
### Vincula tus canales  
Escanea un código QR para WhatsApp, conecta tu buzón por IMAP/SMTP, instala la app Android para el SMS. Cada uno se convierte en una cuenta.
2. 02  
### Registra un solo endpoint  
POST /webhooks con tu URL y tus eventTypes, o añádelo en la página Webhooks del panel. Sin accountIds cubre todas las cuentas, incluso las futuras.
3. 03  
### Verifica una vez, diferencia al final  
Una verificación de firma, un upsert por eventId, una fila en la bandeja. Solo cambia la llamada de respuesta: replyToMessageId para WhatsApp y email, la SIM para el SMS.

POST /webhookscurl

```
curl https://api.unlimitedmessaging.app/webhooks \
  -H "Authorization: Bearer $UM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/um",
    "eventTypes": ["message.received", "message.status", "account.status_changed"],
    "description": "Every reply, every channel"
  }'

# No accountIds: the endpoint covers every WhatsApp number, mailbox and SIM you have,
# including ones linked later. The response carries "secret": "whsec_..." once.
```

No existe la opción «todos los eventos»: indica los tipos que quieres. Un tipo añadido más tarde nunca se activa en los endpoints existentes; envía la lista completa con PATCH /webhooks/{id} para añadirlo.

app/api/webhooks/um/route.tsNext.js route handler

```
// app/api/webhooks/um/route.ts (Next.js App Router)
import crypto from 'node:crypto';
import { UnlimitedMessagingApiClient } from '@unlimited-messaging/sdk';

const um = new UnlimitedMessagingApiClient({ token: process.env.UM_API_KEY! });
const key = Buffer.from(process.env.UM_WEBHOOK_SECRET!.replace(/^whsec_/, ''), 'base64');

// Standard Webhooks: HMAC-SHA256 of "id.timestamp.rawBody", base64.
function verify(raw: string, id: string, ts: string, header: string) {
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
  const expected = crypto.createHmac('sha256', key).update(`${id}.${ts}.${raw}`).digest('base64');
  return header.split(' ').some((entry) => {
    const sig = entry.startsWith('v1,') ? entry.slice(3) : '';
    return sig.length === expected.length &&
      crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
  });
}

export async function POST(req: Request) {
  const raw = await req.text();
  const h = req.headers;
  if (!verify(raw, h.get('webhook-id') ?? '', h.get('webhook-timestamp') ?? '',
    h.get('webhook-signature') ?? '')) {
    return new Response('bad signature', { status: 401 });
  }

  const event = JSON.parse(raw);
  if (event.type !== 'message.received') return new Response(null, { status: 200 });

  const { message: m, channel } = event.data;
  // One inbox row, whatever the channel (upsert on eventId: delivery is at least once).
  await inbox.upsert({
    eventId: event.eventId,
    channel: channel.type,                       // WHATSAPP | EMAIL | SMS
    from: m.sender ?? m.senderId,                // +E164 or email address
    thread: channel.conversation.id ?? m.sender, // SMS has no conversation id
    subject: m.subject ?? null,
    text: m.content,
    at: m.sentAt,                                // order on this, not on arrival
  });

  const answer = await draftReply(m.content);    // your LLM call, or null for a human
  if (answer) {
    if (channel.type === 'SMS') {
      await um.messages.messageSend({
        to: { phone: m.sender },
        channels: [{ channel: 'SMS', accountId: channel.account.id }],
        text: answer,
      });
    } else {
      // WhatsApp and email: same chat or same thread, same number or mailbox.
      await um.messages.messageSend({ replyToMessageId: m.id, text: answer });
    }
  }
  return new Response(null, { status: 200 }); // within 10 s; queue slow work
}
```

inbox y draftReply son tuyos (una tabla, una llamada a un LLM). La verificación sigue el esquema Standard Webhooks documentado, igual para todos los canales.

Vibe coding

## ¿Programas con Cursor, Claude Code, Lovable o Bolt? Pega esto

Contexto suficiente para que tu editor con IA construya toda la ruta de la bandeja unificada de una vez.

Prompt para copiar

Add a unified inbox to this app with Unlimited Messaging: WhatsApp (my number), email (my mailbox) and SMS (my Android phone) all arrive on ONE webhook.

1. Create a POST route at /api/webhooks/um that reads the RAW body.
2. Verify the Standard Webhooks signature: key = base64-decode(UM_WEBHOOK_SECRET without "whsec_"); expected = base64(HMAC-SHA256(key, `${webhook-id}.${webhook-timestamp}.${rawBody}`)); accept if any space-separated entry of the webhook-signature header equals `v1,${expected}` (constant-time compare); reject timestamps more than 5 minutes off; return 401 otherwise.
3. On type "message.received", upsert one row keyed on body.eventId: channel = data.channel.type (WHATSAPP | EMAIL | SMS), from = data.message.sender ?? data.message.senderId, thread = data.channel.conversation.id ?? data.message.sender, subject = data.message.subject, text = data.message.content, at = data.message.sentAt (order on this, never on arrival).
4. Build an inbox page listing threads across channels with a channel badge.
5. Replies: install @unlimited-messaging/sdk, read UM_API_KEY from env. WhatsApp and email: `client.messages.messageSend({ replyToMessageId: data.message.id, text })`. SMS: `client.messages.messageSend({ to: { phone: sender }, channels: [{ channel: 'SMS', accountId: data.channel.account.id }], text })`.
6. Return 200 within 10 seconds; queue slow work. Put UM_API_KEY and UM_WEBHOOK_SECRET in .env and .env.example.

Docs: https://docs.unlimitedmessaging.app (Webhooks). Register with POST https://api.unlimitedmessaging.app/webhooks and eventTypes ["message.received", "message.status", "account.status_changed"].

Lo que se construye

## ¿Qué puedes construir con un solo webhook para todos los canales?

Tres proyectos que en otros sitios son tres integraciones y aquí un solo handler.

### Una bandeja de soporte multicanal

Una lista de conversaciones, una etiqueta por canal, respuestas enviadas desde tu número o tu dirección en el mismo hilo. Añade message.status para mostrar entregado y leído cuando el canal lo informa.

### Un contestador con IA

Pasa content a Claude o GPT con el historial de la conversación, devuelve la respuesta por el canal de origen y pasa a una persona ante palabras clave o dudas.

### Sincronización con el CRM

Asocia cada mensaje al contacto por teléfono o dirección de email, sea cual sea el canal, con sentAt para la cronología.

1. 01  
### Cambio de canal  
¿Sin respuesta en WhatsApp tras un día? Insiste por email o SMS; el mismo POST /message puede enviar por tres canales a la vez.
2. 02  
### Supervisión  
account.status\_changed en los tres canales te avisa cuando un número, un buzón o un móvil deja de reenviar.
3. 03  
### Flujos sin código  
Apunta el webhook a n8n, Make o Zapier y ramifica por data.channel.type.

La tabla

## Una bandeja, tres caminos: Twilio, una pila propia o Unlimited Messaging

Lo que hace falta para recibir respuestas de WhatsApp, email y SMS en el mismo código.

__Una bandeja, tres caminos: Twilio, una pila propia o Unlimited Messaging__
| [Twilio + SendGrid](https://www.twilio.com/docs/messaging/guides/webhook-request)Un proveedor, varios productos | [Meta + servicio de parsing + proveedor SMS](https://developers.facebook.com/docs/graph-api/webhooks/getting-started)Hecho a mano | Unlimited MessagingUn webhook, planes de pago                                             |                                                                      |
| --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| Formatos de payload                                                                                             | Form-encoded para SMS y WhatsApp, multipart para email                                                                            | JSON de Meta, formato del proveedor, multipart o JSON para email                          | Un solo sobre JSON                                                   |
| Verificaciones de firma                                                                                         | X-Twilio-Signature (HMAC-SHA1), más la protección propia del endpoint de parsing                                                  | X-Hub-Signature-256 para Meta, una por cada otro proveedor                                | Una sola verificación Standard Webhooks                              |
| Identidades que ven tus clientes                                                                                | Números alquilados a Twilio, un remitente de WhatsApp registrado                                                                  | Un número trasladado a la Cloud API, un número SMS alquilado                              | Tu propio número, buzón y SIM                                        |
| Configuración antes del primer mensaje                                                                          | Compra de número, registro del remitente de WhatsApp, MX                                                                          | App de Meta y portfolio comercial, MX, alquiler de número                                 | Escanear un QR, contraseña del buzón, app Android                    |
| Coste por mensaje                                                                                               | 0,0083 $ por segmento SMS recibido en EE. UU., 0,005 $ por mensaje de WhatsApp más tarifas de Meta                                | Tarifas de Meta a partir de 1.000 respuestas de servicio por número al mes, coste por SMS | Ninguno; webhooks con Medium o Max                                   |
| Estatus oficial                                                                                                 | WhatsApp Business Platform oficial                                                                                                | WhatsApp Business Platform oficial                                                        | WhatsApp mediante el protocolo no oficial de dispositivos vinculados |

Comprobado el 9 de noviembre de 2026 en las páginas de Twilio (webhooks, precios de SMS y WhatsApp), la documentación de Meta (webhooks, precios) y la guía de Inbound Parse de SendGrid (enlaces en las fuentes).

La letra pequeña

## ¿Qué límites tiene un webhook unificado sobre tus propios canales?

Un solo formato elimina el código de pegamento. Cada canal conserva su naturaleza.

1. 01  
### Los webhooks son de pago  
Enviar por los tres canales es gratis en todos los planes, y los mensajes recibidos aparecen en la bandeja de la aplicación web. Enviarlos a tu servidor requiere Medium (19 € al mes, o 17 € al mes con pago anual) o Max.
2. 02  
### WhatsApp es un dispositivo vinculado  
El número se vincula como WhatsApp Web, con un protocolo no oficial: el spam hace que lo restrinjan, y WhatsApp cierra la sesión de los dispositivos vinculados si el móvil principal pasa 14 días sin conexión.
3. 03  
### El SMS necesita un móvil Android  
La SIM reenvía a través de la app Android gratis (8.0 o posterior), que debe seguir encendida y conectada. Solo texto, y solo los SMS recibidos después de iniciar sesión.
4. 04  
### El email lee la bandeja de entrada  
Por ahora solo buzones IMAP (Gmail con contraseña de aplicación, tu dominio, la mayoría de proveedores); todavía sin Outlook ni Microsoft 365\. El correo que va a spam o a otras carpetas no se ve.
5. 05  
### No todos los campos existen en todos los canales  
El SMS no tiene identificador de conversación ni acuse de lectura, el email no tiene reacciones, WhatsApp no tiene asunto. Programa sobre los campos comunes y trata el resto como opcional.

Cómo elegir

### ¿Webhook unificado o proveedores separados?

Necesitas la insignia oficial de WhatsApp, campañas de plantillas a gran escala, números cortos o miles de direcciones de email generadas: combina proveedores oficiales y presupuesta cada uno. Quieres reunir las respuestas que tus clientes ya envían a tu número, tu dirección y tu móvil, con un solo handler y respuestas desde las mismas identidades: vincula los tres y suscribe un endpoint a message.received.

FAQ

## Preguntas sobre el webhook multicanal

Sí. Con Unlimited Messaging, un endpoint suscrito a message.received recibe los mensajes de tu número de WhatsApp vinculado, tu buzón y tu SIM Android en el mismo sobre JSON firmado; data.channel.type indica el canal. Los webhooks requieren el plan Medium o Max.

data.channel.type es WHATSAPP, EMAIL o SMS, y data.channel.account indica el número, buzón o SIM por el que llegó el mensaje. El email añade subject, html y attachments.

Usa data.channel.conversation.id: el chat o grupo de WhatsApp, o el Message-ID raíz de un hilo de email. El SMS no tiene identificador de conversación, así que agrupa por sender. Para unir a una persona entre canales, cruza su teléfono y su email en tu CRM.

Firmados según Standard Webhooks (HMAC-SHA256 sobre id.timestamp.rawBody, secreto whsec\_). Reintentados ante 429, 5xx, timeouts y errores de red tras 30 s, 2 min, 10 min, 1 h, 6 h, 1 día y 2 días: 8 intentos en algo más de 3 días.

Sí. Pasa content a tu modelo y envía la respuesta con POST /message: replyToMessageId para WhatsApp y email (mismo chat, mismo hilo), o to.phone con una entrada channels de SMS y el accountId de la SIM.

Ninguna de las dos cosas. Un endpoint sin accountIds cubre todas tus cuentas, incluidas las que vincules más adelante. Añade accountIds cuando un equipo solo deba ver algunas.

Sí: message.received para los entrantes, message.sent para lo que envías por la API y message.self\_sent para lo que escribes en tu móvil de WhatsApp, así la bandeja muestra los dos lados.

No. Unlimited Messaging no cobra por mensaje en ningún canal; los webhooks vienen con el plan Medium o Max. Las respuestas SMS cuentan en tu tarifa móvil.

Fuentes

## Fuentes y referencias

Para verificar por ti mismo la información de este artículo:

1. [01Especificación Standard Webhooks↗standardwebhooks.com](https://www.standardwebhooks.com)
2. [02Getting started with webhooks (hub.challenge, X-Hub-Signature-256)↗Meta for Developers](https://developers.facebook.com/docs/graph-api/webhooks/getting-started)
3. [03Precios de la WhatsApp Business Platform↗Meta for Developers](https://developers.facebook.com/docs/whatsapp/pricing)
4. [04Incoming message webhook request (form-encoded)↗Twilio Docs](https://www.twilio.com/docs/messaging/guides/webhook-request)
5. [05Webhooks security (X-Twilio-Signature, HMAC-SHA1)↗Twilio Docs](https://www.twilio.com/docs/usage/webhooks/webhooks-security)
6. [06Precios de SMS en Estados Unidos↗Twilio](https://www.twilio.com/en-us/sms/pricing/us)
7. [07Precios de WhatsApp (0,005 $ por mensaje, entrante o saliente)↗Twilio](https://www.twilio.com/en-us/whatsapp/pricing)
8. [08Setting up the Inbound Parse webhook (MX, multipart/form-data)↗Twilio SendGrid Docs](https://www.twilio.com/docs/sendgrid/for-developers/parsing-email/setting-up-the-inbound-parse-webhook)
9. [09Acerca de los dispositivos vinculados (cierre de sesión tras 14 días sin el móvil principal)↗Servicio de ayuda de WhatsApp](https://faq.whatsapp.com/378279804439436)
10. [10Referencia de la API de Unlimited Messaging - Webhooks↗Unlimited Messaging](https://docs.unlimitedmessaging.app)

![Ilian, ingeniero de software senior](https://ilianazz.com/images/iliazz.png)

Escrito por

[Ilian](https://unlimitedmessaging.app/es/authors/ilian) · Ingeniero de software senior

Ingeniero de software senior, funda y dirige varias empresas tecnológicas. Diseña productos en torno a las API de mensajería, la automatización y la integración de la IA, y comparte aquí lo que aprende construyendo.

[Ver el perfil de LinkedIn↗](https://www.linkedin.com/in/ilianAzz/)Actualizado el 9 de noviembre de 2026

![](https://unlimitedmessaging.app/assets/logos/whatsapp.svg)![](https://unlimitedmessaging.app/assets/logos/email.svg)![](https://unlimitedmessaging.app/assets/logos/sms.svg)

## Tres canales, un solo handler.

Crea una cuenta, vincula tu WhatsApp, tu buzón y tu móvil Android, y activa los webhooks con Medium o Max. Enviar sigue siendo gratis en todos los planes.

[Crear una cuenta gratis→](https://app.unlimitedmessaging.app)

Artículos similares
* [![](https://unlimitedmessaging.app/_next/image?url=%2Fassets%2Farticles%2Fcovers%2Fwhatsapp-webhook-incoming-messages-es.png&w=3840&q=75)Webhook de WhatsApp sin aprobación de Meta: ¿es posible?Los mensajes de WhatsApp que recibe tu propio número, enviados a tu servidor como JSON firmado. Eventos, payload, handler en Node.js.](https://unlimitedmessaging.app/es/articles/whatsapp-webhook-incoming-messages)
* [![](https://unlimitedmessaging.app/_next/image?url=%2Fassets%2Farticles%2Fcovers%2Femail-inbound-webhook-es.png&w=3840&q=75)Webhook de email entrante sin tocar tus MX: ¿cómo?Tu propio buzón a un webhook: asunto, HTML, adjuntos e hilos como JSON firmado, con respuestas desde la misma dirección.](https://unlimitedmessaging.app/es/articles/email-inbound-webhook)
* [![](https://unlimitedmessaging.app/_next/image?url=%2Fassets%2Farticles%2Fcovers%2Fsms-webhook-incoming-sms-es.png&w=3840&q=75)Webhook SMS en tu propio número: ¿hace falta Twilio?Los SMS que recibe tu propia SIM, enviados como JSON firmado por una app Android gratis. Sin número alquilado, sin coste por SMS recibido.](https://unlimitedmessaging.app/es/articles/sms-webhook-incoming-sms)
