Skip to main content

Sending WhatsApp Template Messages via API

Send a pre-approved WhatsApp template to any phone number over HTTPS, from any backend that can make a POST request.

Written by Tarek Khalil

Endpoint

POST https://app.octopods.io/api/v1/whatsapp/templates/{template_id}/messages

  • {template_id} is the ID of the approved WhatsApp template you want to send.

  • Authentication: X-Octopods-Auth: YOUR_WHATSAPP_API_KEY (see API Overview and Authentication).

  • Content type: application/json.

Finding a template ID

Templates must be approved on the WhatsApp channel before they can be sent. Each approved template has a numeric ID you can copy from the Octopods UI:

  1. Open Settings → Channels and select your WhatsApp channel.

  2. Open the Templates tab.

  3. Click the template you want to send. The ID appears in the template details.

Request body

Field

Type

Required

Description

destination_phone

string

Yes

Recipient phone in E.164 format, e.g. +14155552671.

message_variables

object or array

Conditional

Values for the template’s placeholders. Required when the template has variables. See the format details below.

header_attachment_url

string

Conditional

Public URL of the header media file. Required when the template has an image, video, or document header.

destination_user_name

string

No

Display name to associate with the contact if one does not already exist.

open_intercom_conversation

boolean

No

Set to true to open a CRM conversation thread when the message is sent. Defaults to false. Accepts true/false, 1/0, yes/no, on/off.

intercom_teammate_id

string

No

The ID of the teammate the sent message should be attributed to.

Message variable formats

The template determines the shape you must send.

Body-only templates. If every placeholder lives in the template body ({{1}}, {{2}}, …), send an array of strings:

{
  "destination_phone": "+14155552671",
  "message_variables": ["Alex", "1234"]
}

Templates with header, footer, or button placeholders. Send an object with one array per section. Include every section even if it is empty:

{
  "destination_phone": "+14155552671",
  "message_variables": {
    "header": ["Order #1234"],
    "body":   ["Alex", "1234"],
    "footer": [],
    "buttons": ["track/1234"]
  }
}

If the template has non-body placeholders and you send a plain array, the API rejects the request with error code 9.

Media headers

For templates with an image, video, or document header, provide a public URL in header_attachment_url. The URL must be reachable by Octopods’s servers and must point to a file that matches the template’s declared header type.

{
  "destination_phone": "+14155552671",
  "header_attachment_url": "https://example.com/invoice.pdf",
  "message_variables": { "header": [], "body": ["Alex"], "footer": [], "buttons": [] }
}

Full example

curl -X POST "https://app.octopods.io/api/v1/whatsapp/templates/123/messages" \
  -H "X-Octopods-Auth: YOUR_WHATSAPP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "destination_phone": "+14155552671",
    "destination_user_name": "Alex Rivera",
    "message_variables": ["Alex", "1234"],
    "open_intercom_conversation": true
  }'

Successful response

HTTP 201 Created:

{
  "request_id": "abc123…",
  "message_id": 98765,
  "channel_message_id": "provider-id-here"
}

  • message_id — use this value with GET /api/v1/whatsapp/messages/{message_id} to poll delivery status.

  • channel_message_id — the WhatsApp provider’s own ID.

Error codes

Errors return HTTP 400 Bad Request (or HTTP 429 for rate-limit breaches) with:

{ "request_id": "…", "error_code": N, "error": "…" }

Code

Meaning

Fix

1

A required argument is missing (e.g. destination_phone, waba_template_id, header_attachment_url).

Include the named field.

2

message_variables is the wrong type.

Send an array for body-only templates or an object for templates with non-body placeholders.

3

Template does not exist or is not approved on this channel.

Re-check the template ID and confirm it is in the Approved state.

4

The number of variables you supplied does not match the template.

Count the placeholders in the template and supply exactly that many.

5

destination_phone is invalid.

Use E.164 format (leading +, country code, no spaces).

6

Deprecated API key.

Copy the current key from the channel settings screen.

7

WhatsApp provider returned an error.

See the error field; common causes are “recipient not on WhatsApp”, template paused, or a rate limit at the provider.

8

Invalid header media URL.

Confirm the URL is public and the file matches the header’s declared type.

9

Legacy variable format — an array was sent for a template that has header/footer/button variables.

Send message_variables as an object with per-section arrays.

Note: Full details and recovery steps for provider errors are in Troubleshooting Failed Proactive Messages.

Rate limits

WhatsApp endpoints are rate-limited per channel. On a breach, Octopods returns HTTP 429 with a blocked_until timestamp telling you when the block lifts. Pause sends until the timestamp passes.


What’s next

Did this answer your question?