Send WhatsApp Messages
Send an approved WhatsApp template message to any phone number.
POST /v1/whatsapp/sendRequest body
| Field | Type | Required | Description |
|---|---|---|---|
to | string | ✓ | Recipient phone number in E.164 format (e.g. +254700000000) |
phone_number_id | string | ✓ | Your sending phone number id from /v1/whatsapp/phone_numbers |
template_name | string | ✓ | The template name from the templates endpoint |
language_code | string | ✓ | The template language from the templates endpoint (e.g. en_US) |
variables | object | — | Template placeholder values. See Template Variables. |
media_url | string | — | Public URL of media to use as template header. Alternative to media_id. See Sending with Media. |
media_id | string | — | media_id from the upload endpoint. Alternative to media_url. See Sending with Media. |
catalog_id | string | — | Meta catalog ID the products in variables.cards belong to. Required for Product Carousels. |
location | object | For location templates | Latitude, longitude, name, and address for a template with a location header. See Location Templates. |
The variables object holds one entry per template section:
| Field | Type | Description |
|---|---|---|
variables.header | object | Header placeholder values, keyed by param_name |
variables.body | object | Body placeholder values, keyed by param_name |
variables.buttons | object | Dynamic URL button values, keyed by button position. See Button Variables. |
variables.cards | object | Carousel cards, keyed by card position starting at "1". See Carousels. |
Use the exact template_name and language_code as returned by the templates endpoint. Phone numbers are identified by their phone number ID (id field), not the phone number itself.
Sending a message template
If the template has no placeholders, omit the variables field entirely.
cURL
curl -X POST https://api.bahasha.app/v1/whatsapp/send \
-H "Authorization: Bearer bh_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"to": "+254700000000",
"phone_number_id": "123456789",
"template_name": "hello_world",
"language_code": "en_US"
}'Response
{
"success": true,
"message_id": "wamid.HBgNMjU0NzAwMDAwMDAwFQIAERgSNDQ1...",
"to": "+254700000000",
"template": "order_confirmation"
}A successful response means the request was accepted — it does not guarantee delivery. Use webhooks to track delivery status (sent, delivered, read, failed).
Choose your scenario
Everything else you can send is a variation on the request above.
Fill named and positional placeholders in the header and body.
Template VariablesSend one-time passcodes with authentication templates.
Authentication (OTP)Append dynamic values to URL buttons, including two-button templates.
Button VariablesOverride the template’s header image, video, or document per send.
Sending with MediaSend an approved template with a place in its header.
Location TemplatesSend multi-card carousels and fill each card’s own variables.
CarouselsShow 2–10 products from your Meta catalog, chosen at send time.
Product Carousels