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
| Method | Endpoint | Purpose |
|---|---|---|
GET | /templates | List templates |
POST | /templates | Create template |
PUT | /templates/:templateId | Update template |
DELETE | /templates/:templateName | Delete template |
Messages
| Method | Endpoint | Purpose |
|---|---|---|
POST | /send | Send template (or plain text with specific payload body) |
POST | /send-text | Send text |
POST | /send-image | Send image |
POST | /send-video | Send video |
POST | /send-audio | Send audio |
POST | /send-document | Send document |
POST | /marketing-lite/send | Send marketing message (Marketing Messages Lite API) |
GET | /messages/:messageId/status | Fetch 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:
- WABA account with Marketing Messages Lite onboarding completed.
- Marketing Messages Lite terms accepted in Meta account.
- Template in
MARKETINGcategory withAPPROVEDstatus.
Payload
| Field | Type | Required | Notes |
|---|---|---|---|
to | string | Yes | international number format (digits only) |
templateName | string | Yes | approved template name in Meta |
language | string | No | default: pt_BR |
components | array | No | template components/parameters |
productPolicy | string | No | CLOUD_API_FALLBACK (default) or STRICT |
messageActivitySharing | boolean | No | default: true |
bizOpaqueCallbackData | string | No | echoed 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
| Code | Typical cause |
|---|---|
WHATSAPP_NOT_FOUND | whatsappId does not exist |
WHATSAPP_CREDENTIALS_MISSING | channel missing required WABA credentials |
MISSING_PARAMETERS | required payload fields are missing |
MARKETING_LIMIT_REACHED | recipient opted out or marketing limit was reached |
WHATSAPP_API_ERROR | error returned by Meta API |
WABA webhooks (public contract)
When project webhook is enabled, Sendeasy sends:
event: "messaging"for message events.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:
sentdeliveredreadfailed