Volver al blog
Desarrolladores

Cómo reaccionar a un mensaje por la API de WhatsApp

POST /messages con type reaction, el waMessageId y un emoji. Un emoji vacío saca la reacción. Si la ventana de 24 horas está cerrada, la API responde 403.

· 9 min
Cómo reaccionar a un mensaje por la API de WhatsApp

Respuesta corta: para poner un emoji sobre un mensaje, POST https://api.waspytech.com/api/v2/messages con type: "reaction", el waMessageId en reaction.message_id y el emoji en reaction.emoji. Un emoji "" saca la reacción que habías puesto. Si la ventana de 24 horas está cerrada, la API responde 403 SERVICE_WINDOW_EXPIRED.

El contrato está en Messages. El scope es messages:write.

El pedido

message_id es el waMessageId del webhook message.received (empieza con wamid.), no el UUID interno del mensaje en Waspy.

curl -sS -X POST "https://api.waspytech.com/api/v2/messages" \
  -H "Authorization: Bearer $WASPY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: reaccion-wamid-HBgL-ok" \
  -d '{
    "phoneNumberId": "UUID-DEL-CANAL",
    "to": "+5491126032641",
    "type": "reaction",
    "reaction": { "message_id": "wamid.HBgL...", "emoji": "👍" }
  }'

phoneNumberId es el id de GET /api/v2/channels, el UUID del canal en Waspy. to va en E.164. La respuesta 201 trae el mensaje con status: "queued", origin: "external_api" y waMessageId: null hasta que sale. El estado siguiente llega en message.status_changed.

Para sacarla:

curl -sS -X POST "https://api.waspytech.com/api/v2/messages" \
  -H "Authorization: Bearer $WASPY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: reaccion-wamid-HBgL-sacar" \
  -d '{
    "phoneNumberId": "UUID-DEL-CANAL",
    "to": "+5491126032641",
    "type": "reaction",
    "reaction": { "message_id": "wamid.HBgL...", "emoji": "" }
  }'

La clave de sacar es otra: la primera ya quedó guardada 24 horas con el 👍. Idempotency-Key se compara como texto, hasta 256 caracteres. El mecanismo está en idempotencia y scopes.

La ventana de 24 horas

Una reacción no es una plantilla. El envío por API exige la ventana abierta, igual que un texto o una foto. Si serviceWindowExpiresAt está vacío o vencido, no se encola: 403 SERVICE_WINDOW_EXPIRED.

Esa fecha está en GET /api/v2/conversations/:id. La regla de negocio está en la ventana de 24 horas.

PedidoVentana cerradaVentana abierta
type: "reaction"403, no saleSe encola
type: "text"403Mensaje de servicio
type: "template"Sale, y Meta lo cobra según la categoríaTambién se cobra, desde el 1 de octubre de 2026
En Argentina, desde el 1 de octubre de 2026, el texto dentro de la ventana entra en las 1.000 respuestas de servicio del número. La reacción es otro envío de sesión: no la uses para “ahorrar” un mensaje que el cliente necesita leer. La tarifa está en la rate card.

Para qué sirve, y para qué no

Sirve para acusar recibo de un “listo, pagué” o de un comprobante sin meter otro globo de “recibido, gracias, ya lo vemos”. El cliente ve el emoji sobre su mensaje.

No reemplaza:

  • el aviso de despacho (eso es una plantilla de utilidad, con el código de seguimiento);
  • una pregunta de talle (hace falta texto);
  • el handoff. La reacción queda como external_api. Una persona en el inbox queda como panel. Si tu bot tiene que callarse cuando el equipo escribe, la señal es esa, en handoff con origin.

Tampoco hay un POST /templates para crear la plantilla que vas a necesitar cuando la ventana cierre. Las plantillas se leen con GET /templates, GET /templates/:id y GET /templates/by-name/:name, y se arman en el panel. El listado está en listar plantillas.

La API está en Scale y Enterprise. El detalle de planes está en Planes y en la página de la API. Para probar el número, el registro son 10 días sin tarjeta.

Tu equipo atendiendo por WhatsApp en minutos

CRM facil pero potente. En 10 minutos tenes a tu equipo trabajando — no necesitas hablar con nadie.