Messages

/v1/messages

Use the messages node to send text messages, media/documents, and message templates to your customers.

See the following guides for information regarding the specific types of messages you can send: Text Messages, Media Messages, Message Templates, and Other Message Types.

Before You Start

You need:

  • Authenticate yourself and receive an authentication token that enables you to access the service. See the Login and Authentication documentation for more information on how to do this.
  • To verify the WhatApp account you wish to message and get its WhatsApp user ID.
    See the Contacts documentation for more information on how to do this.
  • Meet the cut-off control service requirements for messages.

Before sending a message, you should also send an API call to the contacts node. The information from checking contacts is cached in the container and not doing this might result in an Unknown Contact error.

Constraints

  • The following types of message are supported: text, message templates, images, documents and audio.
  • A text message can be a max of 4096 characters long.

Creating

You send messages by making a POST call to the /messages node regardless of message type. The content of the JSON message body differs for each type of message (text, image, etc.).

Parameters

These are the main parameters used in /messages POST API requests:

NameDescription

recipient_type

Optional.

The type of recipient the message is being sent to.

Supported value: individual

to

Required.

The WhatsApp ID for the recipient of your message. Use the ID returned from the contacts endpoint.

type

Optional for text messages. Required for all other message types.

The type of message you would like to send.


Supported values:

preview_url

Only used with messages of text type.

Allows for URL previews in text messages. For more information, see the Sending URLs in Text Messages. This field is optional if not including a URL in your message.


Values: false (default), true

text

Required for messages of text type.

Contains a text object.

audio

Required when type is set to audio.

The media object containing audio.

document

Required when type is set to document.

The media object containing a document.

image

Required when type is set to image.

The media object containing an image.

sticker

Required when type is set to sticker.

The media object containing a sticker.

video

Required when type is set to video.

The media object containing a video.

contacts

Required when type is set to contacts.

Contains a contacts object.

location

Required when type is set to location.

Contains a location object.

template

Only used with message templates.

Contains a template object.

hsm

Only used with message templates.

Contains an hsm object. Deprecation of the hsm object is planned for a future version.

interactive

Required for interactive messages.

This object contains information about the message you would like to send. The components of each interactive object generally follow a consistent pattern: header, body, footer, and action. See the interactive object below for more information.

The text Object

NameDescription

body

Required.

Contains the text of the message, which can contain URLs and formatting.

The media Object

NameDescription

id

Required when type is audio, document, image, sticker, or video and you are not using a link.

The media object ID. This is returned when the media is successfully uploaded to the WhatsApp Business API client via the media endpoint.


Do not use this field when message type is set to text.

link

Required when type is audio, document, image, sticker, or video and you are not using an uploaded media ID.

The protocol and URL of the media to be sent. Use only with HTTP/HTTPS URLs.


Do not use this field when message type is set to text.

caption

Optional.

Describes the specified document, image, or video media.


Do not use with audio or sticker media.

filename

Optional.

Describes the filename for the specific document. Use only with document media.

provider

Optional.

This path is optionally used with a link when the HTTP/HTTPS link is not directly accessible and requires additional configurations like a bearer token. For information on configuring providers, see the Media Providers documentation.

The contacts Object

Inside contacts, you can nest the following objects: addresses, emails, name, org, phone, and urls.

NameDescription

addresses

Optional.

Full contact address(es) —see addresses object.

birthday

Optional.

YYYY-MM-DD formatted string.

emails

Optional.

Contact email address(es) —see emails object.

name

Required.

Full contact name —see name object.

org

Optional.

Contact organization information —see org object.

phones

Optional.

Contact phone number(s) —see phone object.

urls

Optional.

Contact URL(s) —see urls object.

The addresses Object

NameDescription

street

Optional.

Street number and name

city

Optional.

City name.

state

Optional.

State abbreviation.

zip

Optional.

ZIP code.

country

Optional.

Full country name.

country_code

Optional.

Two-letter country abbreviation.

type

Optional.

Standard Values: HOME, WORK

The emails Object

NameDescription

email

Optional.

Email address

type

Optional.

Standard Values: HOME, WORK

The name Object

NameDescription

formatted_name

Required.

Full name, as it normally appears.

first_name

Optional*.

First name.

last_name

Optional*.

Last name.

middle_name

Optional*.

Middle name.

suffix

Optional*.

Name suffix.

prefix

Optional*.

Name prefix.

*At least one of the optional parameters needs to be included along with the formatted_name parameter.

The org Object

NameDescription

company

Optional.

Name of the contact's company.

department

Optional.

Name of the contact's department.

title

Optional.

Contact's business title.

The phone Object

NameDescription

phone

Optional.

Automatically populated with the wa_id value as a formatted phone number.

type

Optional.

Standard Values: CELL, MAIN, IPHONE, HOME, WORK

wa_id

Optional.

WhatsApp ID.

The urls object

NameDescription

url

Optional.

URL.

type

Optional.

Standard Values: HOME, WORK

The location Object

NameDescription

longitude

Required.

Longitude of the location.

latitude

Required.

Latitude of the location.

name

Optional.

Name of the location.

address

Optional.

Address of the location. Only displayed if name is present.

The template object

Inside template, you can nest the components and the language objects.

NameDescription

namespace

Required.

Namespace of the template.


Beginning with v2.27.8, this must be the namespace associated with the WhatsApp business account that owns the phone number associated with the current WhatsApp Business API client or the message fails to send.

name

Required.

Name of the template.

language

Required.

Specifies the language the template may be rendered in. Only the deterministic language policy works with media template messages. See the Language section for more information.

components

Optional.

Array containing the parameters of the message.

The components object

Inside components, you can nest the parameters object. Additionally, you can set type to button.

NameDescription

type

Required.

Describes the component type.
Values: header, body, footer, or button

subtype

Optional. Used when type is set to button.

Supported values are:

  • quick_reply: Refers to a previously created quick reply button that allows for the customer to return a predefined message. See Callback from a Quick Reply Button Click for an example of a response from a quick reply button.
  • url: Refers to a previously created button that allows the customer to visit the URL generated by appending the text parameter to the predefined prefix URL in the template.

parameters

Optional.

Array containing the content of the message.

The parameters object

NameDescription

type

Required.

Describes the parameter type.
Values: text, currency, date_time, image, document, video


The media types (image, document and video) follow the same format as those used in standard media messages, see the Media documentation for more information. Only PDF documents are currently supported for media message templates.


For more information about currency and date_time, see the Localizable Parameters section. The currency and date_time parameters for template messages uses fallback_value in place of default. See the Request sample above for an example.

The button type

Inside the components object, you can set type to button. These are the button parameters:

NameDescription

sub_type

Required.

Type of button being created.
Values: quick_reply, url

index

Required.

Position index of the button. You can have up to 3 buttons using index values of 0-2.

parameters

Required.

The parameters for the button, which are set at creation time in your Business Manager. Include the following parameters:

  • type (Required): Indicates the type of parameter for the button. Supported values are payload and text.
  • payload (Required for quick_reply buttons): Developer-defined payload that will be returned when the button is clicked in addition to the display text on the button.
  • text (Required for url buttons): Developer provided suffix that will be appended to a previously created dynamic URL button.

The language object

The language parameter sets the language policy for a message template. This field can be nested inside the hsm and template objects.

Name Description

policy

Required.

Default: deterministic
The language policy the message should follow. The fallback option was deprecated with v2.27.8. Learn more about language policy options.

code

Required.

The code of the language or locale to use. Accepts both language and language_locale formats (e.g., en and en_US).

The hsm Object

Deprecation of the hsm object is planned for a future version.

Name Description

namespace

Required.

The namespace to be used. Beginning with v2.2.7, if the namespace does not match up to the element_name, the message fails to send.

element_name

Required.

The element name that indicates which template to use within the namespace. Beginning with v2.2.7, if the element_name does not match up to the namespace, the message fails to send.

language

Required.

Allows for the specification of a deterministic language. See the Language section for more information.


This field used to allow for a fallback option, but this has been deprecated with v2.27.8.

localizable_params

Required.

This field is an array of values to apply to variables in the template. See the Localizable Parameters section for more information.

The interactive Object

The interactive object generally contains 4 main components: header, body, footer, and action. Additionally, some of those components can contain one or more different objects:

  • Inside header, you can nest media objects.
  • Inside action, you can nest section and button objects.
NameDescription

type

Required.

Supported values:

  • list: Use it for List Messages.
  • button: Use it for Reply Buttons.

header

Optional.

Header content displayed on top of a message. See header object for more information.

body

Required.

The body of the message. There’s a maximum of 1024 characters. Emojis and markdown are supported.

footer

Optional.

The footer of the message. There’s a maximum of 60 characters. Emojis and markdown are supported.

action

Required.

Action you want the user to perform after reading the message.

The header Object

NameDescription

type

Required.

The header type you would like to use. Supported values are:

  • text: Used for List Messages and Reply Buttons.
  • video: Used for Reply Buttons.
  • image: Used for Reply Buttons.
  • document: Used for Reply Buttons.

text

Required if type is set to text.

Text for the header. Maximum of 60 characters. Formatting allows emojis, but not markdown.

video

Required if type is set to video.

Contains the media object for this video.

image

Required if type is set to image.

Contains the media object for this image.

document

Required if type is set to document.

Contains the media object for this document.

The body Object

NameDescription

text

Required.

The body content of the message. Maximum of 1024 characters. Emojis and markdown are supported. Links are supported.

NameDescription

text

Required if the footer object is present.

The footer content. Maximum of 60 characters. Emojis and markdown are supported. Links are supported.

The action Object

NameDescription

button

Required for List Messages.

Button content. It cannot be an empty string and must be unique within the message. Maximum of 20 characters. Does not allow emojis or markdown.

buttons

Required for Reply Button Messages.

A button can contain the following parameters:

  • type: only supported type is reply (for Reply Button Messages)
  • title: Button title. It cannot be an empty string and must be unique within the message. Maximum of 20 characters. Does not allow emojis or markdown.
  • id: Unique identifier for your button. Maximum of 256 characters. This ID is returned in the webhook when the button is clicked by the user.

sections

Required for List Messages.

Array of section objects. There is a minimum of 1 and maximum of 10. See section object.

The section Object

NameDescription

title

Required if the message has more than one section.

Title of the section.

rows

Required for List Messages.

Contains a list of rows.

Each row must have a title and an ID. You can add a description, but it is optional.


Example:

"rows": [
  {
   "id":"unique-row-identifier-here",
   "title": "row-title-content-here",
   "description": "row-description-content-here",           
   }
]

Examples

Audio messages:

POST /v1/messages
{
  "recipient_type": "individual",
  "to": "whatsapp-id",
  "type": "audio",
  "audio": {
      "id": "your-media-id",
  }
}

Document messages, using filename:

POST /v1/messages
{
  "recipient_type": "individual",
  "to": "whatsapp-id",
  "type": "document",
  "document": {
      "id": "your-media-id",
      "caption": "your-document-caption-to-be-sent",
      "filename": "your-document-filename"
  }
}

Document messages, using link:

POST /v1/messages
{
  "recipient_type": "individual",
  "to": "whatsapp-id",
  "type": "document",
  "document": {
      "link": "http(s)://the-url"
      "provider": {
          "name" : "provider-name"
      }
      "caption": "your-document-caption"
    }
}

Video messages, using link:

POST /v1/messages
{
  "recipient_type": "individual",
  "to": "whatsapp-id",
  "type": "video",
  
  "video": {
      "link": "http(s)://the-url"
      "provider": {
          "name" : "provider-name"
      }
      "caption": "your-video-caption"
    }
  }
}

Text messages:

POST /v1/messages
{
  "recipient_type": "individual",
  "to": "whatsapp-id",
  "type": "text",
  "text": {
      "body": "your-message-content"
  }
}

Interactive messages (lists):

POST /v1/messages
{
  "recipient_type": "individual",
  "to": "whatsapp-id",
  "type": "text",
  "interactive":{
    "type": "list",
    "header": {
      "type": "text",
      "text": "your-header-content-here"
    },
    "body": {
      "text": "your-text-message-content-here"
    },
    "footer": {
      "text": "your-footer-content-here"
    },
    "action": {
      "button": "cta-button-content-here",
      "sections":[
        {
          "title":"your-section-title-content-here",
          "rows": [
            {
              "id":"unique-row-identifier-here",
              "title": "row-title-content-here",
              "description": "row-description-content-here",           
            }
          ]
        },
        {
          "title":"your-section-title-content-here",
          "rows": [
            {
              "id":"unique-row-identifier-here",
              "title": "row-title-content-here",
              "description": "row-description-content-here",           
            }
          ]
        },
        ...
      ]
    }
  }

}

Interactive messages (reply buttons):

POST /v1/messages
{
  "recipient_type": "individual",
  "to": "whatsapp-id",
  "type": "text",
  "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" 
          }
        }
      ] 
    } # end action   
  } # end interactive

}

The response to your call includes a combination of following components: meta, messages (payload), and errors. See WhatsApp Business API Responses for more information.

The following shows an example of payload in a response; the meta and error objects are omitted for brevity.

{
  "messages": [{ 
    "id": "message-id" 
  }]    
}

If the request is successful, you receive a response with a message ID. If the request returns an errors section, check the originating message and correct the errors before resending the request. For more information about errors, see WhatsApp Business API Client Error Codes and HTTP Status Codes.

Formatting in Text Messages

WhatsApp allows some formatting in messages. To format all or part of a message, use these formatting symbols:

FormattingSymbolExample

Bold

Asterisk (*)

Your total is *$10.50*.

Italics

Underscore (_)

Welcome to _WhatsApp_!

Strike-through

Tilde (~)

This is ~better~ best!

Code

Three backticks (```)

```print 'Hello World';```

Performance

In this context, performance represents the number of messages that can be sent in any given second using the WhatsApp Business API client. The maximum achievable performance depends on a variety of factors, the most important factor being your client setup choice and whether a message is being sent to a new user or an existing user —encryption sessions setup take a little longer when messaging a new user.

Client setupSupported messages per second

Single Shard

70

Multi Shard (32 shards)

250

FAQ

No.

If a user contacts an enterprise, the enterprise can respond with any type of message in the next 24 hours. This type of message is free.

But if the enterprise is contacting a user before the user sends a message or after more than 24 hours have passed, the enterprise can only send a message template. This is a paid notification.

Free-form text messages and media messages will not work outside this 24 hour window. They will result in a failure callback with error 470.

Note: Please do not send the same message repeatedly to the same recipient using the WhatsApp Business API.

There can be multiple reasons why delivery rates are not 100%. Some common cases include users having sporadic access to network or being inactive for a period of time.

Messages that can be delivered with WhatsApp will have a very high delivery rate. However there are many reasons why a message may not be delivered. You will have access to the exact status of a message by monitoring your callbacks. This is different from sending messages with SMS, for example, where you do not have access to final delivered status and resending the message may indeed produce a different outcome.

Messages may remain undelivered because a user's phone is out of service, or battery, or they have lost it and are getting a new one and have disabled their SIM. It is possible there are errors in the business client's ability to connect to the network. It is also possible callbacks (Webhooks) are not being delivered. You can monitor these situations by using the health node. You can turn on server receipt callbacks to know that the message made it into the WhatsApp server cloud.

If and when a user does reconnect to the network all the messages you sent will be delivered to them. Receiving more than one message with the same content will be a bad experience for them. They will be more likely to block you or complain. You will be more likely to be banned.

If you send a message and receive a message ID from the API, you have done what you can to send this message. Do not resend the same content to the same recipient.

If you are seeing low delivery rates over a prolonged period of time, please file a support ticket with Direct Support.

When you send a message, as soon as you get back a message ID, that means the message request has been stored on the database. The WhatsApp Business API Client will keep attempting to send that message until acknowledged by the WhatsApp server. This process has no end timeline. The WhatsApp server will then try to deliver that message to the user's phone. If the user's phone is not online, the message will be stored for 30 days before being discarded by the WhatsApp server.

Yes! WhatsApp allows you to format selected text inside your messages with Bold, Italics, Strikethrough or Monospace.

Currently, there is no way to see how many or which users have blocked your business. The best indicator would be to listen for status callbacks and if you do not receive the delivered status, then either the user has blocked your business or they do not have a network connection. See the Webhook documentation for more details.

If a user has blocked your business, the Contacts API will continue to return that phone number as a valid WhatsApp user. However, when you send the message, it will never get delivered. If it is a paid message, you will not be charged.

No, the order in which the messages arrive is not guaranteed to be the same order as what was sent. If ordering is critical to your use case, the suggested approach is to listen for the delivered callback of the first message before firing the second message.

When using the messages node, you need to set the Content-Type header to application/json for the WhatsApp Business API Client to properly parse the message body. There is also an Authorization header that needs to be set and must contain an unexpired access token. See the Login and Authentication documentation for information on how to get your token and when it expires.

There may be cases where you need more time to handle a customer query and may only be able to provide a response after 24 hours. We recommend creating message templates to either:

  • deliver the result to the user, or
  • prompt the user to reply in order to activate the customer service window.

In both cases, please ensure you provide as much context to the message template as possible. For example:

  • "Hello {{1}}, regarding the issue you reported earlier, we regret to inform you that {{2}}. Apologies for any inconvenience caused."
  • We have updates regarding your ticket. Please respond back if you'd like to continue support."