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.

FieldDescriptionRequired
namespaceThe namespace that will be used. Will be provided to you after the template is approvedYes
element_nameThe element name of the template that will be used. Will be provided to you after the template is approvedYes
languageSpecifies the language, see below for object definitionYes
componentsArray 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_paramsAn 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:

FieldDescriptionRequired
currencyIf the currency object is used, it must contain required parameters currency_code and amount_1000No
date_timeIf the date_time object is used, further definition of the date and time is required. See the example below for two of the optionsNo

The currency object:

FieldDescriptionRequired
fallback_valueDefault text if localization fails. All of the localization parameters must have a fallback value. When specifying text, just the fallback value is requiredYes
codeCurrency code as defined in ISO 4217Yes
amount_1000Amount multiplied by 1000Yes

The date_time object:

FieldDescriptionRequired
fallback_valueDefault text if localization fails. All of the localization parameters must have a fallback value. When specifying text, just the fallback value is requiredYes
day_of_weekIf 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
yearThe yearNo
monthThe monthNo
day_of_monthThe day of monthNo
hourThe hourNo
minuteThe minuteNo
calendarType of calendar. Options: GREGORIAN, SOLAR_HIJRINo

🚧

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 template message

Limited-time offer object:

FieldDescriptionRequired
expiration_time_msOffer code expiration time as a UNIX timestamp in milliseconds.Yes

Coupon code:

FieldDescriptionRequired
coupon_codeOffer 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 template message

Coupon code:

FieldDescriptionRequired
coupon_codeOffer 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

FieldDescriptionRequired
policydeterministic — Deliver the message template in exactly the language and locale asked for.Yes
codeThe 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 TypeDefault TTL
Authentication10 minutes
Utility30 days
Marketing30 days

Custom TTL Ranges

Template TypeCustomizable Range
Authentication30–900 seconds (30 secs–15 mins)
Utility30–43,200 seconds (30 secs–12 hours)
Marketing43,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.