WABA API

Reference for WhatsApp Business API integration through Sendeasy public routes.

Authentication

Required header:

Authorization: Bearer <api_token>

Route prefix

/api/v1/waba/:whatsappId

Templates

MethodEndpointPurpose
GET/templatesList templates
POST/templatesCreate template
PUT/templates/:templateIdUpdate template
DELETE/templates/:templateNameDelete template

Messages

MethodEndpointPurpose
POST/sendSend template (or plain text with specific payload body)
POST/send-textSend text
POST/send-imageSend image
POST/send-videoSend video
POST/send-audioSend audio
POST/send-documentSend document
POST/marketing-lite/sendSend marketing message (Marketing Messages Lite API)
GET/messages/:messageId/statusFetch status history for a message

New API: marketing message

Public endpoint:

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

Meta endpoint used by the backend:

POST /{phone-number-id}/marketing_messages

Prerequisites:

  1. WABA account with Marketing Messages Lite onboarding completed.
  2. Marketing Messages Lite terms accepted in Meta account.
  3. Template in MARKETING category with APPROVED status.

Payload

FieldTypeRequiredNotes
tostringYesinternational number format (digits only)
templateNamestringYesapproved template name in Meta
languagestringNodefault: pt_BR
componentsarrayNotemplate components/parameters
productPolicystringNoCLOUD_API_FALLBACK (default) or STRICT
messageActivitySharingbooleanNodefault: true
bizOpaqueCallbackDatastringNoechoed back in webhook for campaign correlation

Example: send marketing message

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

Success response (example):

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

Limit/opt-out error (example):

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

Example: send text

curl --location 'https://server.sendeasy.pro/api/v1/waba/YOUR_WHATSAPP_ID/send-text' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_API_TOKEN' \
  --data '{
    "to": "5511999999999",
    "text": "Hello! Message sent through WABA API."
  }'

Example: send template

{
  "to": "5511999999999",
  "templateName": "welcome",
  "language": "en_US",
  "components": [
    {
      "type": "body",
      "parameters": [
        { "type": "text", "text": "John" }
      ]
    }
  ]
}

Template with media header (IMAGE / VIDEO / DOCUMENT)

When the approved template has a media header, you must send the header component with parameters. Use lowercase type (header/body), and the image must be served from a public URL of your own (S3, CDN, etc.) — do not use the header_handle returned in the template definition, it expires.

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

Alternatively, replace link with id using the media_id returned by upload at /api/v1/waba/:whatsappId/media.

Message status lookup

Meta's Cloud API does not expose a public endpoint to query message status on demand — status is delivered exclusively via webhook (sent / delivered / read / failed). Sendeasy persists every received event and serves the full history at this route, in the same format as the webhook payload.

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

Example

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

Response

{
  "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" }
      ]
    }
  ]
}

When no event has been recorded yet for the messageId, the response is 404 with statuses: [] — just retry after a few seconds. Only messages sent through the WABA channel have their status persisted at this route.

Common error codes

CodeTypical cause
WHATSAPP_NOT_FOUNDwhatsappId does not exist
WHATSAPP_CREDENTIALS_MISSINGchannel missing required WABA credentials
MISSING_PARAMETERSrequired payload fields are missing
MARKETING_LIMIT_REACHEDrecipient opted out or marketing limit was reached
WHATSAPP_API_ERRORerror returned by Meta API

WABA webhooks (public contract)

When project webhook is enabled, Sendeasy sends:

  1. event: "messaging" for message events.
  2. event: "message_status" for delivery status updates.

Example (messaging):

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

Example (message_status):

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

Common data.status values:

  • sent
  • delivered
  • read
  • failed

Essa informação foi útil?