Webhook de WhatsApp
Recibe los mensajes de WhatsApp en tu servidor,
desde el número que ya usas.
Los webhooks de Meta exigen una app de Meta, un portfolio comercial y un número trasladado a la API. Vincula en cambio tu WhatsApp actual: cada mensaje entrante llega a tu URL como JSON firmado.
¿Con prisa? Resume este artículo con una IA
La respuesta corta
¿Se puede tener un webhook de WhatsApp sin la API Business de Meta?
Sí. Unlimited Messaging vincula tu número de WhatsApp actual como dispositivo vinculado, igual que WhatsApp Web, y envía cada mensaje recibido a tu URL como un evento JSON firmado según Standard Webhooks, llamado message.received. No hay app de Meta que crear, ni verificación de empresa, ni coste por mensaje. Los webhooks están en los planes de pago Medium y Max.
La vía oficial es la WhatsApp Cloud API de Meta. Para recibir sus webhooks creas una app de Meta con el caso de uso de WhatsApp, le asocias un portfolio comercial y una cuenta de WhatsApp Business, respondes a una petición GET de verificación con hub.challenge y sirves un certificado TLS válido: Meta no acepta certificados autofirmados. Un portfolio nuevo solo puede escribir a 250 personas al día (fuera de la ventana de 24 horas) hasta que se verifica, y una empresa que lo construye para clientes necesita además la App Review de Meta.
Unlimited Messaging toma el otro camino: escaneas un código QR desde WhatsApp, Dispositivos vinculados, y el número sigue funcionando en tu móvil. Cada mensaje que llega se guarda y se envía a tu endpoint con el remitente, el texto, la conversación y, para una foto o una nota de voz, una mediaUrl que sirve el archivo. Tu respuesta sale por POST /message desde el mismo número, así que el cliente ve un chat normal.
El precio, con honestidad: es el protocolo no oficial de dispositivos vinculados, no un producto de Meta. Sirve para respuestas y avisos a gente que ya te escribe. Enviar en masa a desconocidos hace que bloqueen el número, sea cual sea la herramienta.
Antes de empezar: las API de WhatsApp gratis comparadas y cómo proteger un número vinculado de un bloqueo.

Los eventos
¿Qué eventos de WhatsApp puedes recibir por webhook?
Diez tipos de evento, elegidos por endpoint: un endpoint solo recibe lo que está en su lista eventTypes. Estos son los que necesita una bandeja de WhatsApp.
message.received
Ha llegado un mensaje, en un chat 1:1 o en un grupo: texto, imagen, vídeo, documento, audio, nota de voz (ptt), sticker o ubicación. Se emite una vez por mensaje; un mensaje con archivo se anuncia cuando el archivo está guardado, con mediaUrl.
message.self_sent
Escribiste un mensaje en el propio móvil, fuera de la API. Misma forma que message.received con direction OUT, para que tu CRM vea los dos lados del chat.
message.reaction, message.edited, message.deleted
Alguien reaccionó con un emoji (o lo quitó), editó un mensaje o lo eliminó para todos. Cada uno señala su objetivo por externalId, y puede llegar antes que el mensaje al que afecta.
message.sent y message.status
Un mensaje que enviaste por API llegó a WhatsApp y luego pasó a DELIVERED, READ, FAILED o UNDELIVERABLE. message.status incluye previousStatus para ignorar un acuse antiguo.
account.status_changed
El número se conectó, se desconectó, se cerró su sesión o WhatsApp lo restringió (BLOCKED, con blockedUntil). Suscríbete para que una bandeja muda nunca pase desapercibida.
{
"type": "message.received",
"eventId": "whd_6f1c2a9e-1b7d-4c55-9a43-2f0e8b7d3c11",
"occurredAt": "2026-11-09T10:00:01.000Z",
"data": {
"message": {
"id": "msg_0e55ff33-854a-482c-8510-68226e09cdcb",
"externalId": "3EB0A1C2D3E4F5061728",
"direction": "IN",
"fromMe": false,
"content": "Hi! Is my order ready for pickup?",
"sentAt": "2026-11-09T10:00:00.000Z",
"receivedAt": "2026-11-09T10:00:01.000Z",
"sender": "+447700900123",
"senderId": "[email protected]",
"senderName": "Lea",
"participant": null,
"replyTo": null,
"transcript": null
},
"channel": {
"type": "WHATSAPP",
"account": { "id": "acc_373bc415-447a-4813-9b61-a3a09ea9aaf3", "name": "Support" },
"conversation": {
"id": "[email protected]",
"isGroup": false,
"address": "+447700900123"
}
}
}
}Puesta en marcha
¿Cómo recibir los mensajes de WhatsApp entrantes en Node.js?
Tres pasos: vincular el número, registrar un endpoint, verificar y procesar cada POST. Responde en menos de 10 segundos y haz el trabajo después.
- 01
Vincula tu WhatsApp
En la aplicación web, añade una cuenta de WhatsApp y escanea el código QR desde WhatsApp, Ajustes, Dispositivos vinculados. El número sigue en tu móvil.
- 02
Registra el endpoint
POST /webhooks con tu URL y tus eventTypes, o añádelo en la página Webhooks del panel. El secreto (whsec_...) se muestra una sola vez.
- 03
Verifica, confirma, actúa
Comprueba la cabecera webhook-signature, devuelve un 2xx y deduplica por eventId: la entrega es «al menos una vez».
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", "account.status_changed"],
"description": "Incoming WhatsApp"
}'
# The response carries "secret": "whsec_..." once. Store it as UM_WEBHOOK_SECRET.import crypto from 'node:crypto';
import express from 'express';
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');
const seen = new Set<string>(); // use your database in production
// 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));
});
}
const app = express();
app.post('/webhooks/um', express.raw({ type: 'application/json' }), async (req, res) => {
const raw = req.body.toString('utf8');
const ok = verify(raw, req.get('webhook-id') ?? '', req.get('webhook-timestamp') ?? '',
req.get('webhook-signature') ?? '');
if (!ok) return res.sendStatus(401);
res.sendStatus(200); // answer within 10 s, work afterwards
const event = JSON.parse(raw);
if (seen.has(event.eventId)) return; // at-least-once delivery
seen.add(event.eventId);
if (event.type === 'message.received' && event.data.channel.type === 'WHATSAPP') {
const { id, content } = event.data.message;
if (content?.toLowerCase().includes('order')) {
// Answers in the same chat, from the same linked number.
await um.messages.messageSend({ replyToMessageId: id, text: 'Checking your order now.' });
}
}
});
app.listen(3000);Vibe coding
¿Programas con Cursor, Claude Code, Lovable o Bolt? Pega esto
El prompt le da a tu editor con IA el endpoint, el esquema de firma y la forma de los eventos, para que escriba la ruta del webhook sin adivinar.
Add an Unlimited Messaging webhook to this app so it receives incoming WhatsApp messages from my own number.
1. Create a POST route at /webhooks/um that reads the RAW request body (no JSON parsing before verification).
2. Verify the Standard Webhooks signature: key = base64-decode(UM_WEBHOOK_SECRET without its "whsec_" prefix); 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 if invalid.
3. Return 200 at once, then process. Deduplicate on body.eventId.
4. On type "message.received" with data.channel.type "WHATSAPP", read data.message.content, data.message.sender (+E164 or null), data.message.senderName and data.message.mediaUrl, and save them.
5. To reply, install @unlimited-messaging/sdk, read UM_API_KEY from env, and call `new UnlimitedMessagingApiClient({ token }).messages.messageSend({ replyToMessageId: data.message.id, text })`.
6. Add UM_API_KEY and UM_WEBHOOK_SECRET to .env and .env.example, never hardcode them.
Docs: https://docs.unlimitedmessaging.app (Webhooks section). Register the URL with POST https://api.unlimitedmessaging.app/webhooks and eventTypes ["message.received"].Lo que se construye
¿Qué puedes hacer con los mensajes de WhatsApp entrantes?
Todo lo que empieza por «cuando un cliente escribe». Algunos usos que encajan bien con el modelo de número vinculado.
Un contestador con IA en tu número real
Pasa content a Claude o GPT y devuelve la respuesta con replyToMessageId. Tus clientes siguen escribiendo al número que tienen guardado, y tú tomas el control desde el móvil cuando quieras.
WhatsApp en tu CRM o tu helpdesk
Guarda cada message.received y message.self_sent en la ficha del contacto, por sender o senderId, para que toda la conversación esté junto a la oportunidad o el ticket.
Consultas de pedidos y reservas
Detecta una palabra clave o un número de pedido en el texto, búscalo y responde en segundos. Los archivos llegan como fichero guardado que puedes descargar.
Seguimiento de grupos
En un grupo, participant indica quién escribió y channel.conversation.participants lista los miembros, actualizados cuando cambia el grupo.
Alertas para el equipo
Reenvía un mensaje urgente a Slack o por email, o avisa a alguien cuando account.status_changed informa de una desconexión.
Flujos sin código
Apunta el webhook a n8n, Make o Zapier y ramifica según type y channel.type sin escribir un servidor.
La tabla
Webhooks de WhatsApp entrantes: Cloud API de Meta, Twilio y Unlimited Messaging
Meta y Twilio son la plataforma Business oficial, con sus aprobaciones y su precio por mensaje. Unlimited Messaging vincula el número que ya tienes.
| Meta Cloud APIOficial, directo | Twilio WhatsAppOficial, vía proveedor | Unlimited MessagingDispositivo vinculado, planes de pago | |
|---|---|---|---|
| Qué configuras primero | App de Meta, portfolio comercial, cuenta de WhatsApp Business | Cuenta de Twilio, portfolio de Meta Business, WABA creada desde Twilio | Escanear un código QR desde tu móvil |
| Tu número actual | Registrado en la plataforma | No puede estar ya registrado en WhatsApp | Se conserva y sigue funcionando en tu móvil |
| Aprobación y límites | 250 destinatarios al día iniciados por la empresa hasta verificar; App Review para tech providers | Verificación de empresa de Meta antes de producción | Ninguna de Meta; se aplican las reglas antispam de WhatsApp |
| Verificación del endpoint | GET de verificación con hub.challenge, TLS válido, sin autofirmados | URL de webhook configurada en el remitente | Ninguna: registras la URL y recibes |
| Firma | X-Hub-Signature-256, HMAC-SHA256 con el secreto de la app | X-Twilio-Signature, HMAC-SHA1 con el auth token | Standard Webhooks, HMAC-SHA256 con un secreto por endpoint |
| Formato del cuerpo | JSON, anidado en entry/changes | Form-encoded (application/x-www-form-urlencoded) | JSON, el mismo sobre para email y SMS |
| Reintentos | Frecuencia decreciente durante un máximo de 7 días | No se indica en la documentación de webhooks | 8 intentos en algo más de 3 días |
| Coste de recibir y responder | Respuestas de servicio gratis hasta 1.000 por número al mes, luego de pago; plantillas de pago | 0,005 $ por mensaje, entrante o saliente, más las tarifas de Meta | Sin coste por mensaje; webhooks con Medium o Max |
Comprobado el 9 de noviembre de 2026 en la documentación de Meta (webhooks, límites de mensajes, precios) y en las páginas de Twilio (alta de WhatsApp, precios, seguridad de webhooks). Enlaces en las fuentes.
La letra pequeña
¿Qué límites tiene un webhook de WhatsApp con número vinculado?
Prescindir de Meta elimina las aprobaciones. No elimina las reglas de WhatsApp ni las realidades de un dispositivo vinculado.
Los webhooks son de pago
El plan Free envía y muestra los mensajes recibidos en la aplicación web, pero enviarlos a tu servidor requiere Medium (19 € al mes, o 17 € al mes con pago anual) o Max. Sin coste por mensaje en ninguno.
No es oficial
El protocolo de dispositivos vinculados es el de WhatsApp Web, no una API de Meta. WhatsApp puede restringir un número que hace spam o recibe denuncias: account.status_changed te avisa, con blockedUntil cuando se conoce.
Un dispositivo vinculado sigue las reglas de WhatsApp
WhatsApp cierra la sesión de los dispositivos vinculados si el móvil principal pasa 14 días sin conexión. Abre WhatsApp en el móvil de vez en cuando y el vínculo funciona aunque el móvil esté apagado.
El orden y los duplicados son cosa tuya
La entrega es «al menos una vez» y sin orden garantizado: un texto enviado justo después de una foto suele llegar antes, porque la foto espera a que su archivo se guarde. Deduplica por eventId y ordena por sentAt.
El historial es opcional
Solo se anuncian los mensajes recibidos después de vincular, salvo que la cuenta se vinculara con syncHistory: los chats antiguos llegan entonces en lotes message.history de hasta 100 mensajes (archivos descritos, no guardados).
FAQ
Preguntas sobre los webhooks de WhatsApp
Fuentes
Fuentes y referencias
Para verificar por ti mismo la información de este artículo:
- Getting started with webhooks (verificación, X-Hub-Signature-256, TLS)Meta for Developers
- Set up webhooks for WhatsApp (reintentos durante un máximo de 7 días)Meta for Developers
- WhatsApp Cloud API - get started (app de Meta, portfolio comercial)Meta for Developers
- Messaging limits (250 para un portfolio comercial nuevo)Meta for Developers
- Get started for tech providers (verificación de empresa y App Review)Meta for Developers
- Precios de la WhatsApp Business PlatformMeta for Developers
- WhatsApp self sign-up (el número no puede estar registrado en WhatsApp)Twilio Docs
- Precios de WhatsApp (0,005 $ por mensaje, entrante o saliente)Twilio
- Webhooks security (X-Twilio-Signature, HMAC-SHA1)Twilio Docs
- Especificación Standard Webhooksstandardwebhooks.com
- Acerca de los dispositivos vinculados (cierre de sesión tras 14 días sin el móvil principal)Servicio de ayuda de WhatsApp
- Referencia de la API de Unlimited Messaging - WebhooksUnlimited Messaging

Escrito por
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.
Tus mensajes de WhatsApp, en tu servidor.
Crea una cuenta, vincula tu número con un código QR y activa los webhooks con Medium o Max. Enviar sigue siendo gratis en todos los planes.