Messages

/v1/messages

Use the messages node to send text, media, contacts, locations, and interactive messages, as well as message templates to your customers.

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

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 WhatsApp 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.

Starting in v2.39 and above, you do not have to call the contacts node before sending a message.

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 requests:

NameDescription (Click the arrow in the left column for supported options.)

audio

object

Required when type=audio.

A media object containing audio.

contacts

object

Required when type=contacts.

A contacts object.

document

object

Required when type=document.

A media object containing a document.

hsm

object
Only used for On-Premises API.

Contains an hsm object. This option was deprecated with v2.39 of the WhatsApp Business On-Premises API. Use the template object instead.


Cloud API users should not use this field.

image

object

Required when type=image.

A media object containing an image.

interactive

object

Required when type=interactive.

An interactive object. The components of each interactive object generally follow a consistent pattern: header, body, footer, and action.

location

object

Required when type=location.

A location object.

messaging_product

string
Required. Only used for Cloud API.

Messaging service used for the request. Use "whatsapp".


On-Premises API users should not use this field.

preview_url

boolean
Required if type=text. Only used for On-Premises API.

Allows for URL previews in text messages — See the Sending URLs in Text Messages. This field is optional if not including a URL in your message. Values: false (default), true.


Cloud API users can use the same functionality with the preview_url field inside the text object.

recipient_type

string

Optional.

Currently, you can only send messages to individuals. Set this as individual.


Default: individual

status

string

A message's status. You can use this field to mark a message as read. See the following guides for information:

sticker

object

Required when type=sticker.

A media object containing a sticker.


For Cloud API users, we support static third-party outbound stickers and all types of inbound stickers. The sticker needs to be 512x512 pixels and the file’s size needs to be less than 100 KB.

template

object

Required when type=template.

A template object.

text

object

Required for text messages.

A text object.

to

string

Required.

WhatsApp ID or phone number for the person you want to send a message to. See Phone Numbers, Formatting for more information.


If needed, On-Premises API users can get this number by calling the contacts endpoint.

type

string

Optional.

The type of message you want to send.


Default: text

Supported Options

  • audio: for audio messages.
  • contacts: for contact messages.
  • document: for document messages.
  • image: for image messages.
  • interactive: for list and reply button messages.
  • location: for location messages.
  • sticker: for sticker messages.
  • template: for template messages. Text and media (images and documents) message templates are supported.
  • text: for text messages.

Text Object

NameDescription

body

Required.

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

Media Object

For the On-Premises API, the media object id is returned when the media is successfully uploaded to the WhatsApp Business on-premises/reference client via the media endpoint.

NameDescription

id

string

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

The media object ID. Do not use this field when message type is set to text.

link

string

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

string

Starting in v2.41.2, it is limited to 1024 characters.

Optional.

Describes the specified document, image, or video media.


Do not use with audio or sticker media.

filename

string

Optional.

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

provider

string

Optional. Only used for On-Premises API.

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.

Contacts Object

Inside contacts, you can nest the following objects: addresses, emails, name, org, phone, and urls. Pluralized objects are to be wrapped in an array as shown in the example below.

NameDescription

addresses

object

Optional.

Full contact address(es) formatted as an addresses object. The object can contain the following fields:

streetstringOptional. Street number and name.

citystringOptional. City name.

statestringOptional. State abbreviation.

zipstringOptional. ZIP code.

countrystringOptional. Full country name.

country_codestringOptional. Two-letter country abbreviation.

typestringOptional. Standard values are HOME and WORK.

birthday

Optional.

YYYY-MM-DD formatted string.

emails

object

Optional.

Contact email address(es) formatted as an emails object. The object can contain the following fields:

emailstringOptional. Email address.

typestringOptional. Standard values are HOME and WORK.

name

object

Required.

Full contact name formatted as a name object. The object can contain the following fields:

formatted_namestringRequired. Full name, as it normally appears.

first_namestringOptional*. First name.

last_namestringOptional*. Last name.

middle_namestringOptional*. Middle name.

suffixstringOptional*. Name suffix.

prefixstringOptional*. Name prefix.


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

org

object

Optional.

Contact organization information formatted as an org object. The object can contain the following fields:

companystringOptional. Name of the contact's company.

departmentstringOptional. Name of the contact's department.

titlestringOptional. Contact's business title.

phones

object

Optional.

Contact phone number(s) formatted as a phone object. The object can contain the following fields:

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

typestringOptional. Standard Values are CELL, MAIN, IPHONE, HOME, and WORK.

wa_idstringOptional. WhatsApp ID.

urls

object

Optional.

Contact URL(s) formatted as a urls object. The object can contain the following fields:

urlstringOptional. URL.

typestringOptional. Standard values are HOME and WORK.

Example of a contacts object with pluralized objects nested inside:

"contacts": [
    {
        "addresses": [
            {
                "city": "city name",
                "country": "country name",
                "country_code": "code",
                "state": "Contact's State",
                "street": "Contact's Street",
                "type": "Contact's Address Type",
                "zip": "Contact's Zip Code"
            }
        ],
        "birthday": "birthday",
        "emails": [
            {
                "email": "email",
                "type": "HOME"
            },
            {
                "email": "email",
                "type": "WORK"
            }
        ],
        "name": {
            "first_name": "first name value",
            "formatted_name": "formatted name value",
            "last_name": "last name value",
            "suffix": "suffix value"
        },
        "org": {
            "company": "company name",
            "department": "dep name",
            "title": "title"
        },
        "phones": [
            {
                "phone": "Phone number",
                "wa-id": "WA-ID value",
                "type": "MAIN"
            },
            {
                "phone": "Phone number",
                "type": "HOME"
            },
            {
                "phone": "Phone number",
                "type": "WORK"
            }
        ],
        "urls": [{
            "url": "some url",
            "type": "WORK"
        }]
    }
]

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.

Template Object

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

Beginning in v2.27.8, a template's namespace must be the namespace associated with the WABA that owns the phone number in the current WhatsApp Business on-prem client. Otherwise, the message will fail to send.

In addition, from v2.41 and onwards, namespace will be an optional field.

NameDescription

name

Required.

Name of the template.

language

object

Required.

Contains a language object. Specifies the language the template may be rendered in.


The language object can contain the following fields:

policystringRequired. The language policy the message should follow. The only supported option is deterministic. See Language Policy Options.

codestringRequired. The code of the language or locale to use. Accepts both language and language_locale formats (e.g., en and en_US). For all codes, see Supported Languages.

components

array of objects

Optional.

Array of components objects containing the parameters of the message.

namespace

Optional. Only used for On-Premises API.

Namespace of the template.

Components Object

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

NameDescription (Click the arrow in the left column for supported options.)

type

string

Required.

Describes the component type.


Example of a components object with an array of parameters object nested inside:

 "components": [{
   "type": "body",
   "parameters": [{
                "type": "text",
                "text": "name"
            },
            {
            "type": "text",
            "text": "Hi there"
            }]
      }] 

Supported Options

  • header
  • body
  • button

For text-based templates, we only support the type=body.

sub_type

string

Required when type=button. Not used for the other types.

Type of button to create.

Supported Options

  • quick_reply: Refers to a previously created quick reply button that allows for the customer to return a predefined message.
  • 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

array of objects

Required when type=button.

Array of parameter objects with the content of the message.

For components of type=button, see the button parameter object.

index

Required when type=button. Not used for the other types. Only used for Cloud API.

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

Parameters Object

NameDescription

type

Required.

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


Example of a parameter object with a text value:

{
    "type": "text",
    "text": "Customer"
}

Example of a parameter object with a media type value of document:

{
    "type": "document",
    "document":{
        "id": "doc_id",
        "filename": "doc_name"
    }
}

This is also known as a Media message template and they only support PDF documents.


For more information about currency and date_time, see the Localizable Parameters section.

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.

Example of button type with sub_type quick_reply:

 {
    "type": "button",
    "sub_type": "quick_reply",
    "index": 0,
    "parameters": 
     [{
    	"type": "payload",
    	"payload": "Yes-Button-Payload"
     }]
} 

Hsm Object

The hsm object has been deprecated with v2.39 of the WhatsApp Business on-premises/reference. Please use the template object instead.

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.

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

string

Required.

The type of interactive message you want to send. Supported values:

  • list: Use it for List Messages.
  • button: Use it for Reply Buttons.
  • product: Use it for Single Product Messages.
  • product_list: Use it for Multi-Product Messages.

header

object

Required for type product_list. Optional for other types.

Header content displayed on top of a message. You cannot set a header if your interactive object is of product type.


The header object contains the following fields:

documentobjectRequired if type is set to document. Contains the media object with the document.

imageobjectRequired if type is set to image. Contains the media object with the image.

videoobjectRequired if type is set to video. Contains the media object with the video.

textstringRequired if type is set to text. Text for the header. Formatting allows emojis, but not markdown. Maximum length: 60 characters.

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

text – for List Messages, Reply Buttons, and Multi-Product Messages.

video – for Reply Buttons.

image – for Reply Buttons.

document – for Reply Buttons.

body

object

Optional for type product. Required for other message types.

An object with the body of the message.


The body object contains the following field:

textstringRequired if body is present. The content of the message. Emojis and markdown are supported. Maximum length: 1024 characters.

footer

object

Optional.

An object with the footer of the message.


The footer object contains the following field:

textstringRequired if footer is present. The footer content. Emojis, markdown, and links are supported. Maximum length: 60 characters.

action

object

Required.

An action object with what you want the user to perform after reading the message. See action object for full information.

Action Object

NameDescription

button

string

Required for List Messages.

Button content. It cannot be an empty string and must be unique within the message. Emojis are supported, markdown is not. Maximum length: 20 characters.

buttons

object

Required for Reply Button Messages.

A button object. The object can contain the following parameters:

type – The only supported option is reply for Reply Button Messages.

title – Button title. It cannot be an empty string and must be unique within the message. Emojis are supported, markdown is not. Maximum length: 20 characters.

id – Unique identifier for your button. This ID is returned in the webhook when the button is clicked by the user. Maximum length: 256 characters.


You cannot have leading or trailing spaces when setting the ID.

sections

array of objects

Required for List Messages and Multi-Product Messages.

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

catalog_id

string

Required for Single Product Messages and Multi-Product Messages.

Unique identifier of the Facebook catalog linked to your WhatsApp Business Account. This ID can be retrieved via Commerce Manager.

product_retailer_id

string

Required for Single Product Messages and Multi-Product Messages.

Unique identifier of the product in a catalog. Maximum 100 characters for both Single Product and Multi-Product messages.


To get this ID, go to Commerce Manager, select your Facebook Business account, and you will see a list of shops connected to your account. Click the shop you want to use. On the left-side panel, click Catalog > Items, and find the item you want to mention. The ID for that item is displayed under the item's name.

Section Object

NameDescription

title

string

Required if the message has more than one section.

Title of the section. Maximum length: 24 characters.

rows

array of objects

Required for List Messages.

Contains a list of row objects. Limited to 10 rows across all sections.


Each row object contains the following fields:

titlestringRequired. Maximum length: 24 characters.

IDstringRequired. Maximum length: 200 characters.

descriptionstringOptional. Maximum length: 72 characters.

product_items

array of objects

Required for Multi-Product Messages.

Array of product objects. There is a minimum of 1 product per section and a maximum of 30 products across all sections.


Each product object contains the following field:

product_retailer_idstringRequired for Multi-Product Messages. Unique identifier of the product in a catalog. To get this ID, go to Commerce Manager, select your account and the shop you want to use. Then, click Catalog > Items, and find the item you want to mention. The ID for that item is displayed under the item's name.

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": "interactive",
  "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": "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" 
          }
        }
      ] 
    } # end action   
  } # end interactive

}

Interactive messages (Multi and Single Product Messages):

{ 
  "recipient_type": "individual",
  "to" : "{{Recipient-WA-ID}}",
  "type": "interactive",
  "interactive": {
    "type": "product",
    "body": {
      "text": "body text"
    },
    "footer": {
      "text": "footer text"
    },
    "action": {
      "catalog_id": "catalog-ID",
      "product_retailer_id": "product-ID"
    }
  }
}

Interactive messages (Multi-Product Messages):

{ 
  "recipient_type": "individual",
  "to" : "whatsapp-id",
  "type": "interactive",
  "interactive": 
    {
    "type": "product_list",
    "Header":{
       "type": "text",
        "text": "text-header-content"
     },
     "body":{
        "text": "text-body-content"
      },
     "footer":{
        "text":"text-footer-content"
     },
     "action":{
        "catalog_id":"catalog-id",
        "sections": [
             {
             "title": "section-title",             
             "product_items": [
                  { "product_retailer_id": "product-SKU-in-catalog" },
                  { "product_retailer_id": "product-SKU-in-catalog" },
                            ...
              ]},
              {
              "title": "the-section-title",
              "product_items": [
                 { "product_retailer_id": "product-SKU-in-catalog" }
                           ...
              ]},
               ...
       ]
     },  
    }
}

The response to your call includes a combination of following components: meta, messages (payload), and errors. See WhatsApp Business on-premises/reference 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 on-premises/reference 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 on-premises/reference 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 Text Messages Per Second

Single Shard

70

Multi Shard (32 shards)

250

FAQ

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."