Use the /PHONE_NUMBER_ID/messages
endpoint to send text, media, contacts, location, and interactive messages, as well as message templates to your customers. Learn more about the messages you can send
.
Endpoint | Authentication |
---|---|
(See Get Phone Number ID ) |
Developers can authenticate their API calls with the access token generated in the App Dashboard > WhatsApp > API Setup . Solution Partners must authenticate themselves with an access token with the |
Messages are identified by a unique ID (WAMID). You can track message status in the Webhooks through its WAMID. You could also mark an incoming message as read through messages endpoint. This WAMID can have a maximum length of up to 128 characters.
With the Cloud API, there is no longer a way to explicitly check if a phone number has a WhatsApp ID. To send someone a message using the Cloud API, just send it directly to the customer's phone number —after they have opted-in . See Reference, Messages for examples.
To send a message, you must first assemble a message object with the content you want to send. These are the parameters used in a message
object:
audio
Required when type=audio
.
A media
object
containing audio.
biz_opaque_callback_data
Optional.
An arbitrary string, useful for tracking.
For example, you could pass the message template ID in this field to track your customer's journey starting from the first message you send. You could then track the ROI of different message template types to determine the most effective one.
Any app subscribed to the messages
webhook field on the WhatsApp Business Account can get this string, as it is included in statuses
object
within webhook payloads.
Cloud API does not process this field, it just returns it as part of sent/delivered/read message webhooks.
Maximum 512 characters.
Cloud API only .
contacts
Required when type=contacts
.
A contacts
object
.
context
Required if replying to any message in the conversation.
An object containing the ID of a previous message you are replying to. For example:
{"message_id":"MESSAGE_ID"}
Cloud API only .
document
Required when type=document
.
A media
object
containing a document.
hsm
Contains an hsm
object
. This option was deprecated with v2.39
of the On-Premises API. Use the template
object instead.
On-Premises API only .
image
Required when type=image
.
A media
object
containing an image.
interactive
Required when type=interactive
.
An interactive
object
. The components of each interactive
object generally follow a consistent pattern: header
, body
, footer
, and action
.
location
Required when type=location
.
A location
object
.
messaging_product
preview_url
Required if type=text
.
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
.
On-Premises API
only. Cloud API users can use the same functionality with the preview_url
field inside a text object
.
recipient_type
Optional.
Currently, you can only send messages to individuals. Set this as individual
.
Default: individual
status
A message's status. You can use this field to mark a message as read
. See the following guides for information:
sticker
Required when type=sticker
.
A media
object
containing a sticker.
Cloud API: Static and animated third-party outbound stickers are supported in addition to all types of inbound stickers. A static sticker needs to be 512x512 pixels and cannot exceed 100 KB. An animated sticker must be 512x512 pixels and cannot exceed 500 KB.
On-Premises API: Only static third-party outbound stickers are supported in addition to all types of inbound stickers. A static sticker needs to be 512x512 pixels and cannot exceed 100 KB. Animated stickers are not supported.
template
Required when type=template
.
A template
object
.
text
Required for text messages.
A text
object
.
to
Required.
WhatsApp ID or phone number of the customer you want to send a message to. See Phone Number Formats .
If needed, On-Premises API users can get this number by calling the contacts
endpoint
.
type
Optional.
The type of message you want to send. If omitted, defaults to text
.
The following objects are nested inside the message object:
Name | Description |
---|---|
|
Optional. Full contact address(es) formatted as an |
|
Optional. |
|
Optional. Contact email address(es) formatted as an |
|
Required. Full contact name formatted as a *At least one of the optional parameters needs to be included along with the |
|
Optional. Contact organization information formatted as an |
|
Optional. Contact phone number(s) formatted as a |
|
Optional. Contact URL(s) formatted as a |
action
Required.
Action you want the user to perform after reading the message.
body
Optional for type product
. Required for other message types.
An object with the body of the message.
The body
object contains the following field:
text
string
– Required if body is present.
The content of the message. Emojis and markdown are supported. Maximum length: 1024 characters.
footer
Optional.An object with the footer of the message.
The footer
object contains the following field:
text
string
– Required if footer is present.
The footer content. Emojis, markdown, and links are supported. Maximum length: 60 characters.
header
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. See header
object
for more information.
type
Required.
The type of interactive message you want to send. Supported values:
button
: Use for Reply Buttons.catalog_message
: Use for Catalog Messages.list
: Use for List Messages.product
: Use for Single-Product Messages.product_list
: Use for Multi-Product Messages.flow
: Use for Flows Messages.The following objects are nested inside the interactive
object:
button
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
Required for Reply Buttons.
A button object can contain the following parameters:
type
: only supported type is reply
(for Reply Button)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 can have up to 3 buttons. You cannot have leading or trailing spaces when setting the ID.
catalog_id
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 the Meta Commerce Manager .
product_retailer_id
Required for Single Product Messages and Multi-Product Messages.
Unique identifier of the product in a catalog.
To get this ID go to Meta Commerce Manager and select your Meta Business account. 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.
sections
Required for List Messages and Multi-Product Messages.
Array of section
objects. Minimum of 1, maximum of 10. See section
object
.
mode
Optional for Flows Messages.
The current mode of the Flow, either draft
or published
.
Default: published
flow_message_version
Required for Flows Messages.
Must be 3
.
flow_token
Required for Flows Messages.
A token that is generated by the business to serve as an identifier.
flow_id
Required for Flows Messages.
Unique identifier of the Flow provided by WhatsApp.
flow_cta
Required for Flows Messages.
Text on the CTA button, eg. "Signup".
Maximum length: 20 characters (no emoji).
flow_action
Optional for Flows Messages.
navigate
or data_exchange
. Use navigate
to predefine the first screen as part of the message. Use data_exchange
for advanced use-cases where the first screen is provided by your endpoint
.
Default: navigate
flow_action_payload
Optional for Flows Messages.
Required only if flow_action
is navigate
. The object can contain the following parameters:
screen
string
– Required.
The id
of the first screen of the Flow.
data
object
– Optional.
The input data for the first screen of the Flow. Must be a non-empty object.
document
Required if type
is set to document
.
Contains the media object for this document.
image
Required if type
is set to image
.
Contains the media object for this image.
text
Required if type
is set to text
.
Text for the header. Formatting allows emojis, but not markdown.
Maximum length: 60 characters.
type
Required.
The header type you would like to use. Supported values:
text
: Used for List Messages, Reply Buttons, and Multi-Product Messages.video
: Used for Reply Buttons.image
: Used for Reply Buttons.document
: Used for Reply Buttons. video
Required if type
is set to video
.
Contains the media object for this video.
product_items
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_id
string
– Required for Multi-Product Messages.
Unique identifier of the product in a catalog. To get this ID, go to the Meta 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. rows
Required for List Messages.
Contains a list of rows. You can have a total of 10 rows across your sections.
Each row must have a title (Maximum length: 24 characters) and an ID (Maximum length: 200 characters). You can add a description (Maximum length: 72 characters), but it is optional.
Example:
"rows": [ { "id":"unique-row-identifier-here", "title": "row-title-content-here", "description": "row-description-content-here", } ]
title
Required if the message has more than one section.
Title of the section.
Maximum length: 24 characters.
Name | Description |
---|---|
|
Required. Location latitude in decimal degrees. |
|
Required. Location longitude in decimal degrees. |
|
Required. Name of the location. |
|
Required. Address of the location. |
See Get Media ID for information on how to get the ID of your media object. For information about supported media types for Cloud API, see Supported Media Types .
id
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
Required when type
is audio
, document
, image
, sticker
, or video
and you are not using an uploaded media ID (i.e. you are hosting the media asset on your public server).
The protocol and URL of the media to be sent. Use onlywith HTTP/HTTPS URLs.
Do not use this field when message type
is set to text
.
Cloud API users only:
Content-Type
HTTP header. For example: Content-Type: video/mp4
. See Supported Media Types
for a list of supported media and their MIME types. caption
Optional.
Media asset caption. Do not use with audio
or sticker
media.
On-Premises API users:
document
media. filename
Optional.
Describes the filename for the specific document. Use onlywith document
media.
The extension of the filename will specify what format the document is displayed as in WhatsApp.
provider
Optional. On-Premises API only.
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
.
Conversation-based pricing has changed. See Pricing to learn how our new conversation-based pricing model works.
In addition, visibility of metric_types
have changed effective July 1, 2023.Please see the Conversation Analytics table
for more details.
Name | Description |
---|---|
|
Required. Name of the template. |
|
Required. Contains a The |
|
Optional. Array of |
|
Optional. Only used for On-Premises API. Namespace of the template. |
The following objects are nested inside the template
object:
type
Required.
Indicates the type of parameter for the button.
Supported Options
"payload"
"text"
payload
Required for quick_reply
buttons.
Developer-defined payload that is returned when the button is clicked in addition to the display text on the button.
See Callback from a Quick Reply Button Click for an example.
text
Required for URL buttons.
Developer-provided suffix that is appended to the predefined prefix URL in the template.
type
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
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.catalog
: Refers to a previously created catalog button that allows for the customer to return a full product catalog. parameters
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.
Position index of the button. You can have up to 10 buttons using index values of 0 to 9.
Name | Description |
---|---|
|
Required. Default text if localization fails. |
|
Required. Currency code as defined in |
|
Required. Amount multiplied by 1000. |
Name | Description |
---|---|
|
Required. Default text. For Cloud API, we always use the fallback value, and we do not attempt to localize using other optional fields. |
type
Required.
Describes the parameter type. Supported values:
currency
date_time
document
image
text
video
For text-based templates, the only supported parameter types are currency
, date_time
, and text
.
text
Required when type=text
.
The message’s text. Character limit varies based on the following included component type.
For the header
component type:
For the body
component type:
body
is the only component type included currency
Required when type=currency
.
A currency
object
.
date_time
Required when type=date_time
.
A date_time
object
.
image
Required when type=image
.
A media
object of type image
. Captions not supported when used in a media template.
document
Required when type=document
.
A media
object of type document
. Only PDF documents are supported for media-based message templates. Captions not supported when used in a media template.
video
Required when type=video
.
A media
object of type video
. Captions not supported when used in a media template.
Name | Description |
---|---|
|
Required for text messages. The text of the text message which can contain URLs which begin with http:// or https:// and formatting. See available formatting options here . If you include URLs in your text and want to include a preview box in text messages ( Maximum length: 4096 characters |
|
Optional. Cloud API only. Set to If On-Premises API users, use |
message_id
Required.
The WhatsApp Message ID (wamid) of the message on which the reaction should appear. The reaction will not be sent if:
If the ID is of a message that has been deleted, the message will not be delivered.
emoji
Required.
Emoji to appear on the message.
See the following guides for full information on how to use the /messages
endpoint to send messages:
curl -X POST \
'https://graph.facebook.com/ v20.0
/FROM_PHONE_NUMBER_ID/messages' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "PHONE_NUMBER",
"type": "text",
"text": { // the text object
"preview_url": false,
"body": "MESSAGE_CONTENT"
}
}'
curl -X POST \
'https://graph.facebook.com/ v20.0
/FROM_PHONE_NUMBER_ID/messages' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "PHONE_NUMBER",
"type": "reaction",
"reaction": {
"message_id": "wamid.HBgLM...",
"emoji": "\uD83D\uDE00"
}
}'
curl -X POST \
'https://graph.facebook.com/ v20.0
/FROM-PHONE-NUMBER-ID/messages' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "PHONE-NUMBER",
"type": "image",
"image": {
"id" : "MEDIA-OBJECT-ID"
}
}'
curl -X POST \
'https://graph.facebook.com/ v20.0
/FROM_PHONE_NUMBER_ID/messages' \
-H 'Authorization: ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"messaging_product": "whatsapp",
"to": "PHONE_NUMBER",
"type": "location",
"location": {
"longitude": LONG_NUMBER,
"latitude": LAT_NUMBER,
"name": LOCATION_NAME,
"address": LOCATION_ADDRESS
}
}'
curl -X POST \
'https://graph.facebook.com/ v20.0
/FROM_PHONE_NUMBER_ID/messages' \
-H 'Authorization: ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"messaging_product": "whatsapp",
"to": "PHONE_NUMBER",
"type": "contacts",
"contacts": [{
"addresses": [{
"street": "STREET",
"city": "CITY",
"state": "STATE",
"zip": "ZIP",
"country": "COUNTRY",
"country_code": "COUNTRY_CODE",
"type": "HOME"
},
{
"street": "STREET",
"city": "CITY",
"state": "STATE",
"zip": "ZIP",
"country": "COUNTRY",
"country_code": "COUNTRY_CODE",
"type": "WORK"
}],
"birthday": "YEAR_MONTH_DAY",
"emails": [{
"email": "EMAIL",
"type": "WORK"
},
{
"email": "EMAIL",
"type": "HOME"
}],
"name": {
"formatted_name": "NAME",
"first_name": "FIRST_NAME",
"last_name": "LAST_NAME",
"middle_name": "MIDDLE_NAME",
"suffix": "SUFFIX",
"prefix": "PREFIX"
},
"org": {
"company": "COMPANY",
"department": "DEPARTMENT",
"title": "TITLE"
},
"phones": [{
"phone": "PHONE_NUMBER",
"type": "HOME"
},
{
"phone": "PHONE_NUMBER",
"type": "WORK",
"wa_id": "PHONE_OR_WA_ID"
}],
"urls": [{
"url": "URL",
"type": "WORK"
},
{
"url": "URL",
"type": "HOME"
}]
}]
}'
curl -X POST \
'https://graph.facebook.com/ v20.0
/FROM_PHONE_NUMBER/messages' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "PHONE_NUMBER",
"type": "interactive",
"interactive": {
"type": "product",
"body": {
"text": "optional body text"
},
"footer": {
"text": "optional footer text"
},
"action": {
"catalog_id": "CATALOG_ID",
"product_retailer_id": "ID_TEST_ITEM_1"
}
}
}'
curl -X POST \
'https://graph.facebook.com/ v20.0
/FROM_PHONE_NUMBER/messages' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "PHONE_NUMBER",
"type": "interactive",
"interactive": {
"type": "product_list",
"header":{
"type": "text",
"text": "header-content"
},
"body": {
"text": "body-content"
},
"footer": {
"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": "section-title",
"product_items": [
{ "product_retailer_id": "product-SKU-in-catalog" },
{ "product_retailer_id": "product-SKU-in-catalog" },
...
]
}
]
}
}
}
curl -X POST \
'https://graph.facebook.com/ v20.0
/FROM_PHONE_NUMBER/messages' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "PHONE_NUMBER",
"type": "interactive",
"interactive" : {
"type" : "catalog_message",
"body" : {
"text": "Thanks for your order! Tell us what address you’d like this order delivered to."
},
"action": {
"name": "catalog_message",
"parameters": {
"thumbnail_product_retailer_id": "<Product-retailer-id>"
}
}
}
}'
curl -X POST \
'https://graph.facebook.com/ v20.0
/FROM_PHONE_NUMBER/messages' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "PHONE_NUMBER",
"type": "interactive",
"interactive" : {
"type": "flow",
"header": {
"type": "text",
"text": "Flow message header"
},
"body": {
"text": "Flow message body"
},
"footer": {
"text": "Flow message footer"
},
"action": {
"name": "flow",
"parameters": {
"flow_message_version": "3",
"flow_token": "AQAAAAACS5FpgQ_cAAAAAD0QI3s",
"flow_id": "<FLOW_ID>",
"flow_cta": "Book!",
"flow_action": "navigate",
"flow_action_payload": {
"screen": "<SCREEN_ID>",
"data": {
"user_name": "name",
"user_age": 25
}
}
}
}
}
}'
curl -X POST \
'https://graph.facebook.com/ v20.0
/FROM_PHONE_NUMBER_ID/messages' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "PHONE_NUMBER",
"type": "interactive",
"interactive": {
"type": "list",
"header": {
"type": "text",
"text": "HEADER_TEXT"
},
"body": {
"text": "BODY_TEXT"
},
"footer": {
"text": "FOOTER_TEXT"
},
"action": {
"button": "BUTTON_TEXT",
"sections": [
{
"title": "SECTION_1_TITLE",
"rows": [
{
"id": "SECTION_1_ROW_1_ID",
"title": "SECTION_1_ROW_1_TITLE",
"description": "SECTION_1_ROW_1_DESCRIPTION"
},
{
"id": "SECTION_1_ROW_2_ID",
"title": "SECTION_1_ROW_2_TITLE",
"description": "SECTION_1_ROW_2_DESCRIPTION"
}
]
},
{
"title": "SECTION_2_TITLE",
"rows": [
{
"id": "SECTION_2_ROW_1_ID",
"title": "SECTION_2_ROW_1_TITLE",
"description": "SECTION_2_ROW_1_DESCRIPTION"
},
{
"id": "SECTION_2_ROW_2_ID",
"title": "SECTION_2_ROW_2_TITLE",
"description": "SECTION_2_ROW_2_DESCRIPTION"
}
]
}
]
}
}
}'
curl -X POST \
'https://graph.facebook.com/ v20.0
/FROM_PHONE_NUMBER_ID/messages' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "PHONE_NUMBER",
"type": "interactive",
"interactive": {
"type": "button",
"body": {
"text": "BUTTON_TEXT"
},
"action": {
"buttons": [
{
"type": "reply",
"reply": {
"id": "UNIQUE_BUTTON_ID_1",
"title": "BUTTON_TITLE_1"
}
},
{
"type": "reply",
"reply": {
"id": "UNIQUE_BUTTON_ID_2",
"title": "BUTTON_TITLE_2"
}
}
]
}
}
}'
Conversation-based pricing has changed. See Pricing to learn how our new conversation-based pricing model works.
In addition, visibility of metric_types
have changed effective July 1, 2023.Please see the Conversation Analytics table
for more details.
curl -X POST \
'https://graph.facebook.com/ v20.0
/FROM_PHONE_NUMBER_ID/messages' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "PHONE_NUMBER",
"type": "template",
"template": {
"name": "TEMPLATE_NAME",
"language": {
"code": "LANGUAGE_AND_LOCALE_CODE"
},
"components": [
{
"type": "header",
"parameters": [
{
"type": "image",
"image": {
"link": "http(s)://URL"
}
}
]
},
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "TEXT_STRING"
},
{
"type": "currency",
"currency": {
"fallback_value": "VALUE",
"code": "USD",
"amount_1000": NUMBER
}
},
{
"type": "date_time",
"date_time": {
"fallback_value": "MONTH DAY, YEAR"
}
}
]
},
{
"type": "button",
"sub_type": "quick_reply",
"index": "0",
"parameters": [
{
"type": "payload",
"payload": "PAYLOAD"
}
]
},
{
"type": "button",
"sub_type": "quick_reply",
"index": "1",
"parameters": [
{
"type": "payload",
"payload": "PAYLOAD"
}
]
}
]
}
}'
curl -X POST \
'https://graph.facebook.com/ v20.0
/FROM_PHONE_NUMBER/messages' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"messaging_product": "whatsapp",
"context": {
"message_id": "MESSAGE_ID"
},
"to": "PHONE_NUMBER",
"type": "text",
"text": {
"preview_url": false,
"body": "your-text-message-content"
}
}’
{ "messaging_product": "whatsapp", "contacts": [ { "input": "16505555555", "wa_id": "16505555555" } ], "messages": [ { "id": "wamid.HBgLMTY1MDUwNzY1MjAVAgARGBI5QTNDQTVCM0Q0Q0Q2RTY3RTcA" } ] }
Applies to businesses in Brazil, Colombia, and Singapore, starting September 12, 2023. Applies to all businesses starting October 12, 2023.
Messages will have one of the following statuses which will be returned in each of the messages
objects
"message_status":"accepted"
: means the message was sent to the intended recipient"message_status":"held_for_quality_assessment"
: means the message send was delayed until quality can be validated and it will either be sent or dropped at this point{ "messaging_product": "whatsapp", "contacts": [ { "input": "16505555555", "wa_id": "16505555555" } ], "messages": [ { "id": "wamid.HBgLMTY1MDUwNzY1MjAVAgARGBI5QTNDQTVCM0Q0Q0Q2RTY3RTcA", "message_status": "accepted", } ] }