REST API
Every endpoint is org-scoped. Pass Authorization: Bearer <token> and x-org-id: <orgId> on each request.
Send a WhatsApp message
POST /orgs/:orgId/conversations/:conversationId/messages
curl -X POST https://webhook.badala.app/orgs/<orgId>/conversations/<convId>/messages \
-H 'Authorization: Bearer <token>' \
-H 'x-org-id: <orgId>' \
-H 'Content-Type: application/json' \
-d '{
"type": "TEXT",
"body": "Hello from the API"
}'For media, send the public URL (any host CDN works) plus type:
{
"type": "IMAGE",
"mediaUrl": "https://assets.badala.app/orgs/<orgId>/uploads/abc.jpg",
"caption": "Optional caption"
}Send a template (broadcast / first-touch)
Required if the customer hasn't messaged in the last 24 hours. Templates must be approved in Meta Business Manager beforehand.
POST /orgs/:orgId/channels/:channelId/templates/send
{
"to": "+96567666156",
"templateName": "appointment_reminder",
"templateLanguage": "en",
"variables": ["Yousef", "May 9 at 4pm"]
}Contacts
| Method | Path | Purpose |
|---|---|---|
GET | /orgs/:orgId/contacts?search=&take=&skip= | List + search |
GET | /orgs/:orgId/contacts/:contactId | Detail incl. conversations |
POST | /orgs/:orgId/contacts | Upsert (by phone) |
PATCH | /orgs/:orgId/contacts/:contactId | Update |
POST | /orgs/:orgId/contacts/import | Bulk CSV import |
Conversations
| Method | Path | Purpose |
|---|---|---|
GET | /orgs/:orgId/conversations | List (filtered by status, channel, assignee) |
GET | /orgs/:orgId/conversations/:id/messages | Message history |
PATCH | /orgs/:orgId/conversations/:id/status | Open / closed |
PATCH | /orgs/:orgId/conversations/:id/assignee | Assign teammate |
Real-time updates
The web app uses Socket.IO at the same origin (wss://webhook.badala.app) for live message push. For server-to-server integrations, use outbound webhooks instead — they're durable and signed.
Rate limits
Outbound WhatsApp messages: gated by Meta's tier (Tier 1 = 80 msg/sec, Tier 2 = 200 msg/sec, etc). Broadcasts respect this internally with a configurable gap. Direct API calls are not rate-limited by Badala beyond what Meta enforces upstream.