Skip to main content

Template messages

WhatsApp only allows businesses to message users outside the customer service window with pre-approved templates. This page explains how to send a template, how to fill in its variables, and the options for each template type.

Template typeCategoryUse it to…
Text and media templatesAnySend text with an optional image, video, document or GIF header.
Interactive templatesUtility, MarketingAdd quick-reply and URL buttons.
Authentication templatesAuthenticationSend one-time passwords and verification codes.
Location templatesUtility, MarketingShare a location as a map pin.
Flows templatesUtility, MarketingOpen a WhatsApp Flow.
Carousel templatesMarketingShow up to 10 scrollable media cards.
Limited-time offer templatesMarketingShow an offer code with an expiry countdown.
Coupon code templatesMarketingShow an offer code the user can copy.
Call permission request templatesMarketingAsk for permission to call the user.

Order details templates for payments are described in Payments – India and Payments – Brazil.


Before you begin​

Create and approve the template​

Templates must be created and approved before you can send them. Request templates through the Channels portal. Once a template is approved, open its Details in the template overview to find the template name, which you use as element_name.

Obtain opt-in​

Users must have actively opted in to the type of messages you send. An active opt-in is triggered by a deliberate user action, such as entering their phone number in a WhatsApp field or ticking a consent box.

When you collect opt-ins, you must:

  • State clearly that the user is opting in to receive WhatsApp messages from your business.
  • Name your business explicitly.
  • Make clear which types of message the user will receive, for example order updates or promotions.
  • Offer a straightforward way to opt out, and honour opt-out requests.
  • Comply with all applicable local laws and regulations.

Accepted opt-in channels include SMS, your website, a WhatsApp conversation, an IVR flow and in-person or paper sign-up.

Quality rating

Meta monitors the quality of your messages. If users frequently block or report your business, Meta limits your messaging. Monitor your quality rating closely when you introduce new opt-in flows or message types.


Template object​

Add a template item to richContent.conversation. The template.whatsapp object corresponds to the template object in Meta's documentation.

Complete request
{
"messages": {
"authentication": {
"productToken": "YOUR_PRODUCT_TOKEN"
},
"msg": [
{
"from": "00316098765432",
"to": [
{ "number": "00316012345678" }
],
"body": {
"type": "auto",
"content": "Fallback text"
},
"allowedChannels": ["WhatsApp"],
"richContent": {
"conversation": [
{
"template": {
"whatsapp": {
"element_name": "order_confirmation",
"language": {
"policy": "deterministic",
"code": "en"
},
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "John" },
{ "type": "text", "text": "ORD-12345" }
]
}
]
}
}
}
]
}
}
]
}
}

The other examples on this page show only the template item.

FieldRequiredDescription
element_nameYesName of the approved template.
languageYesLanguage of the template. See Language.
componentsYesValues for the template's variables, grouped by component. The number of parameters must exactly match the number of variables in the template. Use an empty array if the template has no variables.

Language​

A template can exist in several languages. Specify which one to send.

FieldRequiredDescription
policyYesAlways deterministic: the template is delivered in exactly the language and locale you specify.
codeYesLanguage or locale code, for example en or en_US. See Meta's supported languages.

Components​

ComponentDescription
headerOptional. text, media (image, video, document or gif) or location.
bodyRequired. The main message text. Supports variables.
footerOptional. Static text below the body. Not supported in limited-time offer and coupon code templates.
buttonOptional. Sub-types quick_reply, url, copy_code and flow. Identify each button by its zero-based index.
limited_time_offerLimited-time offer templates only. Sets the offer expiry.
carouselCarousel templates only. Contains the cards.

Parameter types​

Use these types in components[].parameters[]:

TypeUsed inDescription
textHeader, body, buttonsPlain text value. Cannot be empty.
currencyBodyLocalised amount. Requires fallback_value, code (ISO 4217) and amount_1000 (the amount multiplied by 1,000).
date_timeBodyLocalised date and time. Requires fallback_value. Accepts either day_of_week, year, month, day_of_month, hour, minute and calendar (GREGORIAN or SOLAR_HIJRI) or a UNIX timestamp.
image, video, documentHeaderMedia header. Contains a media object (mediaName, mediaUri, mimeType).
locationHeaderLocation header. See Location templates.
payloadquick_reply buttonValue returned in the MO webhook when the user taps the button. Max. 128 characters.
coupon_codecopy_code buttonOffer code. Max. 20 characters.
actionflow buttonContains flow_token and optional flow_action_data.
Text parameter rules

text parameters cannot be empty, and cannot contain newlines (\n), tabs (\t), carriage returns (\r) or more than four consecutive spaces. Requests that break these rules are rejected.

Categories​

Every template is assigned a category when it is created. The category affects delivery rules, pricing and opt-in requirements.

CategoryTypical use
AUTHENTICATIONVerifying a user's identity: one-time passwords, verification codes and login confirmations.
UTILITYFollowing up on a user action or request: order confirmations, delivery updates and account alerts.
MARKETINGPromotions, offers, product announcements and re-engagement.

Templates in the wrong category can be rejected or removed. See Meta's categorisation guidelines.


Text and media templates​

The basic template contains a body with variables, and optionally a header and footer. The header can contain text or media: image, video, document or gif.

GIF headers

GIF headers are supported only in the Marketing Messages API. The GIF must be an MP4 file of max. 3.5 MB, larger files are shown as a video.

Body variables
{
"template": {
"whatsapp": {
"element_name": "TEMPLATE_NAME",
"language": { "policy": "deterministic", "code": "en" },
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "John" },
{
"type": "currency",
"currency": {
"fallback_value": "€100.99",
"code": "EUR",
"amount_1000": 100990
}
},
{
"type": "date_time",
"date_time": {
"fallback_value": "25 February 1977",
"day_of_week": 5,
"day_of_month": 25,
"year": 1977,
"month": 2,
"hour": 15,
"minute": 33
}
},
{
"type": "date_time",
"date_time": {
"fallback_value": "27 January 2017",
"timestamp": 1485470276
}
}
]
}
]
}
}
}
Image header
{
"template": {
"whatsapp": {
"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": [
{ "type": "text", "text": "replace-value-1" }
]
}
]
}
}
}
Document header
{
"template": {
"whatsapp": {
"element_name": "TEMPLATE_NAME",
"language": { "policy": "deterministic", "code": "en" },
"components": [
{
"type": "header",
"parameters": [
{
"type": "document",
"media": {
"mediaName": "terms-and-conditions.pdf",
"mediaUri": "https://www.example.com/documents/terms-and-conditions.pdf",
"mimeType": "application/pdf"
}
}
]
},
{
"type": "body",
"parameters": [
{ "type": "text", "text": "replace-value-1" }
]
}
]
}
}
}

Interactive templates​

Interactive templates add button components to a text or media template. The button labels, the URL or call-to-action buttons (CTA) are defined when you create the template. When sending, you only provide the variable parts.

Button sub-typeWhat you provide
quick_replyA payload (max. 128 characters). It is returned when the user taps the button. See Interactive template replies.
urlFor a dynamic URL, a text parameter with the URL suffix. Static URLs and phone number buttons need no parameters.
Interactive template
{
"template": {
"whatsapp": {
"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", "payload": "confirm-appointment-9rwn" }
]
},
{
"type": "button",
"sub_type": "url",
"index": "1",
"parameters": [
{ "type": "text", "text": "9rwn" }
]
},
{
"type": "button",
"sub_type": "url",
"index": "2",
"parameters": [
{ "type": "text", "text": "ticket.pdf" }
]
}
]
}
}
}

Authentication templates​

Authentication templates deliver one-time passwords and verification codes. Pass the code as the body parameter. Gor templates with a button, pass the code as the button parameter as well.

Phone numbers only

Authentication templates cannot be sent to Business-scoped User IDs. Use the user's phone number.

Button typeBehaviour
Copy codeThe user taps the button, the code is copied to their clipboard, and they paste it into your app.
One-tap autofillThe user taps the button and WhatsApp passes the code to your Android app. Requires changes to your app. On iOS 26 and later, the keyboard suggests the code without any integration.
Zero-tapWhatsApp passes the code to your Android app via a broadcast receiver, without the user leaving your app.

Example of copy code authentication template

Copy code
{
"template": {
"whatsapp": {
"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" }
]
}
]
}
}
}
One-tap autofill
{
"template": {
"whatsapp": {
"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" }
]
}
]
}
}
}
Zero-tap
{
"template": {
"whatsapp": {
"element_name": "your-template-name",
"language": { "policy": "deterministic", "code": "en" },
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "123456" }
]
}
]
}
}
}
Linked devices

Authentication messages are only shown on the user's primary WhatsApp device. On linked devices such as WhatsApp Web or desktop, the message is masked and the user is asked to view it on their primary device. This is enabled by default and requires no configuration.

Set a time-to-live equal to or shorter than your code's validity, so users do not receive expired codes.


Location templates​

A location template shares a location, such as a store, venue or pickup point, as a map pin in the header.

Location templates are available in the Marketing and Utility categories. Choose the category that matches the context: a store address in a promotion is Marketing, a drop-off point for an order the user placed is Utility.

FieldRequiredDescription
latitudeYesLatitude in decimal degrees.
longitudeYesLongitude in decimal degrees.
nameNoName of the location, for example a store.
addressNoAddress of the location.
Location template
{
"template": {
"whatsapp": {
"element_name": "your-template-name",
"language": { "policy": "deterministic", "code": "en" },
"components": [
{
"type": "header",
"parameters": [
{
"type": "location",
"location": {
"latitude": "51.603802",
"longitude": "4.770821",
"name": "CM.com HQ",
"address": "Konijnenberg 30, 4825 BD Breda"
}
}
]
},
{
"type": "body",
"parameters": [
{ "type": "text", "text": "your-text-string" }
]
}
]
}
}
}

Flows templates​

A Flows template contains a button that opens a WhatsApp Flow. The data the user submits is delivered to your MO webhook as a Flows reply.

Example of Flows template message

FieldRequiredDescription
action.flow_tokenNoYour own token. It is returned in the Flows reply so you can correlate the response.
action.flow_action_dataNoInitial data passed to the first screen of the Flow.
Flows template
{
"template": {
"whatsapp": {
"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": {}
}
}
]
}
]
}
}
}

A carousel template is a Marketing template with up to 10 media cards in a horizontally scrollable format. Each card has its own image or video header, body and buttons.

Example of carousel template message

FieldRequiredDescription
cards[].card_indexYesPosition of the card, starting at 0.
cards[].componentsYesThe card's HEADER, BODY and BUTTON components.
HEADER parameter image.mediaUriYesPublic URL of the card image.
BUTTON parameter payloadYes**For quick-reply buttons: the payload returned when tapped.
Carousel template
{
"template": {
"whatsapp": {
"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": "card-0-interested" }
]
}
]
},
{
"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": "card-1-interested" }
]
}
]
}
]
}
]
}
}
}

Limited-time offer templates​

A limited-time offer (LTO) template is a Marketing template that shows an offer code with an expiry date and countdown timer.

Limited-time offer template message

FieldRequiredDescription
limited_time_offer.expiration_time_msYesExpiry of the offer as a UNIX timestamp in milliseconds.
coupon_codeYesOffer code. Max. 20 characters.
Limited-time offer template
{
"template": {
"whatsapp": {
"element_name": "your-template-name",
"language": { "policy": "deterministic", "code": "en_US" },
"components": [
{
"type": "body",
"parameters": []
},
{
"type": "limited_time_offer",
"parameters": [
{
"type": "limited_time_offer",
"limited_time_offer": {
"expiration_time_ms": 1798761600000
}
}
]
},
{
"type": "button",
"sub_type": "copy_code",
"index": 0,
"parameters": [
{ "type": "coupon_code", "coupon_code": "1234ab" }
]
}
]
}
}
}

Coupon code templates​

A coupon code template is a Marketing template with a button that copies an offer code to the user's clipboard. Unlike a limited-time offer, it has no expiry. It can include an image header.

Coupon code template message

FieldRequiredDescription
coupon_codeYesOffer code. Max. 20 characters.
Coupon code template
{
"template": {
"whatsapp": {
"element_name": "your-template-name",
"language": { "policy": "deterministic", "code": "en_US" },
"components": [
{
"type": "body",
"parameters": []
},
{
"type": "button",
"sub_type": "copy_code",
"index": 0,
"parameters": [
{ "type": "coupon_code", "coupon_code": "1234ab" }
]
}
]
}
}
}
Limited-time offer and coupon code restrictions
  • Only Marketing templates are supported.
  • A template can contain only one copy code button, and its label cannot be customised.
  • Footers are not supported.
  • On WhatsApp Web and desktop, users do not see the offer. Instead, they see a message that their client does not support this message type.

Call permission request template​

A call permission request template asks the user for permission to call them, outside the customer service window. It is a Marketing template. Unlike the interactive version, the template must include body text that explains why you want to call. You can also add a header and footer.

The limits for permissions and calls are described under Call permission request message. The user's response is delivered as a call permission reply.

Example of call permission request template

With body variables
{
"template": {
"whatsapp": {
"element_name": "call_permission_request",
"language": { "policy": "deterministic", "code": "en" },
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "John" }
]
}
]
}
}
}
Without body variables
{
"template": {
"whatsapp": {
"element_name": "call_permission_request",
"language": { "policy": "deterministic", "code": "en" },
"components": [
{
"type": "body",
"parameters": []
}
]
}
}
}

Time-to-live (TTL)​

The time-to-live (TTL) or validity period, is how long WhatsApp keeps trying to deliver a template message when the user's device is unreachable. Messages that are not delivered within the TTL are dropped and never reach the user.

CategoryDefault TTLConfigurable range
Authentication10 minutes30 seconds – 15 minutes (30–900 s)
Utility30 days30 seconds – 12 hours (30–43,200 s)
Marketing30 days12 hours – 30 days (43,200–2,592,000 s)
Authentication templates created before 23 October 2024

These templates have a default TTL of 30 days unless you update them.

If you have not received a delivered status report by the time the TTL expires, assume the message was dropped. There may be a short delay between the TTL expiring and the status report, so allow a buffer before acting on undelivered messages. Expired messages are reported with error code 83, see Standard errors.

Recommendation

Set the TTL of authentication templates equal to or shorter than the validity of your codes, so users never receive an expired code.