Qué es la WhatsApp Cloud API
La Cloud API reemplazó a la antigua "On-Premises API" en 2022. Diferencias:
| Cloud API (actual) | On-Premises (legacy) |
|---|
| Hospedada por Meta | Tú la hospedas |
|---|---|
| Setup en horas | Setup en semanas |
| Sin servidor que mantener | VPS + Docker + mantenimiento |
| Misma performance | Más compleja |
| Recomendada para 99% de casos | Solo casos enterprise específicos |
Prerrequisitos
Antes de empezar:
Camino 1: Directo por Meta (complejo)
Si quieres ir directo por Meta sin BSP:
Este camino funciona, pero todavía necesitas:bashcurl -X POST \ "https://graph.facebook.com/v18.0/<PHONE_NUMBER_ID>/messages" \ -H "Authorization: Bearer <ACCESS_TOKEN>" \ -H "Content-Type: application/json" \ -d '{ "messaging_product": "whatsapp", "to": "525511223344", "type": "template", "template": { "name": "hello_world", "language": { "code": "en_US" } } }'
- Aprobar templates manualmente en Meta Business Suite
- Renovar tokens
- Implementar webhooks con verificación de firma
- Manejar errores y retries
- Migrar de número si Meta te limita
Camino 2: Vía BSP oficial (recomendado)
Los BSPs oficiales resuelven el 90% de la complejidad. Así con Zavu:
1. Cuenta gratis
zavu.dev/es — sin tarjeta de crédito.2. Conectar Meta Business
En el dashboard, Add WhatsApp Sender → flujo OAuth con Meta. Autorizas a Zavu como BSP. 5 minutos.
3. Instalar SDK
bash# Node.js npm install @zavudev/sdk
bash# Python pip install zavudev
4. Primer mensaje
Node.js:Python:typescriptimport Zavu from "@zavudev/sdk" const zavu = new Zavu({ apiKey: process.env.ZAVU_API_KEY }) const result = await zavu.messages.send({ to: "+525511223344", channel: "whatsapp", text: "¡Hola! Primer mensaje vía Zavu 🎉" }) console.log(result.message.id, result.message.status)
pythonfrom zavudev import Zavu zavu = Zavu(api_key=os.environ["ZAVU_API_KEY"]) result = zavu.messages.send( to="+525511223344", channel="whatsapp", text="¡Hola! Primer mensaje vía Zavu 🎉" ) print(result.message.id, result.message.status)
Mensajes libres vs templates
La ventana de 24 horas es central:
- Dentro de 24h después que el cliente te respondió: cualquier mensaje (texto, mídia, botones)
- Fuera de 24h: solo templates aprobados
Enviar template
typescriptawait zavu.messages.send({ to: "+525511223344", channel: "whatsapp", messageType: "template", content: { templateId: "tpl_pedido_confirmado", templateVariables: { "1": "Juan", "2": "12345", "3": "$89.90 MXN" } } })
Categorías de templates:
- Utility (transaccional) — confirmaciones, recordatorios — $0.60 MXN
- Authentication (OTP) — códigos — $0.40 MXN
- Marketing (promocional) — ofertas — $3.20 MXN
Media rica
typescript// Imagen await zavu.messages.send({ to: "+525511223344", channel: "whatsapp", messageType: "image", text: "¡Mira nuestro nuevo producto!", content: { mediaUrl: "https://ejemplo.com/producto.jpg" } }) // Documento PDF await zavu.messages.send({ to: "+525511223344", channel: "whatsapp", messageType: "document", content: { mediaUrl: "https://ejemplo.com/factura.pdf", filename: "factura.pdf" } }) // Botones interactivos await zavu.messages.send({ to: "+525511223344", channel: "whatsapp", messageType: "buttons", text: "¿Cómo podemos ayudarte?", content: { buttons: [ { id: "comprar", title: "Quiero comprar" }, { id: "dudas", title: "Resolver dudas" }, { id: "rastreo", title: "Rastrear pedido" } ] } })
Recibiendo mensajes (webhooks)
Configura endpoint HTTPS en Zavu Dashboard. Cada mensaje recibido genera un POST:
typescript// app/api/whatsapp-webhook/route.ts (Next.js) export async function POST(req: Request) { const event = await req.json() const signature = req.headers.get("x-zavu-signature") if (!verifySignature(signature, event)) { return new Response("Unauthorized", { status: 401 }) } switch (event.type) { case "message.inbound": console.log(Cliente ${event.message.from}: ${event.message.text}) break case "message.delivered": console.log(Mensaje ${event.message.id} entregado) break case "message.read": console.log(Mensaje ${event.message.id} leído) break } return new Response("ok") }
Errores comunes
131056 - Number not registered: el número no está habilitado en WhatsApp Business. Verifica en Meta Business Suite.131005 - Access denied: token incorrecto o expirado. Usa System User token (permanente) en producción.132000 - Template not approved: template en revisión todavía. Espera o usa texto libre en ventana de 24h.Mensaje no llega: el destinatario puede no tener WhatsApp o bloqueó tu número. Verifica con webhook message.failed.Webhook no responde en 2s: Meta reintenta hasta 3 veces. Estructura tu endpoint para responder rápido y procesar async.Costos de WhatsApp Cloud API (México)
Meta cobra por conversación de 24h iniciada, no por mensaje. Precios MX 2026:
| Categoría | Costo Meta |
|---|
| Utility (transaccional) | ~$0.60 MXN |
|---|---|
| Authentication (OTP) | ~$0.40 MXN |
| Marketing | ~$3.20 MXN |
| Service (cliente inicia) | Gratis |
Recursos relacionados
- API de WhatsApp: guía para desarrolladores
- Cómo crear un chatbot en WhatsApp
- Construye un agente de IA para WhatsApp con FastAPI
- Documentación técnica
- Zavu vs Twilio