WABA API

Referencia para integrar WhatsApp Business API por rutas públicas de Sendeasy.

Autenticación

Header obligatorio:

Authorization: Bearer <api_token>

Prefijo de rutas

/api/v1/waba/:whatsappId

Templates

MétodoEndpointFinalidad
GET/templatesListar templates
POST/templatesCrear template
PUT/templates/:templateIdActualizar template
DELETE/templates/:templateNameEliminar template

Mensajes

MétodoEndpointFinalidad
POST/sendEnviar template (o texto simple con body específico)
POST/send-textEnviar texto
POST/send-imageEnviar imagen
POST/send-videoEnviar video
POST/send-audioEnviar audio
POST/send-documentEnviar documento
POST/marketing-lite/sendEnviar mensaje de marketing (Marketing Messages Lite API)
GET/messages/:messageId/statusConsultar historial de estados de un mensaje

Nueva API: mensaje de marketing

Endpoint público:

POST /api/v1/waba/:whatsappId/marketing-lite/send

Endpoint Meta usado por el backend:

POST /{phone-number-id}/marketing_messages

Prerrequisitos:

  1. Cuenta WABA con onboarding de Marketing Messages Lite finalizado.
  2. Términos de Marketing Messages Lite aceptados en la cuenta Meta.
  3. Template en categoría MARKETING con estado APPROVED.

Payload

CampoTipoObligatorioObservaciones
tostringnúmero en formato internacional (solo dígitos)
templateNamestringnombre de template aprobado en Meta
languagestringNopor defecto: pt_BR
componentsarrayNocomponentes/parámetros del template
productPolicystringNoCLOUD_API_FALLBACK (default) o STRICT
messageActivitySharingbooleanNopor defecto: true
bizOpaqueCallbackDatastringNoregresa en webhook para correlación de campaña

Ejemplo: envío de mensaje de marketing

curl --location 'https://server.sendeasy.pro/api/v1/waba/SEU_WHATSAPP_ID/marketing-lite/send' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer SEU_API_TOKEN' \
  --data '{
    "to": "5511999999999",
    "templateName": "promo_blackfriday",
    "language": "pt_BR",
    "components": [
      {
        "type": "body",
        "parameters": [
          { "type": "text", "text": "Juan" }
        ]
      }
    ],
    "productPolicy": "CLOUD_API_FALLBACK",
    "messageActivitySharing": true,
    "bizOpaqueCallbackData": "campaign_blackfriday_2026"
  }'

Respuesta de éxito (ejemplo):

{
  "messages": [
    { "id": "wamid.HBg..." }
  ]
}

Error de límite/opt-out (ejemplo):

{
  "error": "MARKETING_LIMIT_REACHED",
  "message": "User has opted out of marketing messages or reached the limit",
  "details": "..."
}

Ejemplo: envío de texto

curl --location 'https://server.sendeasy.pro/api/v1/waba/SEU_WHATSAPP_ID/send-text' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer SEU_API_TOKEN' \
  --data '{
    "to": "5511999999999",
    "text": "¡Hola! Mensaje enviado por la WABA API."
  }'

Ejemplo: envío de template

{
  "to": "5511999999999",
  "templateName": "boas_vindas",
  "language": "pt_BR",
  "components": [
    {
      "type": "body",
      "parameters": [
        { "type": "text", "text": "Juan" }
      ]
    }
  ]
}

Template con header de medios (IMAGE / VIDEO / DOCUMENT)

Cuando el template aprobado tiene un header de medios, hay que enviar el componente header con parameters. Usa type en minúsculas (header/body), y la imagen debe servirse desde una URL pública propia (S3, CDN, etc.) — no uses el header_handle devuelto en la definición del template, expira.

{
  "to": "5511999999999",
  "templateName": "promo_lanzamiento",
  "language": "es_CO",
  "components": [
    {
      "type": "header",
      "parameters": [
        {
          "type": "image",
          "image": { "link": "https://tu-cdn.com/banner.jpg" }
        }
      ]
    }
  ]
}

Alternativamente, reemplaza link por id con el media_id devuelto por la subida en /api/v1/waba/:whatsappId/media.

Consulta de estado de mensaje

La Cloud API de Meta no expone un endpoint público para consultar el estado bajo demanda — el estado se entrega exclusivamente por webhook (sent / delivered / read / failed). Sendeasy persiste cada evento recibido y entrega el historial en esta ruta, con el mismo formato del payload del webhook.

GET /api/v1/waba/:whatsappId/messages/:messageId/status

Ejemplo

curl --location 'https://server.sendeasy.pro/api/v1/waba/TU_WHATSAPP_ID/messages/wamid.HBg.../status' \
  --header 'Authorization: Bearer TU_API_TOKEN'

Respuesta

{
  "statuses": [
    {
      "id": "wamid.HBgMNTUzMT...",
      "status": "sent",
      "timestamp": "1710000000",
      "recipient_id": "5511999999999"
    },
    {
      "id": "wamid.HBgMNTUzMT...",
      "status": "failed",
      "timestamp": "1710000003",
      "recipient_id": "5511999999999",
      "errors": [
        { "code": 131026, "title": "Message undeliverable" }
      ]
    }
  ]
}

Cuando aún no hay eventos registrados para el messageId, la respuesta es 404 con statuses: [] — basta con reintentar tras unos segundos. Solo los mensajes enviados por el canal WABA tienen estado persistido en esta ruta.

Códigos de error comunes

CódigoCuándo ocurre
WHATSAPP_NOT_FOUNDwhatsappId no existe
WHATSAPP_CREDENTIALS_MISSINGcanal sin credenciales WABA completas
MISSING_PARAMETERSfaltan campos obligatorios del payload
MARKETING_LIMIT_REACHEDcontacto con opt-out o límite de marketing alcanzado
WHATSAPP_API_ERRORerror devuelto por la API de Meta

Webhooks WABA (contrato público)

Cuando el webhook del proyecto está habilitado, Sendeasy envía:

  1. event: "messaging" para eventos de mensaje.
  2. event: "message_status" para actualizaciones de estado de entrega.

Ejemplo (messaging):

{
  "event": "messaging",
  "channel": "waba",
  "data": {},
  "channelId": "uuid-del-canal"
}

Ejemplo (message_status):

{
  "event": "message_status",
  "channel": "whatsapp",
  "data": {
    "messageId": "wamid.HBg...",
    "status": "read",
    "timestamp": "1713800010"
  },
  "channelId": "uuid-del-canal"
}

Valores comunes de data.status:

  • sent
  • delivered
  • read
  • failed

Essa informação foi útil?