WhatsApp Cloud API
Todo lo necesario para enviar y recibir mensajes a través del WABA del negocio: mensajes simples y con plantilla, multimedia, botones y listas interactivas, marcar como leído, gestionar plantillas, perfil del negocio, diagnostics del número y estadísticas.
Para conceptos comunes (autenticación, scopes, errores, idempotencia) andá a la página principal. Para recibir mensajes entrantes ver Webhooks. Para conectar el WhatsApp del negocio por primera vez ver Onboarding.
Enviar mensajes
POST /v1/messages
Plantilla simple (primer mensaje a un contacto):
POST /v1/messages
{
"tenant_ref": "pizzeria-don-mario",
"to": "5491155555555",
"type": "template",
"template": {
"name": "hello_world",
"language": "en_US"
}
}
Plantilla con variables:
POST /v1/messages
{
"tenant_ref": "pizzeria-don-mario",
"to": "5491155555555",
"type": "template",
"template": {
"name": "pedido_listo",
"language": "es",
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "Juan" },
{ "type": "text", "text": "12345" }
]
}
]
}
}
Texto libre (solo si la conversación tiene una sesión activa de 24h):
POST /v1/messages
{
"tenant_ref": "pizzeria-don-mario",
"to": "5491155555555",
"type": "text",
"text": {
"body": "Hola, gracias por escribirnos. ¿En qué te ayudo?"
}
}
GET /v1/messages/{id}
Consulta el estado actual de un mensaje enviado.
GET /v1/messages/019dcf...
Respuesta:
{
"id": "019dcf...",
"status": "delivered",
"waba_message_id": "wamid.HBg...",
"created_at": "2026-05-07T15:30:00Z",
"updated_at": "2026-05-07T15:30:12Z"
}
Imágenes, audio, video y documentos
Adjuntá multimedia por URL pública (Meta la descarga). Los formatos aceptados los define Meta — los más comunes andan sin problema.
Imagen
POST /v1/messages
{
"tenant_ref": "pizzeria-don-mario",
"to": "5491155555555",
"type": "image",
"image": {
"link": "https://tu-cdn.com/pizza.jpg",
"caption": "Hoy en promo: muzza con fainá."
}
}
Video
POST /v1/messages
{
"tenant_ref": "pizzeria-don-mario",
"to": "5491155555555",
"type": "video",
"video": {
"link": "https://tu-cdn.com/horno.mp4",
"caption": "Recién salida del horno."
}
}
Audio
POST /v1/messages
{
"tenant_ref": "pizzeria-don-mario",
"to": "5491155555555",
"type": "audio",
"audio": { "link": "https://tu-cdn.com/aviso.ogg" }
}
Documento
POST /v1/messages
{
"tenant_ref": "pizzeria-don-mario",
"to": "5491155555555",
"type": "document",
"document": {
"link": "https://tu-cdn.com/factura-12345.pdf",
"filename": "factura-12345.pdf",
"caption": "Tu factura."
}
}
Sticker
POST /v1/messages
{
"tenant_ref": "pizzeria-don-mario",
"to": "5491155555555",
"type": "sticker",
"sticker": { "link": "https://tu-cdn.com/gracias.webp" }
}
Stickers tienen que ser .webp y cumplir el tamaño exacto
que pide Meta (512x512 px, máx 100 KB para estáticos). Si Meta los
rechaza, te devolvemos meta_other con el detalle.
Botones y listas
Los mensajes interactivos permiten que el contacto te responda con un
click. Las respuestas te llegan por webhook como message.received
con un payload que indica qué botón apretó.
Botones de respuesta rápida (Quick Reply)
Hasta 3 botones. El id es lo que te llega cuando aprieta.
POST /v1/messages
{
"tenant_ref": "pizzeria-don-mario",
"to": "5491155555555",
"type": "interactive",
"interactive": {
"type": "button",
"body": { "text": "¿Confirmás tu pedido #12345?" },
"action": {
"buttons": [
{ "type": "reply", "reply": { "id": "ok", "title": "Sí, confirmar" } },
{ "type": "reply", "reply": { "id": "cancel", "title": "No, cancelar" } }
]
}
}
}
Lista de opciones
Hasta 10 opciones agrupadas en secciones. Útil para menús.
POST /v1/messages
{
"tenant_ref": "pizzeria-don-mario",
"to": "5491155555555",
"type": "interactive",
"interactive": {
"type": "list",
"body": { "text": "Elegí una opción." },
"action": {
"button": "Ver menú",
"sections": [
{
"title": "Pizzas",
"rows": [
{ "id": "muzza", "title": "Muzzarella", "description": "$3500" },
{ "id": "napoli", "title": "Napolitana", "description": "$4200" }
]
},
{
"title": "Bebidas",
"rows": [
{ "id": "coca", "title": "Coca 1.5L", "description": "$1800" }
]
}
]
}
}
}
Ubicación, contactos y reacciones
Ubicación
POST /v1/messages
{
"tenant_ref": "pizzeria-don-mario",
"to": "5491155555555",
"type": "location",
"location": {
"latitude": -34.6037,
"longitude": -58.3816,
"name": "Pizzería Don Mario",
"address": "Av. Corrientes 1234, CABA"
}
}
Contacto
POST /v1/messages
{
"tenant_ref": "pizzeria-don-mario",
"to": "5491155555555",
"type": "contacts",
"contacts": [
{
"name": { "formatted_name": "Mario Rossi", "first_name": "Mario" },
"phones": [
{ "phone": "+5491155551234", "type": "CELL" }
]
}
]
}
Reacción a un mensaje
Reaccionás con un emoji a un mensaje que te mandó el contacto.
Necesitás el waba_message_id que te llegó por webhook.
POST /v1/messages
{
"tenant_ref": "pizzeria-don-mario",
"to": "5491155555555",
"type": "reaction",
"reaction": {
"message_id": "wamid.HBg...",
"emoji": "👍"
}
}
Para sacar una reacción, mandá la misma estructura con
"emoji": "" (string vacío).
Responder a un mensaje
Cualquier tipo de mensaje puede ser reply a un mensaje
anterior — visualmente aparece citado en el chat del contacto.
Agregá context.message_id con el waba_message_id
del mensaje al que respondés:
POST /v1/messages
{
"tenant_ref": "pizzeria-don-mario",
"to": "5491155555555",
"type": "text",
"context": { "message_id": "wamid.HBg..." },
"text": { "body": "Sí, está abierto hasta las 23." }
}
Marcar como leído
POST /v1/messages/mark-read
Le decimos a Meta que tu sistema ya leyó el mensaje del contacto (el contacto va a ver el doble tilde azul). Opcionalmente activa el indicador "escribiendo…".
POST /v1/messages/mark-read
{
"tenant_ref": "pizzeria-don-mario",
"waba_message_id": "wamid.HBg...",
"typing_indicator": true
}
El indicador "escribiendo…" dura ~25 segundos o hasta que mandes el próximo mensaje (lo que ocurra primero).
Descargar media recibida
GET /v1/media/{id}
Cuando un contacto te manda una foto, audio, video o documento, en el
webhook message.received llega un media.id.
Bajalo desde nuestro endpoint — proxiamos con el token de Meta así
no tenés que manejarlo vos.
GET /v1/media/MID01?tenant_ref=pizzeria-don-mario
Authorization: Bearer TU_API_KEY
Respuesta: el binario crudo, con headers:
Content-Type: el MIME real (ejimage/jpeg).Content-Length: tamaño en bytes.X-Sabado-Media-SHA256: hash del archivo para integridad.
Si querés sugerir un nombre de archivo para descarga directa:
GET /v1/media/MID01?tenant_ref=pizzeria-don-mario&filename=foto.jpg
Plantillas
POST /v1/templates
Crear una plantilla en nombre del negocio. Meta la pasa a revisión.
POST /v1/templates
{
"tenant_ref": "pizzeria-don-mario",
"name": "pedido_listo",
"language": "es",
"category": "UTILITY",
"components": [
{
"type": "BODY",
"text": "Hola {{1}}, tu pedido #{{2}} ya está listo para retirar.",
"example": { "body_text": [["Juan", "12345"]] }
},
{
"type": "FOOTER",
"text": "Sabado Cloud · Notificación automática"
}
]
}
Reglas que aplica Meta:
- Nombre: solo lowercase, números, guiones bajos.
- Body: máximo 1024 chars. Variables
{{1}}, {{2}}, ...en orden. - Example: obligatorio cuando hay variables.
- Category:
UTILITY(notificaciones operativas),MARKETING(promocionales) oAUTHENTICATION(OTP).
GET /v1/templates
Listar las plantillas del negocio.
GET /v1/templates?tenant_ref=pizzeria-don-mario&limit=20
DELETE /v1/templates/{name}
Borrar una plantilla.
DELETE /v1/templates/pedido_listo?tenant_ref=pizzeria-don-mario
Perfil del negocio
Datos visibles cuando el contacto toca el nombre del negocio dentro de WhatsApp: descripción, sitio web, rubro, etc. El cliente final también lo puede editar desde su panel.
GET /v1/business-profile
GET /v1/business-profile?tenant_ref=pizzeria-don-mario
Authorization: Bearer TU_API_KEY
Respuesta:
{
"tenant_ref": "pizzeria-don-mario",
"profile": {
"about": "La mejor pizza al horno de barro.",
"address": "Av. Corrientes 1234, CABA",
"description": "Pizzería tradicional desde 1985...",
"email": "contacto@donmario.com.ar",
"vertical": "RESTAURANT",
"websites": ["https://donmario.com.ar"],
"profile_picture_url": "https://...",
"messaging_product": "whatsapp"
}
}
PUT /v1/business-profile
Mandá solo los campos que querés cambiar. Lo que no mandes queda intacto.
PUT /v1/business-profile
{
"tenant_ref": "pizzeria-don-mario",
"about": "Pizza al horno de barro · Delivery 30 min",
"vertical": "RESTAURANT",
"websites": ["https://donmario.com.ar"]
}
Reglas de Meta:
about: máximo 139 caracteres.description: máximo 512 caracteres.websites: máximo 2 URLs.vertical: uno deAUTO, BEAUTY, APPAREL, EDU, ENTERTAIN, EVENT_PLAN, FINANCE, GROCERY, GOVT, HOTEL, HEALTH, NONPROFIT, PROF_SERVICES, RETAIL, TRAVEL, RESTAURANT, OTHER, NOT_A_BIZ, UNDEFINED.
Para cambiar la foto de perfil hay que subir el binario al endpoint de Meta y mandar el handle resultante. Por ahora no lo exponemos — si lo necesitás, escribinos.
Estado del número
Diagnostics en vivo del número conectado del negocio: calidad, capacidad, throughput y salud. El cliente final ve lo mismo en su panel.
GET /v1/phone-number
GET /v1/phone-number?tenant_ref=pizzeria-don-mario
Authorization: Bearer TU_API_KEY
Respuesta:
{
"tenant_ref": "pizzeria-don-mario",
"phone_number": {
"display_phone_number": "+54 9 11 5555-1234",
"verified_name": "Pizzería Don Mario",
"quality_rating": "GREEN",
"throughput": { "level": "STANDARD" },
"health_status": {
"entities": [
{ "entity_type": "PHONE_NUMBER", "can_send_message": "AVAILABLE" }
]
},
"messaging_limit_tier": "TIER_1K",
"name_status": "APPROVED",
"code_verification_status": "VERIFIED",
"platform_type": "CLOUD_API",
"last_onboarded_time": "2026-04-23T18:22:00+0000"
}
}
| Campo | Valores | Qué significa |
|---|---|---|
quality_rating | GREEN / YELLOW / RED | Calidad percibida por los contactos. RED limita envíos. |
messaging_limit_tier | TIER_50 / 250 / 1K / 10K / 100K / UNLIMITED | Cantidad de conversaciones únicas por día. |
throughput.level | STANDARD / HIGH / NOT_APPLICABLE | Velocidad máxima de envío. |
health_status.entities[].can_send_message | AVAILABLE / LIMITED / BLOCKED | Estado operativo de cada entidad (PHONE_NUMBER, WABA, BUSINESS). |
POST /v1/phone-number/register
Re-registra el número contra Meta. Útil para destrabar errores
131031 Business Account locked en Test Numbers, o para
reanudar uso de un número que fue desactivado.
POST /v1/phone-number/register
{
"tenant_ref": "pizzeria-don-mario",
"pin": "000000"
}
Si el número tiene 2FA activado, el pin es obligatorio
y son los 6 dígitos del 2FA. Para Test Numbers de Meta el default
es 000000.
Respuesta:
{ "ok": true }
Errores específicos:
422 meta_pin_mismatch(Meta 133005) — el PIN no es el correcto.423 meta_account_locked(Meta 131031) — la cuenta sigue lockeada después del intento. Contactanos.
Estadísticas
Métricas históricas de conversaciones y plantillas, directo del WABA del negocio. Las fechas se mandan como Unix timestamp en segundos.
GET /v1/analytics/conversations
Volumen y costo de conversaciones en un rango temporal.
GET /v1/analytics/conversations
?tenant_ref=pizzeria-don-mario
&start=1714521600
&end=1717113600
&granularity=DAILY
Respuesta:
{
"tenant_ref": "pizzeria-don-mario",
"analytics": {
"data_points": [
{ "start": 1714521600, "end": 1714608000, "conversation": 47, "cost": 0.94 },
{ "start": 1714608000, "end": 1714694400, "conversation": 63, "cost": 1.26 }
]
}
}
Parámetros opcionales para filtrar:
| Parámetro | Valores |
|---|---|
granularity | HALF_HOUR, DAILY, MONTHLY (default DAILY) |
phone_numbers[] | Filtrar por display phone numbers específicos |
country_codes[] | ISO 3166-1 alpha-2 (ej AR, BR) |
metric_types[] | COST, CONVERSATION |
conversation_categories[] | AUTHENTICATION, MARKETING, SERVICE, UTILITY |
conversation_types[] | FREE_ENTRY_POINT, FREE_TIER, REGULAR |
conversation_directions[] | BUSINESS_INITIATED, USER_INITIATED |
GET /v1/analytics/templates
Métricas por plantilla: enviados, entregados, leídos, clicks. Hasta 10 templates por request.
GET /v1/analytics/templates
?tenant_ref=pizzeria-don-mario
&start=1714521600
&end=1717113600
&template_ids[]=TPL1
&template_ids[]=TPL2
&metric_types[]=SENT
&metric_types[]=DELIVERED
&metric_types[]=READ
&metric_types[]=CLICKED
Respuesta:
{
"tenant_ref": "pizzeria-don-mario",
"analytics": {
"data": [
{
"template_id": "TPL1",
"data_points": [
{ "start": 1714521600, "sent": 120, "delivered": 118, "read": 95 }
]
}
]
}
}
Los template_ids los obtenés con
GET /v1/templates — cada item tiene un id
de Meta.