La WhatsApp Cloud API es la API oficial de Meta para enviar y recibir mensajes en WhatsApp Business, alojada por la propia Meta (no requiere hospedar nada por tu cuenta). Este tutorial muestra cómo empezar de cero hasta el primer mensaje enviado, con código real en Python y Node.js.
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 |
No necesitas lidiar directamente con la Cloud API. Proveedores oficiales (BSPs) como Zavu abstraen la complejidad. Pero es importante entender qué hay debajo.
Prerrequisitos
Antes de empezar:
Camino 1: Directo por Meta (complejo)
Si quieres ir directo por Meta sin BSP:
terminalcurl -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" } } }'
Este camino funciona, pero todavía necesitas:
- 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
terminal# Node.js npm install @zavudev/sdk
terminal# Python pip install zavudev
4. Primer mensaje
Node.js:
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)
Python:
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() break case "message.delivered": console.log(Cliente${event.message.from}: ${event.message.text}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 |
Los BSPs agregan costo de plataforma. Zavu pasa el costo de Meta sin markup — precios completos.
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
Conclusión
La WhatsApp Cloud API reemplaza el app de celular por un endpoint REST programable. Puedes ir directo por Meta (más trabajo, más control) o usar un BSP oficial como Zavu (más simple, sin gestionar tokens, templates ni migraciones). La API te da todo lo que el app no tiene: múltiples agentes, integración CRM, automatización de templates, webhooks y media rica. Empieza con este tutorial — en 30 minutos envías tu primer mensaje.