Los mensajes interactivos permiten a los usuarios responder con un tap en lugar de escribir. Whaapy soporta en esta fase:
Botones : Hasta 3 opciones rápidas
Listas : Menús desplegables con secciones
CTA URL : Botón que abre una URL en el navegador
Flows : Apertura de un Flow de WhatsApp ya creado en Meta
Los mensajes interactivos solo pueden enviarse dentro de la ventana de 24 horas. Fuera de la ventana, usa templates .
Muestra hasta 3 botones con opciones rápidas. Ideal para preguntas simples o menús pequeños.
Ejemplo Básico
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": "interactive",
"interactive": {
"type": "button",
"body": {
"text": "¿Qué te gustaría hacer hoy?"
},
"action": {
"buttons": [
{
"type": "reply",
"reply": {
"id": "ver_menu",
"title": "Ver Menú"
}
},
{
"type": "reply",
"reply": {
"id": "hacer_pedido",
"title": "Hacer Pedido"
}
},
{
"type": "reply",
"reply": {
"id": "hablar_agente",
"title": "Hablar con Agente"
}
}
]
}
}
}'
{
"to" : "+5215512345678" ,
"type" : "interactive" ,
"interactive" : {
"type" : "button" ,
"header" : {
"type" : "text" ,
"text" : "🍕 Pizzería Whaapy"
},
"body" : {
"text" : "¡Bienvenido! ¿En qué podemos ayudarte?"
},
"footer" : {
"text" : "Responde con un botón"
},
"action" : {
"buttons" : [
{
"type" : "reply" ,
"reply" : { "id" : "menu" , "title" : "Ver Menú" }
},
{
"type" : "reply" ,
"reply" : { "id" : "pedido" , "title" : "Mi Pedido" }
}
]
}
}
}
{
"to" : "+5215512345678" ,
"type" : "interactive" ,
"interactive" : {
"type" : "button" ,
"header" : {
"type" : "image" ,
"image" : {
"link" : "https://example.com/promo.jpg"
}
},
"body" : {
"text" : "¡Promoción especial! 2x1 en pizzas familiares."
},
"action" : {
"buttons" : [
{
"type" : "reply" ,
"reply" : { "id" : "aprovechar" , "title" : "¡Quiero!" }
},
{
"type" : "reply" ,
"reply" : { "id" : "mas_info" , "title" : "Más Info" }
}
]
}
}
}
Campos de Botones
Debe ser "button" para reply buttons.
Header opcional. Puede ser text, image, video, o document.
Texto principal del mensaje. Máximo 1024 caracteres.
Texto secundario en gris. Máximo 60 caracteres.
interactive.action.buttons
Array de 1-3 botones. Cada botón tiene type: "reply" y objeto reply con id y title.
ID único del botón. Lo recibirás en el webhook cuando el usuario responda. Máximo 256 caracteres.
Texto visible del botón. Máximo 20 caracteres.
Listas (List Messages)
Menús desplegables con hasta 10 opciones organizadas en secciones. Ideal para catálogos, horarios, o menús extensos.
Ejemplo Básico
{
"to" : "+5215512345678" ,
"type" : "interactive" ,
"interactive" : {
"type" : "list" ,
"body" : {
"text" : "Elige una opción de nuestro menú:"
},
"action" : {
"button" : "Ver Opciones" ,
"sections" : [
{
"title" : "Pizzas" ,
"rows" : [
{
"id" : "pizza_margarita" ,
"title" : "Margarita" ,
"description" : "Tomate, mozzarella, albahaca - $150"
},
{
"id" : "pizza_pepperoni" ,
"title" : "Pepperoni" ,
"description" : "Pepperoni, mozzarella - $180"
}
]
},
{
"title" : "Bebidas" ,
"rows" : [
{
"id" : "bebida_refresco" ,
"title" : "Refresco" ,
"description" : "Coca-Cola, Sprite, Fanta - $35"
},
{
"id" : "bebida_agua" ,
"title" : "Agua" ,
"description" : "Natural o mineral - $25"
}
]
}
]
}
}
}
{
"to" : "+5215512345678" ,
"type" : "interactive" ,
"interactive" : {
"type" : "list" ,
"header" : {
"type" : "text" ,
"text" : "🍕 Menú Pizzería Whaapy"
},
"body" : {
"text" : "Tenemos las mejores pizzas de la ciudad. ¡Elige tu favorita!"
},
"footer" : {
"text" : "Envío gratis en pedidos mayores a $300"
},
"action" : {
"button" : "Ver Menú" ,
"sections" : [
{
"title" : "Pizzas Clásicas" ,
"rows" : [
{
"id" : "margarita" ,
"title" : "Margarita" ,
"description" : "Tomate, mozzarella, albahaca fresca"
},
{
"id" : "pepperoni" ,
"title" : "Pepperoni" ,
"description" : "Pepperoni premium, mozzarella"
},
{
"id" : "hawaiana" ,
"title" : "Hawaiana" ,
"description" : "Jamón, piña, mozzarella"
}
]
},
{
"title" : "Pizzas Especiales" ,
"rows" : [
{
"id" : "4_quesos" ,
"title" : "4 Quesos" ,
"description" : "Mozzarella, parmesano, gorgonzola, provolone"
},
{
"id" : "bbq_chicken" ,
"title" : "BBQ Chicken" ,
"description" : "Pollo, salsa BBQ, cebolla caramelizada"
}
]
}
]
}
}
}
Campos de Listas
Debe ser "list" para list messages.
Header opcional. Solo soporta type: "text" en listas.
Texto principal. Máximo 1024 caracteres.
Texto secundario. Máximo 60 caracteres.
interactive.action.button
Texto del botón que abre la lista. Máximo 20 caracteres.
interactive.action.sections
Array de secciones. Máximo 10 secciones, máximo 10 rows en total.
Campos de Section
Título de la sección. Máximo 24 caracteres. Requerido si hay más de una sección.
Array de opciones dentro de la sección.
Campos de Row
ID único de la opción. Lo recibirás en el webhook. Máximo 200 caracteres.
Título visible de la opción. Máximo 24 caracteres.
Descripción adicional. Máximo 72 caracteres.
CTA URL (Call-to-Action URL)
Muestra un botón que abre una URL en el navegador del usuario al hacer tap. Ideal para dirigir a páginas de pago, formularios web, catálogos online o cualquier enlace externo.
Ejemplo Básico
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": "interactive",
"interactive": {
"type": "cta_url",
"body": {
"text": "¡Tu pedido #12345 está listo! Haz seguimiento en tiempo real."
},
"action": {
"name": "cta_url",
"parameters": {
"display_text": "Rastrear Pedido",
"url": "https://mitienda.com/tracking/12345"
}
}
}
}'
{
"to" : "+5215512345678" ,
"type" : "interactive" ,
"interactive" : {
"type" : "cta_url" ,
"header" : {
"type" : "text" ,
"text" : "🛒 Mi Tienda Online"
},
"body" : {
"text" : "Aprovecha nuestras ofertas de temporada con hasta 50% de descuento en productos seleccionados."
},
"footer" : {
"text" : "Oferta válida hasta agotar existencias"
},
"action" : {
"name" : "cta_url" ,
"parameters" : {
"display_text" : "Ver Ofertas" ,
"url" : "https://mitienda.com/ofertas"
}
}
}
}
{
"to" : "+5215512345678" ,
"type" : "interactive" ,
"interactive" : {
"type" : "cta_url" ,
"header" : {
"type" : "image" ,
"image" : {
"link" : "https://example.com/promo-banner.jpg"
}
},
"body" : {
"text" : "Nueva colección disponible. ¡Sé el primero en verla!"
},
"action" : {
"name" : "cta_url" ,
"parameters" : {
"display_text" : "Comprar Ahora" ,
"url" : "https://mitienda.com/nueva-coleccion"
}
}
}
}
Campos de CTA URL
Header opcional. Puede ser text, image, video, o document.
Texto principal del mensaje. Máximo 1024 caracteres.
Texto secundario en gris. Máximo 60 caracteres.
interactive.action.parameters.display_text
Texto visible del botón. Máximo 30 caracteres.
interactive.action.parameters.url
URL que se abrirá al hacer tap en el botón. Debe ser una URL válida con https://.
A diferencia de los reply buttons, los CTA URL no generan un webhook de respuesta al ser tocados. El usuario simplemente es redirigido al navegador. Si necesitas trackear clics, usa UTM parameters en la URL.
Respuesta del Usuario
Cuando el usuario selecciona un botón o item de lista, recibirás un webhook con el id seleccionado:
Webhook - Botón seleccionado
{
"type" : "interactive" ,
"interactive" : {
"type" : "button_reply" ,
"button_reply" : {
"id" : "hacer_pedido" ,
"title" : "Hacer Pedido"
}
}
}
Webhook - Lista seleccionada
{
"type" : "interactive" ,
"interactive" : {
"type" : "list_reply" ,
"list_reply" : {
"id" : "pizza_pepperoni" ,
"title" : "Pepperoni" ,
"description" : "Pepperoni, mozzarella - $180"
}
}
}
Webhook - Flow enviado por el usuario
{
"type" : "interactive" ,
"interactive" : {
"type" : "nfm_reply" ,
"nfm_reply" : {
"name" : "booking_flow" ,
"body" : "Sucursal Centro · 2026-03-10 16:00" ,
"response_json" : "{ \" screen \" : \" BOOK_APPOINTMENT \" , \" values \" :{ \" branch \" : \" Sucursal Centro \" , \" slot \" : \" 2026-03-10 16:00 \" , \" service \" : \" demo \" }}"
}
}
}
Usa IDs descriptivos como "confirmar_pedido_12345" para facilitar el procesamiento en tu backend.
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" : "interactive" ,
"direction" : "outbound" ,
"status" : "sent" ,
"createdAt" : "2026-01-22T10:30:00Z"
}
}
Límites
Elemento Límite Botones por mensaje 3 Secciones en lista 10 Rows totales en lista 10 Caracteres en body 1024 Caracteres en título de botón 20 Caracteres en display_text (CTA URL) 30 Caracteres en título de row 24 Caracteres en descripción de row 72 Caracteres en footer 60
Comparación: Botones vs Listas vs CTA URL
Aspecto Botones Listas CTA URL Opciones máximas 3 10 1 (un solo botón) Visibilidad Siempre visibles Requiere tap para expandir Siempre visible Header con imagen Sí No (solo texto) Sí Descripciones No Sí No Organización Flat Secciones Botón único Webhook al responder Sí (button_reply) Sí (list_reply) No (abre navegador) Mejor para Decisiones rápidas Catálogos, menús Links externos, pagos
Casos de Uso
{
"type" : "button" ,
"body" : { "text" : "Tu pedido #12345 está listo. ¿Confirmamos envío?" },
"action" : {
"buttons" : [
{ "type" : "reply" , "reply" : { "id" : "confirmar" , "title" : "Confirmar" } },
{ "type" : "reply" , "reply" : { "id" : "modificar" , "title" : "Modificar" } },
{ "type" : "reply" , "reply" : { "id" : "cancelar" , "title" : "Cancelar" } }
]
}
}
{
"type" : "list" ,
"body" : { "text" : "Selecciona tu horario de entrega preferido:" },
"action" : {
"button" : "Ver Horarios" ,
"sections" : [
{
"title" : "Mañana" ,
"rows" : [
{ "id" : "9am" , "title" : "9:00 - 11:00 AM" },
{ "id" : "11am" , "title" : "11:00 - 1:00 PM" }
]
},
{
"title" : "Tarde" ,
"rows" : [
{ "id" : "2pm" , "title" : "2:00 - 4:00 PM" },
{ "id" : "4pm" , "title" : "4:00 - 6:00 PM" }
]
}
]
}
}
{
"type" : "button" ,
"body" : { "text" : "¿Cómo calificarías tu experiencia con nosotros?" },
"action" : {
"buttons" : [
{ "type" : "reply" , "reply" : { "id" : "excelente" , "title" : "😊 Excelente" } },
{ "type" : "reply" , "reply" : { "id" : "buena" , "title" : "🙂 Buena" } },
{ "type" : "reply" , "reply" : { "id" : "mejorar" , "title" : "😕 Puede mejorar" } }
]
}
}
{
"type" : "cta_url" ,
"body" : { "text" : "Tu pedido #12345 por $350 MXN está confirmado. Completa el pago en el siguiente enlace:" },
"footer" : { "text" : "Link válido por 24 horas" },
"action" : {
"name" : "cta_url" ,
"parameters" : {
"display_text" : "Pagar Ahora" ,
"url" : "https://mitienda.com/pago/12345"
}
}
}
{
"type" : "cta_url" ,
"header" : {
"type" : "image" ,
"image" : { "link" : "https://example.com/catalogo-preview.jpg" }
},
"body" : { "text" : "Explora nuestro catálogo completo con más de 200 productos disponibles." },
"action" : {
"name" : "cta_url" ,
"parameters" : {
"display_text" : "Ver Catálogo" ,
"url" : "https://mitienda.com/catalogo"
}
}
}
Flows de WhatsApp
Usa un Flow ya existente en Meta sin necesidad de crearlo desde Whaapy. El contrato sigue el formato nativo de WhatsApp Cloud API: type: "interactive" con interactive.type: "flow".
Ejemplo Básico
{
"to" : "+5215512345678" ,
"type" : "interactive" ,
"interactive" : {
"type" : "flow" ,
"header" : {
"type" : "text" ,
"text" : "Reserva tu cita"
},
"body" : {
"text" : "Completa este flujo para reservar tu cita en menos de 1 minuto."
},
"footer" : {
"text" : "Datos protegidos"
},
"action" : {
"name" : "flow" ,
"parameters" : {
"flow_message_version" : "3" ,
"flow_id" : "123456789012345" ,
"flow_cta" : "Abrir flow" ,
"flow_token" : "lead_987654321" ,
"flow_action" : "navigate" ,
"flow_action_payload" : {
"screen" : "BOOK_APPOINTMENT" ,
"data" : {
"service" : "demo" ,
"source" : "api"
}
}
}
}
}
}
Campos de Flow
interactive.action.parameters.flow_message_version
Actualmente debe ser "3".
interactive.action.parameters.flow_id
ID único del Flow en Meta. Debes enviar flow_id o flow_name, pero no ambos.
interactive.action.parameters.flow_name
Nombre del Flow en Meta. Alternativa a flow_id.
interactive.action.parameters.flow_cta
Texto del CTA visible para abrir el Flow. Recomendado: 30 caracteres o menos.
interactive.action.parameters.flow_token
Token propio de tu negocio para correlacionar la respuesta del Flow.
interactive.action.parameters.flow_action
navigate o data_exchange. Si no lo envías, Meta usa navigate.
interactive.action.parameters.flow_action_payload.screen
Pantalla inicial del Flow cuando usas navigate.
interactive.action.parameters.flow_action_payload.data
Datos iniciales que quieres inyectar a la primera pantalla del Flow.
Próximos Pasos
Enviar Ubicación Comparte coordenadas GPS
Enviar Contactos Comparte tarjetas vCard