Skip to main content

Send Template Message

Send a WhatsApp message to a contact using an approved message template. This is the primary way to reach contacts — template messages can be sent anytime, even outside the 24-hour customer service window.

POST /api/v1/messages/send

Request body

FieldTypeRequiredDescription
template_namestringYesName of your approved template (case-sensitive)
contact_phonestringYesPhone number with country code, without + (e.g., 911234567890)
contact_namestringNoContact's name. Defaults to User #<random> if omitted
body_dataobjectNoTemplate body variables as key-value pairs. Defaults to empty {}. Required if your template has variables like {{1}}, {{2}}
header_dataobjectNoHeader variables — only needed for templates with a text header that contains variables
media_urlstringNoPublicly accessible URL for image, video, or document. Required if template has a media header
filenamestringNoFilename for document attachments (defaults to untitled)
waba_phone_idstringNoWhich WhatsApp number to send from (uses your default number if omitted)
Auto-created contacts

If the contact phone number doesn't exist in your Waplify account, the contact will be created automatically when you send the message. The source will be set to api.

Understanding template variables

Templates use placeholders like {{1}}, {{2}} for personalized content. You fill these in via body_data when sending.

How to know which variables your template needs:

  1. Call the List Templates endpoint
  2. Look at the body field — it shows the template text with placeholders
  3. Look at header_format — if it's IMAGE, VIDEO, or DOCUMENT, you need a media_url
  4. Look at requires_media — if true, a media_url is required

Variable types

Positional variables (most common): {{1}}, {{2}}, {{3}} Pass them as string keys:

{
"body_data": { "1": "John", "2": "Premium Plan", "3": "99" }
}

Named variables: {{name}}, {{company}}, {{amount}} Pass them with the exact key name (case-sensitive):

{
"body_data": { "name": "John", "company": "Acme Corp", "amount": "99" }
}

Examples

Basic template (body variables only)

curl -X POST https://server.waplify.io/api/v1/messages/send \
-H "Authorization: Bearer wapl_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"template_name": "order_confirmation",
"contact_phone": "911234567890",
"contact_name": "John Doe",
"body_data": {
"1": "John",
"2": "Premium Plan",
"3": "99"
}
}'

Template with text header variables

curl -X POST https://server.waplify.io/api/v1/messages/send \
-H "Authorization: Bearer wapl_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"template_name": "daily_report",
"contact_phone": "911234567890",
"contact_name": "John Doe",
"header_data": {
"1": "Daily Checkup"
},
"body_data": {
"1": "Rahul"
}
}'

Template with image header

curl -X POST https://server.waplify.io/api/v1/messages/send \
-H "Authorization: Bearer wapl_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"template_name": "promo_image",
"contact_phone": "911234567890",
"contact_name": "John Doe",
"body_data": {
"1": "John",
"2": "50%"
},
"media_url": "https://example.com/promo-banner.png"
}'

Template with video header

curl -X POST https://server.waplify.io/api/v1/messages/send \
-H "Authorization: Bearer wapl_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"template_name": "product_video",
"contact_phone": "911234567890",
"contact_name": "John Doe",
"body_data": {
"1": "John"
},
"media_url": "https://example.com/product-demo.mp4"
}'

Template with document header

curl -X POST https://server.waplify.io/api/v1/messages/send \
-H "Authorization: Bearer wapl_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"template_name": "invoice_template",
"contact_phone": "911234567890",
"contact_name": "John Doe",
"body_data": {
"1": "John"
},
"media_url": "https://example.com/invoice-june.pdf",
"filename": "Invoice June 2024.pdf"
}'

Success response

{
"status": "success",
"message": "Message sent successfully",
"message_id": "wamid.HBgNOTE4MDMxMjM0NTY3OA==",
"contact_id": "507f1f77bcf86cd799439012",
"template_name": "order_confirmation",
"timestamp": "2024-06-15T10:00:00Z"
}
FieldDescription
message_idWhatsApp's message ID — use this to track delivery via webhooks
contact_idThe contact's ID in Waplify (created automatically if new)
timestampWhen the message was accepted (ISO 8601 format)
"Success" means accepted, not delivered

A "status": "success" response does not mean the message has been delivered to the contact's phone. It only means WhatsApp has accepted your message and will attempt to deliver it.

What happens after a successful response:

  1. API returns success → WhatsApp accepted the message
  2. message.sent webhook → WhatsApp started processing the message
  3. message.delivered webhook → Message reached the contact's phone
  4. message.read webhook → Contact opened and read the message

If delivery fails at any point, you receive a message.failed webhook with the error details.

To track actual delivery, set up webhooks and listen for the message.delivered event. Do not assume a success API response means the message was delivered.

Error responses

Missing template variables

// 400 Bad Request
{
"error": "bad_request",
"message": "Missing body variables in 'body_data': 2, 3"
}

Template not approved

// 400 Bad Request
{
"error": "bad_request",
"message": "Template 'my_template' is not approved. Status: PENDING"
}

Template not found

// 404 Not Found
{
"error": "not_found",
"message": "Template 'nonexistent_template' not found"
}

Media required but not provided

// 400 Bad Request
{
"error": "bad_request",
"message": "Media URL is required for this template"
}

Invalid phone number

// 400 Bad Request
{
"error": "bad_request",
"message": "Invalid phone number format"
}

Media file limits

TypeMax SizeAccepted Formats
Image5 MBJPEG, PNG
Video16 MBMP4
Document100 MBPDF, DOC, DOCX, PPT, PPTX, TXT