Skip to content

Messages

The Messages API allows you to send various types of WhatsApp messages including text, media, templates, and interactive messages.

Retrieve messages for a specific contact.

Terminal window
GET /api/contacts/{id}/messages

| Parameter | Type | Description | |-----------|------|-------------| | page | integer | Page number (default: 1) | | limit | integer | Items per page (default: 50, max: 100) | | before | string | Get messages before this message ID | | after | string | Get messages after this message ID |

{
"status": "success",
"data": {
"items": [
{
"id": "uuid",
"wa_message_id": "wamid.xxx",
"contact_id": "uuid",
"direction": "incoming",
"type": "text",
"content": {
"text": "Hello!"
},
"status": "delivered",
"timestamp": "2024-01-01T12:00:00Z"
}
],
"total": 100,
"page": 1,
"limit": 50
}
}

Send a text message to a contact.

Terminal window
POST /api/contacts/{id}/messages
{
"type": "text",
"text": "Hello! How can I help you today?"
}
{
"status": "success",
"data": {
"id": "uuid",
"wa_message_id": "wamid.xxx",
"status": "sent",
"timestamp": "2024-01-01T12:00:00Z"
}
}

Send a pre-approved template message.

Terminal window
POST /api/messages/template

| Field | Type | Required | Description | |-------|------|----------|-------------| | contact_id | string | One of contact_id or phone_number | UUID of existing contact | | phone_number | string | One of contact_id or phone_number | Phone number (creates contact if not exists) | | template_name | string | One of template_name or template_id | Name of the template | | template_id | string | One of template_name or template_id | UUID of the template | | template_params | object | No | Named or positional body parameters | | header_params | object | No | Value for a TEXT header with a {{var}} (max 1). Keyed by the variable's name for named templates, or "1" for positional. Falls back to template_params if omitted. | | button_params | object | No | Dynamic URL button parameters (button index → value) | | account_name | string | No | Specific WhatsApp account to use |

Using phone number (creates contact if needed):

Terminal window
curl -X POST "http://your-server:8080/api/messages/template" \
-H "X-API-Key: whm_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"phone_number": "919876543210",
"template_name": "hello_world"
}'
{
"phone_number": "919876543210",
"template_name": "hello_world"
}

With named parameters:

If your template has placeholders like Hello {{name}}, your order {{order_id}} is ready:

{
"contact_id": "uuid",
"template_name": "order_confirmation",
"template_params": {
"name": "John",
"order_id": "12345"
}
}

With positional parameters:

{
"phone_number": "919876543210",
"template_name": "order_confirmation",
"template_params": {
"1": "John",
"2": "12345"
}
}

With a TEXT header variable:

Meta allows at most one variable in a TEXT header. If your template's header is Our {{season}} sale is on!, supply the value via header_params:

{
"phone_number": "919876543210",
"template_name": "seasonal_promotion",
"header_params": {
"season": "Summer"
},
"template_params": {
"customer_name": "John",
"discount": "25%"
}
}

For a positional header (Our {{1}} sale is on!), use "1" as the key. If you omit header_params, the value is looked up in template_params by the same name — convenient for named templates where the header variable doesn't collide with a body variable.

With URL button parameters:

If your template has a URL button with a dynamic variable (e.g., https://example.com/track/{{1}}), provide the dynamic value via button_params. The key is the button index (starting from "0"):

{
"contact_id": "uuid",
"template_name": "order_shipped",
"template_params": {
"name": "John",
"order_id": "12345"
},
"button_params": {
"0": "12345"
}
}
{
"status": "success",
"data": {
"message_id": "uuid",
"phone_number": "919876543210",
"status": "pending",
"template_name": "order_confirmation"
}
}

Send an image, video, document, or audio message.

Terminal window
POST /api/messages/media
{
"contact_id": "uuid",
"type": "image",
"media_url": "https://example.com/image.jpg",
"caption": "Check out this product!"
}

| Type | Formats | Max Size | |------|---------|----------| | image | JPEG, PNG | 5 MB | | video | MP4, 3GPP | 16 MB | | audio | AAC, MP3, OGG | 16 MB | | document | PDF, DOC, XLS, PPT | 100 MB |

{
"status": "success",
"data": {
"id": "uuid",
"wa_message_id": "wamid.xxx",
"status": "sent"
}
}

Send interactive messages with buttons or CTA URLs.

Terminal window
POST /api/contacts/{id}/messages

Send a message with up to 3 quick reply buttons:

Terminal window
curl -X POST "http://your-server:8080/api/contacts/{contact_id}/messages" \
-H "X-API-Key: whm_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"type": "interactive",
"interactive": {
"type": "button",
"body": "How would you like to proceed?",
"buttons": [
{ "id": "yes", "title": "Yes" },
{ "id": "no", "title": "No" }
]
}
}'
{
"type": "interactive",
"interactive": {
"type": "button",
"body": "How would you like to proceed?",
"buttons": [
{ "id": "yes", "title": "Yes" },
{ "id": "no", "title": "No" }
]
}
}

Send a message with a call-to-action URL button:

Terminal window
curl -X POST "http://your-server:8080/api/contacts/{contact_id}/messages" \
-H "X-API-Key: whm_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"type": "interactive",
"interactive": {
"type": "cta_url",
"body": "Click below to view your order details",
"button_text": "View Order",
"url": "https://example.com/orders/12345"
}
}'
{
"type": "interactive",
"interactive": {
"type": "cta_url",
"body": "Click below to view your order details",
"button_text": "View Order",
"url": "https://example.com/orders/12345"
}
}
{
"status": "success",
"data": {
"id": "uuid",
"wa_message_id": "wamid.xxx",
"status": "sent"
}
}

Mark a message as read.

Terminal window
PUT /api/messages/{id}/read
{
"status": "success",
"data": null
}

Messages go through the following status flow:

| Status | Description | |--------|-------------| | pending | Message queued for sending | | sent | Message sent to WhatsApp servers | | delivered | Message delivered to recipient's device | | read | Message read by recipient | | failed | Message failed to send |

Text

Plain text messages

Image

JPEG, PNG images with optional caption

Video

MP4 videos with optional caption

Document

PDF, Word, Excel, and other documents

Audio

Voice messages and audio files

Template

Pre-approved message templates

Interactive

Buttons, lists, and reply buttons

Flow

WhatsApp Flows