Template messages
To send a message to a user first a template must be used. These templates must be setup and approved before they can be used. You can request templates via the Channels portal.
Once a template is approved you can use the template namespace and name to send a message (Use the details button in your template overview to find these values).
The template message must have the exact same number of variables as the template has. The same template can be set-up in multiple languages, hence you also need a language parameter.
Please remember that a user must have opted in for the type of communication as well. The opt-in must be an active opt-in. This means it must be triggered by a user action, such as entering a phone number in a WhatsApp field or checking a box to indicate consent.
Requirements for Opt-In:
You are obligated to adhere to the following criteria when securing opt-ins:
- Clearly communicate that users are opting in to receive messages from you via WhatsApp.
- Explicitly mention your name for which users are opting in to receive messages.
- Ensure compliance with relevant laws and regulations.
Approved Opt-In Methods:
Any opt-in method must align with the aforementioned requirements to be considered policy compliant. The following are examples of acceptable opt-in methods:
- SMS
- Website
- Within a WhatsApp thread
- Over the phone (utilizing an interactive voice response (IVR) flow)
- In-person or via paper (allowing users to physically sign a document to opt in)
You must persist in enhancing the user experience during the opt-in process. To achieve this, you should:
- Establish clear expectations for users regarding the messages they will receive. This involves obtaining opt-ins that cover various message categories (e.g., order updates, relevant offers, product recommendations) or obtaining separate opt-ins for specific message categories. This approach reduces the risk of users blocking you due to unsolicited messages.
- Provide explicit instructions on how users can opt out of receiving messages from specific categories and ensure compliance with these requests.
- Design opt-in and opt-out processes that are transparent and user-friendly.
- Clearly articulate the value of receiving information via WhatsApp.
- Vigilantly monitor the quality rating, especially when introducing new opt-in methods.
Important
It is strongly advised that you prioritize user experience optimization when designing opt-in processes.
Users can block or report businesses and Meta will rate limit businesses if the business's quality is low for a sustained period of time.
A template object contains a 'whatsapp' object, which corresponds to the template object in the WhatsApp for Business docs.
Field | Description | Required |
---|---|---|
namespace | The namespace that will be used. Will be provided to you after the template is approved | Yes |
element_name | The element name of the template that will be used. Will be provided to you after the template is approved | Yes |
language | Specifies the language, see below for object definition | Yes |
components | Array containing the content-components of the message, to personalize the templated message. See the WhatsApp documentation for advanced details. | Yes (only for media templates) |
localizable_params | An array of parameters to personalize the templated message. Use components if your template needs media or has a header/footer. See the WhatsApp documentation for advanced details. | Yes (only for regular templates) |
Note
Only PDF documents are supported for media-based message templates.
Warning
The Text parameter within a template cannot be left empty. Doing so will result in an error.
Media template message
Media templates is a newer generation of WhatsApp templates, which in addition to the text body, can also feature a header with an additional image, video or document, as well as a footer.
The header can have three component types: image
, document
, video
and text
. The body and footer can only have the component type text
. The parameters
are similar to the localizable_params
of the older template format, but NOT the same.
In the example below, we send a media template message.
{
"messages": {
"msg": [
{
"from": "00316098765432",
"to": [
{
"number": "0031612345678"
}
],
"body": {
"type": "auto",
"content": "This is a WhatsApp message"
},
"allowedChannels": ["WhatsApp"],
"richContent": {
"conversation": [
{
"template": {
"whatsapp": {
"namespace": "your namespace id here",
"element_name": "TEMPLATE_NAME",
"language": {
"policy": "deterministic",
"code": "en"
},
"components": [
{
"type": "header",
"parameters": [
{
"type": "image",
"media": {
"mediaName": "conversational-commerce",
"mediaUri": "https://www.cm.com/cdn/web/nl-nl/blog/conversational-commerce.jpg",
"mimeType": "image/jpeg"
}
}
]
},
{
"type": "body",
"parameters": [
{
//Text cannot be empty, always need to have value
"type": "text",
"text": "replace-value-1"
},
{
"type": "currency",
"currency": {
"fallback_value": "$100.99",
"code": "USD",
"amount_1000": 100990
}
},
{
"type": "date_time",
"date_time": {
"fallback_value": "February 25, 1977",
"day_of_week": 5,
"day_of_month": 25,
"year": 1977,
"month": 2,
"hour": 15,
"minute": 33, // OR
"timestamp": 1485470276
}
}
]
}
]
}
}
}
]
}
}
]
}
}
Interactive template message
Interactive templates is a newer generation of WhatsApp templates, which in addition to the media template, can also support button
-components.
The button
-component can be either of sub_type
: quick_reply
or url
.
- With
quick_reply
the end-user will see a suggestion to respond with. The button text itself has to be specified during creation of the template. - With
url
you are able to send a Call-to-action button. This can be a phone number to call, or an url to visit. This has to be specified during creation of the template as well.
The payload
on quick_reply
buttons will be sent back when an end-user interacts with such a button. The maximum length of the payload is 128 characters. This will be explained in the incoming messages documentation.
In the example below, we send an interactive template message.
{
"messages": {
"msg": [
{
"from": "00316098765432",
"to": [
{
"number": "00316012345678"
}
],
"body": {
"type": "auto",
"content": "fallback message"
},
"allowedChannels": ["WhatsApp"],
"richContent": {
"conversation": [
{
"template": {
"whatsapp": {
"namespace": "your namespace id here",
"element_name": "TEMPLATE_NAME",
"language": {
"policy": "deterministic",
"code": "en"
},
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "your-text-string"
}
]
},
{
"type": "button",
"sub_type": "quick_reply",
"index": "0",
"parameters": [
{
"type": "payload",
// Business Developer-defined payload
"payload": "aGlV0RT"
}
]
},
{
"type": "button",
"sub_type": "url",
"index": "1",
"parameters": [
{
"type": "text",
// Business Developer-defined dynamic URL suffix
"text": "9rwn"
}
]
},
{
"type": "button",
"sub_type": "url",
"index": "2",
"parameters": [
{
"type": "text",
// Business Developer-defined dynamic URL suffix
"text": "ticket.pdf"
}
]
}
]
}
}
}
]
}
}
]
}
}
Template message (Regular)
This is the template message format without media. There are some rules that must be adhered to:
Field | Description | Required |
---|---|---|
currency | If the currency object is used, it must contain required parameters currency_code and amount_1000 | No |
date_time | If the date_time object is used, further definition of the date and time is required. See the example below for two of the options | No |
The currency
object:
Field | Description | Required |
---|---|---|
fallback_value | Default text if localization fails. All of the localization parameters must have a fallback value. When specifying text, just the fallback value is required | Yes |
code | Currency code as defined in ISO 4217 | Yes |
amount_1000 | Amount multiplied by 1000 | Yes |
The date_time
object:
Field | Description | Required |
---|---|---|
fallback_value | Default text if localization fails. All of the localization parameters must have a fallback value. When specifying text, just the fallback value is required | Yes |
day_of_week | If different from the value derived from the date (if specified), use the derived value. Both strings and numbers are accepted. Options: "MONDAY", 1, "TUESDAY", 2, "WEDNESDAY", 3, "THURSDAY", 4, "FRIDAY", 5, "SATURDAY", 6, "SUNDAY", 7 | No |
year | The year | No |
month | The month | No |
day_of_month | The day of month | No |
hour | The hour | No |
minute | The minute | No |
calendar | Type of calendar. Options: GREGORIAN, SOLAR_HIJRI | No |
Note
The hsm-templates that use the
localizable_params
-structure, will be deprecated in a future version.
In the example below, we send a template message.
{
"messages": {
"msg": [
{
"from": "00316098765432",
"to": [
{
"number": "0031612345678"
}
],
"body": {
"type": "auto",
"content": "This is a WhatsApp message"
},
"allowedChannels": ["WhatsApp"],
"richContent": {
"conversation": [
{
"template": {
"whatsapp": {
"namespace": "your namespace id here",
"element_name": "TEMPLATE_NAME",
"language": {
"policy": "deterministic",
"code": "en"
},
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "your-text-string"
},
{
"type": "currency",
"currency": {
"fallback_value": "$100.99",
"code": "USD",
"amount_1000": 100990
}
},
{
"type": "date_time",
"date_time": {
"fallback_value": "February 25, 1977",
"day_of_week": 5,
"day_of_month": 25,
"year": 1977,
"month": 2,
"hour": 15,
"minute": 33
}
},
{
"type": "date_time",
"date_time": {
"fallback_value": "February 25, 1977",
"timestamp": 1485470276
}
}
]
}
]
}
}
}
]
}
}
]
}
}
Template message (Flows)
In the example below, we send an interactive WhatsApp Flows message.
{
"messages": {
"msg": [
{
"from": "00316098765432",
"to": [
{
"number": "00316012345678"
}
],
"body": {
"type": "auto",
"content": "fallback message"
},
"allowedChannels": [
"WhatsApp"
],
"richContent": {
"conversation": [
{
"template": {
"whatsapp": {
"namespace": "your-namespace",
"element_name": "your-template-name",
"language": {
"policy": "deterministic",
"code": "en"
},
"components": [
{
"type": "button",
"sub_type": "flow",
"index": "0",
"parameters": [
{
"type": "action",
"action": {
"flow_token": "your-flow-token",
"flow_action_data": {}
}
}
]
}
]
}
}
}
]
}
}
]
}
}
Authentication messages
Authentication messages allow you to send messages with an authentication code and a 'copy code' button.
In the example below, we send an Authentication message.
{
"messages": {
"msg": [
{
"from": "00316098765432",
"to": [
{
"number": "00316012345678"
}
],
"body": {
"type": "auto",
"content": "authentication message"
},
"allowedChannels": [
"WhatsApp"
],
"richContent": {
"conversation": [
{
"template": {
"whatsapp": {
"namespace": "your-namespace",
"element_name": "your-template-name",
"language": {
"policy": "deterministic",
"code": "en"
},
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "123456"
}
]
},
{
"type": "button",
"sub_type": "url",
"index": "0",
"parameters": [
{
"type": "text",
"text": "123456"
}
]
}
]
}
}
}
]
}
}
]
}
}
Template message (Carousel)
In the example below, we send an interactive WhatsApp Carousel message.
{
"messages": {
"msg": [
{
"from": "00316098765432",
"to": [
{
"number": "00316012345678"
}
],
"body": {
"type": "auto",
"content": "fallback message"
},
"allowedChannels": [
"WhatsApp"
],
"richContent": {
"conversation": [
{
"template": {
"whatsapp": {
"namespace": "your-namespace",
"element_name": "your-template-name",
"language": {
"policy": "deterministic",
"code": "en"
},
"components": [
{
"type": "BODY",
"parameters": []
},
{
"type": "CAROUSEL",
"cards": [
{
"card_index": 0,
"components": [
{
"type": "HEADER",
"parameters": [
{
"type": "IMAGE",
"image": {
"mediaUri": "https://cmcom.s3.eu-west-3.amazonaws.com/webimage-C0D8E5EE-2ABC-41F2-B3E694BF22A1D6C6.png"
}
}
]
},
{
"type": "BODY",
"parameters": []
},
{
"type": "BUTTON",
"sub_type": "QUICK_REPLY",
"index": 0,
"parameters": [
{
"type": "PAYLOAD",
"payload": "your-payload-here"
}
]
}
]
},
{
"card_index": 1,
"components": [
{
"type": "HEADER",
"parameters": [
{
"type": "IMAGE",
"image": {
"mediaUri": "https://cmcom.s3.eu-west-3.amazonaws.com/webimage-4C0C8462-0F93-41AC-A66F3D614E53DFA5.png"
}
}
]
},
{
"type": "BODY",
"parameters": []
},
{
"type": "BUTTON",
"sub_type": "QUICK_REPLY",
"index": 0,
"parameters": [
{
"type": "PAYLOAD",
"payload": "your-payload-here"
}
]
}
]
}
]
}
]
}
}
}
]
}
}
]
}
}
Template message (Limited-time offer and Coupon code)
Limited-time offer templates let you show expiration dates and countdown timers for offer codes in your messages. It makes it easy for you to let end-users know about time-limited deals and keep them engaged. Coupon code templates are marketing templates that display a single copy code button that can be combined with a URL button. When tapped, the code is copied to the end-users clipboard. They can also contain an image as header.

Limited-time offer template message
Limited-time offer object:
Field | Description | Required |
---|---|---|
expiration_time_ms | Offer code expiration time as a UNIX timestamp in milliseconds. | Yes |
Coupon code:
Field | Description | Required |
---|---|---|
coupon_code | Offer code as text. Maximum 15 characters. | Yes |
In the example below, we send a Limited-time offer template message:
{
"messages": {
"msg": [
{
"from": "00316098765432",
"to": [
{
"number": "00316012345678"
}
],
"body": {
"type": "auto",
"content": "fallback message"
},
"allowedChannels": [
"WhatsApp"
],
"richContent": {
"conversation": [
{
"template": {
"whatsapp": {
"namespace": "your-namespace",
"element_name": "your-template-name",
"language": {
"policy": "deterministic",
"code": "en_US"
},
"components": [
{
"parameters": [],
"type": "body"
},
{
"type": "limited_time_offer",
"parameters": [
{
"type": "limited_time_offer",
"limited_time_offer": {
"expiration_time_ms": 1708184832000
}
}
]
},
{
"type": "button",
"sub_type": "copy_code",
"index": 0,
"parameters": [
{
"type": "coupon_code",
"coupon_code": "1234ab"
}
]
}
]
}
}
}
]
}
}
]
}
}
Coupon code templates are marketing templates that display a copy code button (without expiration date). When tapped, the code is copied to the customer's clipboard. They can also contain an image as header.

Coupon code template message
Coupon code:
Field | Description | Required |
---|---|---|
coupon_code | Offer code as text. Maximum 15 characters. | Yes |
In the example below, we send a Coupon template message:
{
"messages": {
"msg": [
{
"from": "00316098765432",
"to": [
{
"number": "00316012345678"
}
],
"body": {
"type": "auto",
"content": "fallback message"
},
"allowedChannels": [
"WhatsApp"
],
"richContent": {
"conversation": [
{
"template": {
"whatsapp": {
"namespace": "your-namespace",
"element_name": "your-template-name",
"language": {
"policy": "deterministic",
"code": "en_US"
},
"components": [
{
"parameters": [],
"type": "body"
},
{
"type": "button",
"sub_type": "copy_code",
"index": 0,
"parameters": [
{
"type": "coupon_code",
"coupon_code": "1234ab"
}
]
}
]
}
}
}
]
}
}
]
}
}
Important for LTO and Coupon templates
- Only templates categorized as MARKETING are supported.
- Only one copy coupon button per template.
- Footer components are not supported.
- End-users who view a limited-time offer template message using that WhatsApp web app or desktop app will not see the offer, but will instead see a message indicating that they have received a message but that it's not supported in the client they are using.
Language
Field | Description | Required |
---|---|---|
policy | deterministic — Deliver the message template in exactly the language and locale asked for. | Yes |
code | The code of the language or locale to use — Accepts both language and language_locale formats (e.g., en and en_US). | Yes |
WhatsApp maintains a list of valid language codes
Time-To-Live (TTL) for WhatsApp Message Templates
The Time-To-Live (TTL), or validity period, defines how long the system will attempt to deliver a WhatsApp message if the recipient is temporarily unavailable. This parameter is configurable per template type: Authentication, Utility, and Marketing.
WhatsApp supports a longer Time-To-Live than CM.com does. Messages will be marked as expired after 24h even if the TTL is set to a longer time. WhatsApp will continue to try to deliver the messages until the set TTL is hit, even after we expire the message.
Default TTL Values
Template Type | Default TTL |
---|---|
Authentication | 10 minutes |
Utility | 30 days |
Marketing | 30 days |
Custom TTL Ranges
Template Type | Customizable Range |
---|---|
Authentication | 30–900 seconds (30 secs–15 mins) |
Utility | 30–43,200 seconds (30 secs–12 hours) |
Marketing | 43,200–2,592,000 seconds (12 hrs–30 d) |
Templates created before 23 October 2024
Authentication templates created before 23 October 2024 default to 30 days unless explicitly updated.
TTL Expiry and Dropped Messages
Messages not delivered within the configured TTL will no longer end up on the end user's phone.
If you do not receive a delivered message webhook before the TTL expires, assume the message was dropped.
There may be a short delay between TTL expiry and the corresponding webhook. Consider implementing a buffer period before acting on undelivered messages.
Recommendation
We recommend setting the TTL of your authentication templates equal to or less than your code expiration time to avoid delivering expired codes to users.
Updated 20 days ago