Skip to main content

Send WhatsApp Message

Send text, media, template, or interactive messages via WhatsApp.

Request Parameters

ParameterRequiredTypeDescription
fromMandatoryStringYour WhatsApp-enabled phone number (E.164)
toMandatoryStringRecipient phone number (E.164)
contentMandatoryObjectMessage content object (see below)
status_callbackOptionalStringWebhook URL for delivery status updates
custom_dataOptionalStringApplication-specific metadata

Content Object

{
"recipient_type": "individual",
"type": "text",
"text": {
"body": "Hello! How can we help you today?"
}
}

Supported Content Types

Text:

{ "type": "text", "text": { "body": "Your message here", "preview_url": false } }

preview_url (optional boolean): set to true to show a URL preview if the body contains an https:// or http:// link.

Image:

{ "type": "image", "image": { "link": "https://example.com/image.jpg", "caption": "Check this out" } }

Audio:

{ "type": "audio", "audio": { "link": "https://example.com/audio.mp3" } }

Video:

{ "type": "video", "video": { "link": "https://example.com/video.mp4", "caption": "Watch this" } }

Document:

{ "type": "document", "document": { "link": "https://example.com/invoice.pdf", "caption": "Invoice", "filename": "invoice.pdf" } }

filename controls the display name and format shown in WhatsApp.

Sticker:

{ "type": "sticker", "sticker": { "link": "https://example.com/sticker.webp" } }

Static stickers: 512×512 px, max 100 KB, image/webp. Animated stickers: 512×512 px, max 500 KB, image/webp.

Location:

{ "type": "location", "location": { "longitude": 77.5946, "latitude": 12.9716, "name": "Exotel Office", "address": "Bangalore, India" } }

name and address are optional; address is only displayed when name is also provided.

Contacts:

{
"type": "contacts",
"contacts": [{
"name": { "formatted_name": "John Doe", "first_name": "John", "last_name": "Doe" },
"phones": [{ "phone": "+919876543210", "type": "CELL" }],
"emails": [{ "email": "john@example.com", "type": "WORK" }],
"org": { "company": "Acme Corp", "title": "Engineer" }
}]
}

Interactive (Reply Buttons):

{
"type": "interactive",
"interactive": {
"type": "button",
"header": { "type": "text", "text": "Order Update" },
"body": { "text": "Choose an option:" },
"footer": { "text": "Reply below" },
"action": {
"buttons": [
{ "type": "reply", "reply": { "id": "btn_yes", "title": "Yes" } },
{ "type": "reply", "reply": { "id": "btn_no", "title": "No" } }
]
}
}
}

Up to 3 reply buttons. Button title max 20 characters, button id max 256 characters.

Interactive (List Message):

{
"type": "interactive",
"interactive": {
"type": "list",
"header": { "type": "text", "text": "Choose a category" },
"body": { "text": "Select an option from the list below" },
"footer": { "text": "Powered by Exotel" },
"action": {
"button": "View Options",
"sections": [
{
"title": "Support",
"rows": [
{ "id": "row_billing", "title": "Billing", "description": "Payment and invoice queries" },
{ "id": "row_tech", "title": "Technical", "description": "Product and technical issues" }
]
}
]
}
}
}

action.button (string, max 20 chars) is the list button label. Up to 10 sections, up to 10 rows total across all sections. Row title max 24 chars, description max 72 chars, id max 200 chars. Section title is required when there are multiple sections (max 24 chars).

Interactive Header types: text (max 60 chars), image, video, document. Header is optional for list messages.

Interactive Body: max 1024 characters. Interactive Footer: max 60 characters.

Code Examples

curl -u '<api_key>:<api_token>' -X POST "https://api.exotel.com/v2/accounts/<your_sid>/messages" \
-H "Content-Type: application/json" \
-d '{
"from": "+919876500001",
"to": "+919876543210",
"content": {
"recipient_type": "individual",
"type": "text",
"text": { "body": "Hello from Exotel!" }
},
"status_callback": "https://your-server.com/wa-status"
}'

Response

HTTP 202 Accepted

{
"request_id": "b434e927a5844175b23059cd96feea3d",
"method": "POST",
"http_code": 202,
"metadata": {
"total": 1,
"success": 1,
"failed": 0
},
"response": {
"whatsapp": {
"messages": [
{
"code": 202,
"error_data": null,
"status": "success",
"data": {
"sid": "2FdiiEQUosckPhpZfuVwfjxiSlc16a4"
}
}
]
}
}
}

Response Fields

FieldDescription
request_idUnique ID of the request — use for debugging and tracing
methodHTTP method of the request (e.g., POST)
http_codeHTTP status code
metadata.totalTotal messages in the request
metadata.successMessages successfully accepted
metadata.failedMessages that failed to be accepted
response.whatsapp.messages[].codePer-message HTTP response code
response.whatsapp.messages[].error_dataError details for a failed message (null on success), with code, message, and description
response.whatsapp.messages[].statusPer-message status (success or failed)
response.whatsapp.messages[].data.sidUnique SID of the message — log this for future tracking

HTTP Status Codes

CodeDescription
202Message accepted for delivery
400Malformed request
401Authentication failed
402Plan limit exceeded
403Access denied
404Resource not found
5xxServer error — retry the request

Try It