Skip to main content

Send WhatsApp Template Message

Full reference for the endpoint that sends an approved WhatsApp template message from your backend to a customer's WhatsApp number.

Written by Tarek Khalil

Endpoint

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

The template’s ID is part of the URL path — not a body field. You can find it on the template’s detail page in Octopods or via the list templates endpoint.

Only templates in Accepted state are accepted by this endpoint.

Authentication

Include your WhatsApp Business API Key in the request header:

X-Octopods-Auth: YOUR_WHATSAPP_BUSINESS_API_KEY

See API Key Authentication for how to find this key.

Required parameters

Send the request body as JSON with Content-Type: application/json.

  • destination_phone — the recipient’s phone number in E.164 format (for example, +15551234567). Numbers that fail validation are rejected with error code 5 (PHONE_INVALID).

  • message_variables — the substitution values for any {{N}} placeholders the template contains. Structure depends on which sections of the template have variables (see below).

If the template has no variables, message_variables can be omitted.

Optional parameters

  • header_attachment_url — required only if the template’s header is a media header (image, video, or document). The URL must be publicly reachable and must match the header’s media type. Required but missing returns error code 1 (ARGUMENT_MISSING); invalid URL returns error code 8 (INVALID_HEADER).

  • open_intercom_conversationtrue to open a new conversation in Intercom or HubSpot alongside the send, false (default) to send without opening a conversation. Accepts true, false, 1, 0, yes, no, on, off.

  • intercom_teammate_id — the ID of the Intercom teammate who should appear as the sender. Defaults to the workspace’s configured default sender.

  • destination_user_name — display name to attach to the contact when the conversation is created. Optional; used only when open_intercom_conversation is true and the contact does not already exist.

Variable structure

WhatsApp templates can have variables in four places: header text, body, footer, and URL buttons. The shape of message_variables depends on where your template’s variables live.

Body-only variables — array shape

When a template has variables only in the body, you may pass message_variables as a flat array whose order matches {{1}}, {{2}}, {{3}}, and so on.

{
  "destination_phone": "+15551234567",
  "message_variables": ["Jane", "ORD-9876", "April 28"]
}

Any other case — object shape

When a template has variables in the header, footer, or URL buttons (or any combination), message_variables must be an object with one array per section. Sending a flat array in this case returns error code 9 (LEGACY_VARIABLES_TYPE).

{
  "destination_phone": "+15551234567",
  "message_variables": {
    "header": ["Jane"],
    "body": ["ORD-9876", "April 28"],
    "footer": [],
    "buttons": ["https://example.com/track/ORD-9876"]
  }
}

Every array must contain exactly as many values as the template has placeholders for that section. Mismatched counts return error code 4 (VARIABLES_SIZE) with the expected total count in the error message.

Example request

POST https://app.octopods.io/api/v1/whatsapp/templates/84579/messages
X-Octopods-Auth: YOUR_WHATSAPP_BUSINESS_API_KEY
Content-Type: application/json{
  "destination_phone": "+15551234567",
  "message_variables": {
    "header": ["Jane"],
    "body": ["ORD-9876", "April 28"],
    "footer": [],
    "buttons": []
  },
  "open_intercom_conversation": true
}

Success response

On success the API returns HTTP 201 Created with a JSON body:

{
  "request_id": "e23080fd-8b63-460e-83bd-cf5d2c1497b6",
  "message_id": 3851828,
  "message_status_url": "https://app.octopods.io/api/v1/whatsapp/messages/3851828",
  "phone_number": "+15551234567",
  "channel_message_id": "wamid.HBgNNTUxMTk3MjI3ODA2MhUCABEYE..."
}

  • request_id — unique ID for this API request. Quote this when contacting support.

  • message_id — Octopods’ internal ID for the message. Use it with the status endpoint.

  • message_status_url — a ready-made link to the status endpoint for this message.

  • phone_number — the number the message was sent to.

  • channel_message_id — the ID assigned by WhatsApp (the wamid.* value). Useful for cross-referencing WhatsApp’s own logs.

Error response

On failure the API returns HTTP 400 Bad Request with a JSON body that includes the error code and a human-readable message:

{
  "request_id": "e23080fd-8b63-460e-83bd-cf5d2c1497b6",
  "error_code": 3,
  "error": "Message Template does not exist."
}

Error codes

Code

Name

When it happens

1

ARGUMENT_MISSING

A required parameter (destination_phone, or header_attachment_url for media headers) was omitted.

2

TYPE_MISMATCH

message_variables was neither an object nor an array.

3

TEMPLATE_NOT_EXIST

No accepted template exists at :template_id for this WABA.

4

VARIABLES_SIZE

The count of supplied variables does not match the template’s placeholders.

5

PHONE_INVALID

destination_phone failed E.164 validation.

6

DEPRECATED_API_KEY

The API key has been rotated or revoked. Fetch the current key from Octopods.

7

WHATSAPP_ERROR

WhatsApp rejected the send. The error field carries WhatsApp’s reason.

8

INVALID_HEADER

header_attachment_url could not be fetched, was the wrong media type, or was blocked.

9

LEGACY_VARIABLES_TYPE

An array was passed for a template whose variables are not body-only. Use the object shape.

A full catalog of error codes across all endpoints is in the API Error Reference.

Rate limits

The WhatsApp API is rate-limited per WhatsApp Business API Key. Exceeding the limit returns HTTP 429 with a retry timestamp; pause sends until the timestamp passes before retrying.

Tip: batch sends at a steady pace rather than bursting — the limiter tolerates short surges but blocks sustained bursts.


What’s next

Did this answer your question?