Messages
https://whatsapp.turn.io/v1/messages
This endpoint responsible for sending messages via WhatsApp. Messages for WhatsApp are classified as:
Turn.io's outbound messaging API is synchronous to the upstream gateways. If Turn.io returns with a success response, the upstream gateway has accepted the message for delivery. Turn.io does not queue outbound messaging.
This endpoint is rate limited on a per number basis. See rate limiting for more information.
Text Messagesβ
$ curl -X POST "https://whatsapp.turn.io/v1/messages" \
-H "Authorization: Bearer token" \
-H "Content-Type: application/json" \
-d '
{
"preview_url": false | true,
"recipient_type": "individual",
"to": "whatsapp-id",
"type": "text",
"text": {
"body": "your-text-message-content"
}
}'
> {
"messages": [{
"id": "gBEGkYiEB1VXAglK1ZEqA1YKPrU"
}]
}
Make sure to replace
tokenwith your access token.
A successful response includes a messages object with an identifier for the newly created message.
An unsuccessful response will contain an error message. See Error and Status Codes for more information.
Parametersβ
| Parameter | Required | Default | Description |
|---|---|---|---|
| preview_url | no | false | Specifying preview_url in the request is optional when including a URL in your message. To include a URL preview, set preview_url to true in the message body and make sure the URL begins with http:// or https://. |
| to | conditional | The WhatsApp ID (phone number) of the recipient. Required if recipient is not provided. | |
| recipient | conditional | The BSUID of the recipient (e.g. US.13491208655302741918). Required if to is not provided. | |
| type | no | text | Specifying type in the request is optional when you are sending a text message. |
| text.body | yes | The text to send |
Reaction Messagesβ
Use the messages endpoint to react to a message a customer has sent you with an emoji. Provide the message_id of the message you are reacting to and the emoji to apply. This uses the same format as the WhatsApp Cloud API reaction message.
$ curl -X POST "https://whatsapp.turn.io/v1/messages" \
-H "Authorization: Bearer token" \
-H "Content-Type: application/json" \
-d '
{
"to": "whatsapp-id",
"type": "reaction",
"reaction": {
"message_id": "the-message-id-you-are-reacting-to",
"emoji": "π"
}
}'
> {
"messages": [{
"id": "gBEGkYiEB1VXAglK1ZEqA1YKPrU"
}]
}
Make sure to replace
tokenwith your access token.
To remove a reaction you previously sent, send the same request with emoji set to an empty string ("").
Parametersβ
| Parameter | Required | Default | Description |
|---|---|---|---|
| to | conditional | The WhatsApp ID (phone number) of the recipient. Required if recipient is not provided. | |
| recipient | conditional | The BSUID of the recipient. Required if to is not provided. | |
| type | yes | Must be reaction. | |
| reaction.message_id | yes | The ID of the message you are reacting to. | |
| reaction.emoji | yes | The emoji to apply. Use an empty string ("") to remove an existing reaction. |
Media Messagesβ
Use the messages endpoint to send messages containing audio, images, documents, or stickers to your customers.
When you send a message that includes media, you must provide the ID of the uploaded media in the request body. You must also specify the type of media that you are sending: audio, image, video, document, or sticker. When the request is received, the media is uploaded to the WhatsApp server and sent to the user indicated in the to field.
$ curl -X POST https://whatsapp.turn.io/v1/messages \
-H 'Authorization: Bearer token' \
-H 'Content-Type: application/json' \
-d '
{
"recipient_type": "individual",
"to": "whatsapp-id",
"type": "audio" | "document" | "image" | "sticker" | "video",
"audio": {
"id": "your-media-id",
}
"document": {
"id": "your-media-id",
"caption": "your-document-caption"
}
"image": {
"id": "your-media-id",
"caption": "your-image-caption"
}
"sticker": {
"id": "your-media-id"
}
"video": {
"id": "your-media-id",
"caption": "your-video-caption"
}
}
'
> {
"messages": [{
"id": "gBEGkYiEB1VXAglK1ZEqA1YKPrU"
}]
}
The successful response includes a messages object with a message ID. An unsuccessful response will contain an error message. See Error and Status Codes for more information on errors.
Parametersβ
| Name | Required | Default | Description | Options |
|---|---|---|---|---|
| to | conditional | The WhatsApp ID (phone number) of the recipient. Required if recipient is not provided. | ||
| recipient | conditional | The BSUID of the recipient. Required if to is not provided. | ||
| type | yes | no | text | Options: text, image, audio, document, sticker |
| <media-type>.id | The media object ID, which is returned when the media is successfully uploaded to the WhatsApp Business API Client with the media endpoint. | |||
| <media-type>.caption | Describes the specified image or document media. Do not use with audio or sticker media. |
Additional documentation:
Templated Messagesβ
$ curl -X POST https://whatsapp.turn.io/v1/messages \
-H 'Authorization: Bearer token' \
-H 'Content-Type: application/json' \
-d '
{
"to": "whatsapp_id",
"type": "template",
"template": {
"namespace": "template-namespace",
"name": "template-name",
"language": {
"code": "en",
"policy": "deterministic"
},
"components": [
{
"type" : "header",
"parameters": [
{
"type": "text",
"text": "header placeholder value"
}
]
},
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "body placeholder 1 value"
},
{
"type": "text",
"text": "body placeholder 2 value"
}
]
}
]
}
}'
> {
"messages": [{
"id": "gBEGkYiEB1VXAglK1ZEqA1YKPrU"
}]
}
As with normal messages, the message is sent to the /v1/messages endpoint. What's different about sending templated messages is that the message type is set to template and a template object is provided with information such as which message template to use.
The template property indicates the namespace and the name of the message template that should be sent. It also includes a list of components that will be used to build the template header, footer, body and buttons.
The namespace can be determined using the Turn.io web application as follows:
- Navigate to Settings > API & Webhooks.
- Click the Generate Credentials button.
- View your Message Template API details including namespace and access token.
Please refer to the official WhatsApp documentation for more details.
Please note that every new number is limited to sending message templates to a maximum of 1000 users a day. As a numbers' total audience grows WhatsApp will extend the per day limit as per the tiers outlined in the Quality Rating and Messaging Limits documentation. WhatsApp will not start a number on a higher tier and Turn.io is not able to manually change or request a tier change for a number. Tiers are determined by WhatsApp based on a numbers' organic growth and overall quality rating.
Interactive Messagesβ
Sending quick reply messagesβ
$ curl -X POST https://whatsapp.turn.io/v1/messages \
-H 'Authorization: Bearer token' \
-H 'Content-Type: application/json' \
-d '
{
"to": "whatsapp_id",
"type": "interactive",
"interactive": {
"type": "button",
"header": { # optional
"type": "text" | "image" | "video" | "document",
"text": "your text"
# OR
"document": {
"id": "your-media-id",
"filename": "some-file-name"
}
# OR
"document": {
"link": "the-provider-name/protocol://the-url",
"provider": {
"name": "provider-name",
},
"filename": "some-file-name"
},
# OR
"video": {
"id": "your-media-id"
}
# OR
"video": {
"link": "the-provider-name/protocol://the-url",
"provider": {
"name": "provider-name"
}
}
# OR
"image": {
"id": "your-media-id"
}
# OR
"image": {
"link": "http(s)://the-url",
"provider": {
"name": "provider-name"
}
}
}, # end header
"body": {
"text": "your-text-body-content"
},
"footer": { # optional
"text": "your-text-footer-content"
},
"action": {
"buttons": [
{
"type": "reply",
"reply": {
"id": "unique-postback-id",
"title": "First Buttonβs Title"
}
},
{
"type": "reply",
"reply": {
"id": "unique-postback-id",
"title": "Second Buttonβs Title"
}
}
]
}
}
}'
> {
"messages": [{
"id": "gBEGkYiEB1VXAglK1ZEqA1YKPrU"
}]
}
Start a Turn.io journey when an interactive reply button is clickedβ
This API is still in alpha and subject to change. Features, endpoints, and data structures may be modified or removed in future releases.
Similar to template quick reply buttons, you can start a journey when a contact clicks an interactive reply button. Set the button's id to turn-start-journey:JOURNEY-ID-HERE.
For example, to send two reply buttons that each start a different journey:
$ curl -X POST https://whatsapp.turn.io/v1/messages \
-H 'Authorization: Bearer token' \
-H 'Content-Type: application/json' \
-d '
{
"to": "whatsapp_id",
"type": "interactive",
"interactive": {
"type": "button",
"body": {
"text": "How can we help?"
},
"action": {
"buttons": [
{
"type": "reply",
"reply": {
"id": "turn-start-journey:018f2df5-3dad-7eb2-b706-8930546a94c6",
"title": "Sales"
}
},
{
"type": "reply",
"reply": {
"id": "turn-start-journey:018f2df6-20e0-7354-9f4c-6a3a43daf896",
"title": "Support"
}
}
]
}
}
}'
Sending list messagesβ
$ curl -X POST https://whatsapp.turn.io/v1/messages \
-H 'Authorization: Bearer token' \
-H 'Content-Type: application/json' \
-d '
{
"to": "whatsapp_id",
"type": "interactive",
"interactive": {
"type": "list",
"header": {
"type": "text",
"text": "your-header-content"
},
"body": {
"text": "your-text-message-content"
},
"footer": {
"text": "your-footer-content"
},
"action": {
"button": "cta-button-content",
"sections": [
{
"title":"your-section-title-content",
"rows": [
{
"id":"unique-row-identifier",
"title": "row-title-content",
"description": "row-description-content",
}
]
},
{
"title":"your-section-title-content",
"rows": [
{
"id":"unique-row-identifier",
"title": "row-title-content",
"description": "row-description-content",
}
]
}
]
}
}
}'
> {
"messages": [{
"id": "gBEGkYiEB1VXAglK1ZEqA1YKPrU"
}]
}
Sending location request messagesβ
$ curl -X POST https://whatsapp.turn.io/v1/messages \
-H 'Authorization: Bearer token' \
-H 'Content-Type: application/json' \
-d '
{
"to": "whatsapp_id",
"type": "interactive",
"interactive": {
"type": "location_request_message",
"body": {
"text": "Please let us know where you are?"
},
"action": {
"name": "send_location"
}
}
}'
> {
"messages": [{
"id": "gBEGkYiEB1VXAglK1ZEqA1YKPrX"
}]
}
As with normal messages, the message is sent to the /v1/messages endpoint. What's different about sending interactive messages is that the message type is set to interactive and an interactive object is provided with information, such as which type of interactive message one wants to use along with its payload. Currently, button and list types are supported.
The interactive property is different depending on the type of interactive message that should be sent (buttons or list message). It includes an action property that will be used to build the set of options for the message.
Please refer to the official WhatsApp documentation for more details.
Interactive Templated Messagesβ
Sending an interactive message simply boils down to sending a templated message using a template that contains buttons.
Please refer to the official WhatsApp documentation for more details.
$ curl -X POST https://whatsapp.turn.io/v1/messages \
-H 'Authorization: Bearer token' \
-H 'Content-Type: application/json' \
-d '
{
"to": "whatsapp_id",
"type": "template",
"template": {
"namespace": "template-namespace",
"name": "template-name",
"language": {
"code": "en",
"policy": "deterministic"
},
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "body placeholder 1 value"
}
]
},
{
"type": "button",
"sub_type" : "quick_reply",
"index": "0",
"parameters": [
{
"type": "payload",
"payload": "button-0-payload"
}
]
},
{
"type": "button",
"sub_type" : "quick_reply",
"index": "1",
"parameters": [
{
"type": "payload",
"payload": "button-1-payload"
}
]
}
]
}
}'
> {
"messages": [{
"id": "gBEGkYiEB1VXAglK1ZEqA1YKPrU"
}]
}
For quick reply buttons, it is possible to provide a custom payload for each button. The payload will be part of the incoming message notification that will be sent by WhatsApp whenever the button is clicked.
Start a Turn.io journey when a template quick reply button is clickedβ
If you supply a button payload of the form turn-start-journey:JOURNEY-ID-HERE (for example turn-start-journey:8515561e-2e82-431d-b8f3-e4bac8189183), Turn.io will start the desired Journey when the user clicks on the template quick reply button.
Here is an example that sends a template with quick reply buttons that will start different journeys when clicked:
$ curl -X POST https://whatsapp.turn.io/v1/messages \
-H 'Authorization: Bearer token' \
-H 'Content-Type: application/json' \
-d '
{
"to": "whatsapp_id",
"type": "template",
"template": {
"namespace": "template-namespace",
"name": "template-name",
"language": {
"code": "en",
"policy": "deterministic"
},
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "body placeholder 1 value"
}
]
},
{
"type": "button",
"sub_type" : "quick_reply",
"index": "0",
"parameters": [
{
"type": "payload",
"payload": "turn-start-journey:018f2df5-3dad-7eb2-b706-8930546a94c6"
}
]
},
{
"type": "button",
"sub_type" : "quick_reply",
"index": "1",
"parameters": [
{
"type": "payload",
"payload": "turn-start-journey:018f2df6-20e0-7354-9f4c-6a3a43daf896"
}
]
}
]
}
}'
> {
"messages": [{
"id": "gBEGkYiEB1VXAglK1ZEqA1YKPrU"
}]
}
Media Templated Messagesβ
$ curl -X POST https://whatsapp.turn.io/v1/messages \
-H 'Authorization: Bearer token' \
-H 'Content-Type: application/json' \
-d '
{
"to": "whatsapp_id",
"type": "template",
"template": {
"namespace": "template-namespace",
"name": "template-name",
"language": {
"code": "en",
"policy": "deterministic"
},
"components": [
{
"type": "header",
"parameters": [
{
"type": "video",
"video": {
"link": "https://url.com/video-file.mp4"
}
}
]
}
]
}
}'
> {
"messages": [{
"id": "gBEGkYiEB1VXAglK1ZEqA1YKPrU"
}]
}
Sending a media templated message simply means sending a templated message using a template that that has a media header. When sending the templated message, the components array of the request object should provide the URL of the media file you intend to send inside its parameters object.
Please refer to the official WhatsApp documentation for more details.
Authentication Templated Messagesβ
Authentication templates are used to send one-time passwords (OTP) or verification codes.
The example below sends a template named verification_code whose body contains *{{1}}* is your verification code... and has a single URL-type "Copy code" button with {{1}} in the URL. See Listing Message Templates for the full template definition.
$ curl -X POST \
https://whatsapp.turn.io/v1/messages \
-H 'Authorization: Bearer token' \
-H 'Content-Type: application/json' \
-d '
{
"to": "whatsapp_id",
"type": "template",
"template": {
"namespace": "template-namespace",
"name": "verification_code",
"language": {
"code": "en",
"policy": "deterministic"
},
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "123456"
}
]
},
{
"type": "button",
"sub_type": "url",
"index": "0",
"parameters": [
{
"type": "text",
"text": "123456"
}
]
}
]
}
}'
> {
"messages": [{
"id": "wamid.HBgNNTUyMTk5NjE2NTQxORUCABEYEjU0MUVERTBENDNCMzZCQjZDQwA="
}]
}
The components array:
| Component | Description |
|---|---|
body | A text parameter with the OTP code, replacing the {{1}} placeholder in the template body. |
button | A text parameter with the OTP code. The sub_type must be "url" and index must be "0", matching the button defined in the template. The code replaces the {{1}} placeholder in the button URL. |
If you get an error like OAuthException: Invalid parameter when sending an authentication template, it usually means:
- The
sub_typedoesn't match the button type in the template (e.g. using"quick_reply"instead of"url") - The button
parametersare missing or malformed - The
indexdoesn't match the button position
Use the Listing Message Templates endpoint to verify your template's button types before building the send request.
Please refer to the official WhatsApp documentation for more details.
Formatting in Text Messagesβ
WhatsApp allows some formatting in messages. To format all or part of a message, use these formatting symbols:
| Formatting | Symbol | Example |
|---|---|---|
| bold | Asterisk(*) | Your total is *$10.50*. |
| italics | Underscore(_) | Welcome to WhatsApp! |
| Tilde(~) | This is | |
code | Three backticks (```) | ```print 'Hello World';``` |
HSM (Removed)β
The legacy HSM message format was deprecated and removed by WhatsApp, and support
for it has been removed from this API. Requests with "type": "hsm" are rejected.
Use the template message format instead.