curl -X POST https://api.whaapy.com/messages/v1 \
-H "Authorization: Bearer wha_TU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+5215512345678",
"type": "template",
"templateName": "orden_confirmada",
"template_parameters": ["Juan Pérez", "#ORD-12345", "$1,500.00"]
}'
const response = await fetch('https://api.whaapy.com/messages/v1', {
method: 'POST',
headers: {
'Authorization': 'Bearer wha_TU_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
to: '+5215512345678',
type: 'template',
templateName: 'orden_confirmada',
template_parameters: ['Juan Pérez', '#ORD-12345', '$1,500.00']
})
});
import requests
response = requests.post(
'https://api.whaapy.com/messages/v1',
headers={
'Authorization': 'Bearer wha_TU_API_KEY',
'Content-Type': 'application/json'
},
json={
'to': '+5215512345678',
'type': 'template',
'templateName': 'orden_confirmada',
'template_parameters': ['Juan Pérez', '#ORD-12345', '$1,500.00']
}
)
{
"messaging_product": "whatsapp",
"contacts": [
{ "input": "+5215512345678", "wa_id": "5215512345678" }
],
"messages": [
{ "id": "550e8400-e29b-41d4-a716-446655440000", "wamid": "wamid.HBgLNTIxNTUx..." }
],
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"conversationId": "660e8400-e29b-41d4-a716-446655440001",
"messageType": "template",
"direction": "outbound",
"status": "sent",
"createdAt": "2026-01-22T10:30:00Z"
}
}
Mensajes
Enviar Templates
Envía mensajes template pre-aprobados por Meta
POST
/
messages
/
v1
curl -X POST https://api.whaapy.com/messages/v1 \
-H "Authorization: Bearer wha_TU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+5215512345678",
"type": "template",
"templateName": "orden_confirmada",
"template_parameters": ["Juan Pérez", "#ORD-12345", "$1,500.00"]
}'
const response = await fetch('https://api.whaapy.com/messages/v1', {
method: 'POST',
headers: {
'Authorization': 'Bearer wha_TU_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
to: '+5215512345678',
type: 'template',
templateName: 'orden_confirmada',
template_parameters: ['Juan Pérez', '#ORD-12345', '$1,500.00']
})
});
import requests
response = requests.post(
'https://api.whaapy.com/messages/v1',
headers={
'Authorization': 'Bearer wha_TU_API_KEY',
'Content-Type': 'application/json'
},
json={
'to': '+5215512345678',
'type': 'template',
'templateName': 'orden_confirmada',
'template_parameters': ['Juan Pérez', '#ORD-12345', '$1,500.00']
}
)
{
"messaging_product": "whatsapp",
"contacts": [
{ "input": "+5215512345678", "wa_id": "5215512345678" }
],
"messages": [
{ "id": "550e8400-e29b-41d4-a716-446655440000", "wamid": "wamid.HBgLNTIxNTUx..." }
],
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"conversationId": "660e8400-e29b-41d4-a716-446655440001",
"messageType": "template",
"direction": "outbound",
"status": "sent",
"createdAt": "2026-01-22T10:30:00Z"
}
}
Los templates son mensajes pre-aprobados por Meta que puedes enviar en cualquier momento, incluso fuera de la ventana de 24 horas. Son ideales para:
Ejemplo con
Política de IDs (
Cuando envías templates por
El resultado será
Soluciones:
Solución: Revisa cuántos Permisos de Media (
Soluciones:
- Notificaciones transaccionales (confirmación de pedido, envío, etc.)
- Re-engagement con clientes inactivos
- Marketing autorizado
- Alertas y recordatorios
Los templates deben ser aprobados por Meta antes de usarlos. La aprobación puede tomar hasta 24 horas.
Formatos de Envío
Whaapy soporta tres formas de enviar templates:- Shortcut Whaapy
- Shortcut con Header
- Formato Meta Completo
Formato simplificado con
templateName y template_parameters:{
"to": "+5215512345678",
"type": "template",
"templateName": "orden_confirmada",
"template_parameters": ["Juan", "#12345"]
}
Incluye imagen/video/documento en el header con
header_media:{
"to": "+5215512345678",
"type": "template",
"templateName": "promo_imagen",
"template_parameters": ["20%", "Enero 2026"],
"header_media": {
"type": "image",
"url": "https://example.com/promo.jpg"
}
}
Control total con
template.components:{
"to": "+5215512345678",
"type": "template",
"template": {
"name": "orden_confirmada",
"language": { "code": "es_MX" },
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "Juan" },
{ "type": "text", "text": "#12345" }
]
}
]
}
}
Shortcut Whaapy (Simplificado)
El formato más sencillo para templates con solo parámetros de texto en el body.curl -X POST https://api.whaapy.com/messages/v1 \
-H "Authorization: Bearer wha_TU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+5215512345678",
"type": "template",
"templateName": "orden_confirmada",
"template_parameters": ["Juan Pérez", "#ORD-12345", "$1,500.00"]
}'
const response = await fetch('https://api.whaapy.com/messages/v1', {
method: 'POST',
headers: {
'Authorization': 'Bearer wha_TU_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
to: '+5215512345678',
type: 'template',
templateName: 'orden_confirmada',
template_parameters: ['Juan Pérez', '#ORD-12345', '$1,500.00']
})
});
import requests
response = requests.post(
'https://api.whaapy.com/messages/v1',
headers={
'Authorization': 'Bearer wha_TU_API_KEY',
'Content-Type': 'application/json'
},
json={
'to': '+5215512345678',
'type': 'template',
'templateName': 'orden_confirmada',
'template_parameters': ['Juan Pérez', '#ORD-12345', '$1,500.00']
}
)
Campos
string
required
Nombre exacto del template como aparece en Meta Business Manager.
array
Array de strings con los valores para cada
{{placeholder}} del template body, en orden.El shortcut asume idioma
es_MX por defecto. Para otros idiomas, usa el formato Meta completo.Shortcut con Header Media
Para templates que incluyen imagen, video o documento en el header.{
"to": "+5215512345678",
"type": "template",
"templateName": "promo_navidad",
"template_parameters": ["30%", "25 de diciembre"],
"header_media": {
"type": "image",
"url": "https://example.com/navidad-promo.jpg"
}
}
Con Video
{
"to": "+5215512345678",
"type": "template",
"templateName": "tutorial_producto",
"template_parameters": ["Producto X"],
"header_media": {
"type": "video",
"url": "https://example.com/tutorial.mp4"
}
}
Con Documento
{
"to": "+5215512345678",
"type": "template",
"templateName": "factura_mensual",
"template_parameters": ["Enero 2026", "$2,500.00"],
"header_media": {
"type": "document",
"url": "https://example.com/factura.pdf"
}
}
Campos de header_media
string
required
Tipo de media:
image, video, o document.string
required
URL pública del archivo multimedia.
string
Media ID de Meta previamente subido con el mismo número/WABA que enviará el template.
Ejemplo con media_id (sin URL pública)
{
"to": "+5215512345678",
"type": "template",
"templateName": "orden_servicio",
"template_parameters": ["Juan"],
"header_media": {
"type": "document",
"media_id": "155857201882704"
}
}
Compatibilidad legacy: si un cliente envía accidentalmente el
media_id en header_media.url, Whaapy intenta normalizarlo automáticamente.Formato Meta Completo
Control total sobre todos los componentes del template: header, body, footer y botones.Template Básico
{
"to": "+5215512345678",
"type": "template",
"template": {
"name": "orden_confirmada",
"language": {
"policy": "deterministic",
"code": "es_MX"
},
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "Juan Pérez" },
{ "type": "text", "text": "#ORD-12345" }
]
}
]
}
}
Template con Header de Imagen
{
"to": "+5215512345678",
"type": "template",
"template": {
"name": "confirmacion_pago",
"language": { "policy": "deterministic", "code": "es_MX" },
"components": [
{
"type": "header",
"parameters": [
{
"type": "image",
"image": { "link": "https://example.com/recibo.jpg" }
}
]
},
{
"type": "body",
"parameters": [
{ "type": "text", "text": "Juan Pérez" },
{ "type": "text", "text": "#ORD-12345" }
]
}
]
}
}
Template con Currency y Date
{
"to": "+5215512345678",
"type": "template",
"template": {
"name": "resumen_compra",
"language": { "policy": "deterministic", "code": "es_MX" },
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "Juan Pérez" },
{ "type": "text", "text": "#ORD-12345" },
{
"type": "currency",
"currency": {
"fallback_value": "$1,500.00 MXN",
"code": "MXN",
"amount_1000": 1500000
}
},
{
"type": "date_time",
"date_time": {
"fallback_value": "25 de enero, 2026"
}
}
]
}
]
}
}
Template con Botones
{
"to": "+5215512345678",
"type": "template",
"template": {
"name": "confirmacion_envio",
"language": { "policy": "deterministic", "code": "es_MX" },
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "Juan" },
{ "type": "text", "text": "#ENV-789" }
]
},
{
"type": "button",
"sub_type": "quick_reply",
"index": "0",
"parameters": [
{ "type": "payload", "payload": "confirmar_recibido_789" }
]
},
{
"type": "button",
"sub_type": "url",
"index": "1",
"parameters": [
{ "type": "text", "text": "ENV-789" }
]
}
]
}
}
Tipos de Parámetros
| Tipo | Uso | Ejemplo |
|---|---|---|
text | Texto simple | { "type": "text", "text": "Juan Pérez" } |
currency | Valores monetarios formateados | Ver ejemplo abajo |
date_time | Fechas y horas | Ver ejemplo abajo |
image | Imagen en header | { "type": "image", "image": { "link": "url" } } |
video | Video en header | { "type": "video", "video": { "link": "url" } } |
document | PDF en header | { "type": "document", "document": { "link": "url" } } |
payload | Datos de callback para botones | { "type": "payload", "payload": "data" } |
Parámetro Currency
{
"type": "currency",
"currency": {
"fallback_value": "$1,500.00 MXN",
"code": "MXN",
"amount_1000": 1500000
}
}
amount_1000 es el monto multiplicado por 1000. Para $1,500.00 MXN, el valor es 1500000.Parámetro Date/Time
{
"type": "date_time",
"date_time": {
"fallback_value": "25 de enero, 2026 a las 3:00 PM"
}
}
Estructura de Botones
Los botones en templates tienen diferentes tipos:| sub_type | Descripción | Parámetros |
|---|---|---|
quick_reply | Botón de respuesta rápida | payload (string de callback) |
url | Botón que abre URL | text (sufijo dinámico de URL) |
catalog | Abre catálogo de productos | N/A |
Política de IDs (payload) para quick reply
Cuando envías templates por POST /messages/v1, Whaapy resuelve el payload del botón en este orden:
overrideexplícito en request solo siallowButtonIdOverride=truebuttonIdconfigurado en el template del negocio- fallback automático:
btn_{index}_{templateName}
boolean
Opcional (default:
false). Si está en true, permite sobreescribir el payload de quick reply desde template.components.Ejemplo de override explícito (avanzado)
{
"to": "+5215512345678",
"type": "template",
"templateName": "confirmacion_envio",
"template_parameters": ["Juan", "#ENV-789"],
"allowButtonIdOverride": true,
"template": {
"components": [
{
"type": "button",
"sub_type": "quick_reply",
"index": "0",
"parameters": [
{ "type": "payload", "payload": "confirmar_envio_custom" }
]
}
]
}
}
Ejemplo Quick Reply
{
"type": "button",
"sub_type": "quick_reply",
"index": "0",
"parameters": [
{ "type": "payload", "payload": "confirmar_pedido_12345" }
]
}
Ejemplo URL Dinámica
Si tu template tiene botón URL conhttps://example.com/track/{{1}}:
{
"type": "button",
"sub_type": "url",
"index": "0",
"parameters": [
{ "type": "text", "text": "ENV-789" }
]
}
https://example.com/track/ENV-789.
string
required
Índice del botón (0-9). Corresponde al orden de los botones en el template.
Respuesta Exitosa
{
"messaging_product": "whatsapp",
"contacts": [
{ "input": "+5215512345678", "wa_id": "5215512345678" }
],
"messages": [
{ "id": "550e8400-e29b-41d4-a716-446655440000", "wamid": "wamid.HBgLNTIxNTUx..." }
],
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"conversationId": "660e8400-e29b-41d4-a716-446655440001",
"messageType": "template",
"direction": "outbound",
"status": "sent",
"createdAt": "2026-01-22T10:30:00Z"
}
}
Errores Comunes
Template No Encontrado (132000)
{
"error": "template_not_found",
"message": "El template no existe o no está aprobado",
"code": "132000",
"details": {
"template_name": "orden_confirmada",
"language": "es_MX"
}
}
- Verifica el nombre exacto en Meta Business Manager
- Confirma que el template está aprobado (no en revisión)
- Verifica el código de idioma correcto
Número de Parámetros Incorrecto
{
"error": "invalid_template_parameters",
"message": "El template requiere 3 parámetros, se recibieron 2"
}
{{placeholders}} tiene tu template y envía la misma cantidad de parámetros.
Permisos de Media (MEDIA_PERMISSION_DENIED)
{
"error": "Media permission denied",
"message": "No se pudo acceder al media_id del header con las credenciales actuales de WhatsApp.",
"code": "MEDIA_PERMISSION_DENIED",
"hint": "Verifica que el media fue subido con el mismo número/WABA/token que envía el template."
}
- Confirma que el
media_idpertenece al mismo WABA/número emisor. - Re-sube el archivo usando la misma credencial que envía el template.
- Si no tienes
media_idválido, usaheader_media.urlpública.
Códigos de Idioma Comunes
| Código | Idioma |
|---|---|
es_MX | Español (México) |
es_ES | Español (España) |
es_AR | Español (Argentina) |
en_US | Inglés (Estados Unidos) |
pt_BR | Portugués (Brasil) |
Usa
"policy": "deterministic" para asegurar que se use exactamente el idioma especificado. Sin esto, WhatsApp puede seleccionar un idioma diferente basado en las preferencias del usuario.Crear Templates en Meta
- Ve a Meta Business Suite
- Navega a WhatsApp Manager → Message Templates
- Click en Create Template
- Selecciona categoría (Marketing, Utility, Authentication)
- Define header, body, footer y botones
- Envía para aprobación
Los templates de categoría “Authentication” tienen reglas especiales y mayores restricciones.
Próximos Pasos
Mensajes Interactivos
Botones y listas sin templates
Reintentar Mensajes
Reenviar después de template
Was this page helpful?