Sending Message Templates

/v1/messages

You can use the messages endpoint to send Message Templates to your customers. Use the WhatsApp Manager to create your Message Templates. For more information, read the Creating Message Templates documentation.

This document covers:

Prerequisites

Request

As with other messages, the message is sent to the /v1/messages endpoint. What's different about sending Message Templates is the content of the message body specified with the hsm parameter.

The hsm parameter contains a namespace and an element_name pair that identify a template and the values to apply to variables in that template.

The following code provides an example of sending a Message Template. This example uses the purchase_with_credit_card element name within the cdb2df51_9816_c754_c5a4_64cdabdcad3e namespace.

POST /v1/messages
  
{
    "to": "whatsapp_id" | "whatsapp_group_id",
    "ttl": "P1D" | "86400" | 86400,
    "type": "hsm",
  
    "hsm": { 
        "namespace": "cdb2df51_9816_c754_c5a4_64cdabdcad3e",
        "element_name": "purchase_with_credit_card", 
        "language": {
            "policy": "deterministic" | "fallback",
            "code": "en_US"
        },
        "localizable_params": [ 
            { "default": "$10" }, 
            { "default": "1234" } 
        ]
    }  
}

The resulting message received by the customer will look like this:

You made a purchase for $10 using a credit card ending in 1234.

As you can see from looking at the localizable parameters and the message the client received, the template used the default value of 10 as the amount of the purchase and the default value of 1234 as the last numbers of the account.

Parameters

Name Required Description

type

Yes (for Message Templates)

The type of message being sent
Default: text
Other options: image, audio, document, hsm

to

Yes

The WhatsApp ID or group ID to whom the message is being sent

ttl

No

As of v2.21.3 — Time To Live (TTL) duration.
Default: 7 days
Other options: The minimum and maximum supported durations are 1 to 30 days (both inclusive).
Accepts both a string in the ISO-8601 duration format as well as just seconds. Durations must be specified in exact multiple of days; any values that are in between will be automatically rounded to the nearest day. See the ttl object section for more information.

recipient_type

No (Optional)

Default: individual
Other options: group
For sending a text message to a group, see the Send a Message to a Group documentation.

hsm

Yes (for Message Templates)

The containing element for the message content — Indicates that the message is highly structured. Parameters contained within provide the structure.

The ttl object

Beginning with v2.21.3, the ttl object provides the ability to set an expiration duration for messages (i.e., Time To Live). Businesses can use this to ensure that messages are delivered in a given time window. Currently, TTLs are only supported for Message Templates.

If the message is not delivered to the customer before the expiration period the message will expire and will not be delivered. You will get a failed callback notification with error code 410 when a sent message expires (such as the example below), but there won't be a delivery receipt because messages that expire will not be delivered.

Example failed callback notification

"statuses": [
    {
        "errors": [
            {
                "code": 410,
                "title": "Message expired"
            }
        ],
        "id": "gBGGFmkiWVVPAgmurVK0Oo_-o60",
        "recipient_id": "16695551234",
        "status": "failed",
        "timestamp": "1538520126"
    }
]

The hsm object

Name Required Description

namespace

Yes

The namespace that will be used

element_name

Yes

The element name that indicates which template to use within the namespace

language

Yes

Allows for the specification of a deterministic or fallback language
See the Language section for more information.

localizable_params

Yes

This field is an array of values to apply to variables in the template
See the Localizable Parameters section for more information.

Language

The language parameter sets the language policy for an Message Template; you can set it to either fallback or deterministic.

Parameters

Name Required Description

policy

Yes

Options: fallback, deterministic
The language policy the message should follow

code

Yes

The code of the language or locale to use — Accepts both language and language_locale formats (e.g., en and en_US).

Language packs

Message Templates are stored in the form of language packs.

A language pack is basically a bundle of Message Template elements for a particular language/locale. If a business contains at least one translation for a language/locale, they are considered to support that, and a pack for that language/locale will be created.

A Message Template namespace is a bundle of language packs for a particular business.

Deterministic versus Fallback

There are two policies that you can specify when sending an Message Template: deterministic and fallback.

  • deterministic — Deliver the Message Template in exactly the language and locale asked for.
  • fallback — Deliver the Message Template in the language that matches user's language/locale setting on device. If one can't be found, deliver using the specified fallback language.

The only real difference is that with fallback, we try to locate the language pack using the device's language/locale setting first.

Deterministic

If a Message Template is sent with the language: policy field set to deterministic, the device will query the server for a language pack of that particular language.

If you send a Message Template like the following:

{ 
  "namespace": "business_a_namespace" 
  "element_name": "hello_world", 
  "language": {
      "policy": "deterministic",
      "code": "en"
  }
  "localizable_params": [ 
      { "default": "1234" }
  ], 
}

When this message is delivered to the device, the device will do the following:

Step 1: "policy": "deterministic" and "code": "en" — Is there a cached en pack on the device?

  • If yes, go to Step 2.
  • If no, is the en pack found on the server?
    • If yes, update local cache and go to Step 2.
    • If no, log the failure, the server returns a structure_unavailable error via a Webhook, and no messages are rendered on the device.

Step 2: "element": "hello_world" — Does the element exist?

  • If yes, unpack the parameters and render the message on the device.
  • If no,
    • if the language pack is from the local cache, download the latest en pack from the server and repeat Step 2.
    • if the language pack was recently downloaded from the server, log the failure, the server returns a structure_unavailable error via a Webhook, and no messages are rendered on the device.

Note: The device language/locale settings are completely ignored.

A problem that can arise when using the deterministic policy is if what you're requesting doesn't exist. Make sure:

  • The namespace is correct,
  • The element name is correct,
  • The language/locale translation exists for that element, and
  • That the number of parameters sent matches what is specified in the Message Template.
Fallback

If a Message Template is sent with the language: policy field is set to fallback, the device will try to be smart and pick the right translation to display depending on the device's language/locale settings.

If you send a Message Template like the following:

{ 
  "namespace": "business_a_namespace" 
  "element_name": "hello_world", 
  "language": {
      "policy": "fallback",
      "code": "en"
  }
  "localizable_params": [ 
      { "default": "1234" }
  ], 
}

When this message is delivered to the device, the device will do the following:

Step 1: "policy": "fallback" and "code": "en" — Load the device's language/locale setting as device_lg-lc. Is there a cached device_lg-lc pack on the device?

  • If yes, go to Step 2.
  • If no, is the device_lg-lc language pack found on the server?
    • If yes, update the local cache, and go to Step 2 with the device_lg-lc language pack.
    • If no, use the fallback lg-lc (in this case, en), and check the cache or query the server for an en pack ("code": "en"). Is it found?
      • If yes, update the local cache, and go to Step 2 with the en pack.
      • If no, log the failure, the server returns a structure_unavailable error via a Webhook, and no messages are rendered on the device.

Step 2: "element": "hello_world" — Does the element exist?

  • If yes, unpack the parameters and render the message on the device.
  • If no,
    • if the language pack is from the local cache, download the latest pack from the server, and repeat Step 2.
    • if the language pack is recently downloaded from the server, log the failure, the server returns a structure_unavailable error via a Webhook, and no messages are rendered on the device.

To avoid issues when using the fallback policy, ensure that for every language you support, a translation is provided for all elements.

Localizable Parameters

When sending a Message Template, the hsm object is required. To define Message Templates, you specify a namespace and an element_name pair that identify a template. Templates have parameters that will be dynamically incorporated into the message. For the example used in this document, the Message Template looks like this:

"You made a purchase for {{1}} using a credit card ending in {{2}}."

For "namespace": "cdb2df51_9816_c754_c5a4_64cdabdcad3e" with "element_name": "purchase_with_credit_card", the first value you list replaces the {{1}} variable in the template message and the second value you list replaces the {{2}} variable.

Note that the number of parameters passed into the payload must match the number of parameters in the hsm object. If not, you will get a callback informing you that there was an issue displaying the Message Template.

Some of these parameters (e.g., date_time or currency) are localizable so that they are displayed appropriately based on the customer's language and locale preferences. If the device is unsuccessful in localizing a parameter, it will fallback to the value that is provided as the "default" value.

The localizable_params options are shown in the table below. For more information on localizable parameters, read the Localization documentation.

Parameters

NameTypeRequiredDescription

default

String

Yes

Default text if localization fails

currency

currency object

No

If the currency object is used, it contains required parameters currency_code and amount_1000.

date_time

date_time object

No

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.

All of the localization parameters must have a default value. The default value is all that is needed when you are specifying text.

However, to specify currency and date in addition to the default, when applicable, use the currency and date_time objects, as shown below. This will allow the client to attempt to localize this data the best way possible and fallback to the default option only if they cannot localize the data. Note that using the currency and date_time` objects for appropriate parameters is highly recommended to enable an optimal localized experience for your customers.

The following is a complete example that demonstrates the use of all of the currently supported localized types:

{
  "to": "19195551112",
  "type": "hsm",
  "recipient_type": "individual",
  
  "hsm": {
    "namespace": "cdb2df51_9816_c754_c5a4_64cdabdcad3e",
    "element_name": "four_lparam_demo",
    "language": {
            "policy": "deterministic",
            "code": "en_US"
        }
  
    "localizable_params": [
      {
        "default": "just a string"
      },
      {
        "default": "$100.99",
        "currency": {
          "currency_code": "USD",
          "amount_1000": 100990
        }
      },
      {
        "default": "February 25, 1977",
        "date_time": {
          "component": {
            "day_of_week": 5,
            "day_of_month": 25,
            "year": 1977,
            "month": 2,
            "hour": 15,
            "minute": 33
          }
        }
      },
      {
        "default": "January 26, 2017",
        "date_time": {
          "unix_epoch": {
            "timestamp": 1485470276
          }
        }
      }
    ]
  
  }
}

Response

A successful response includes a messages object with an id.

{
  "messages": [{
    "id": "gBEGkYiEB1VXAglK1ZEqA1YKPrU"
  }]
}  

An unsuccessful response will contain an error object that will contain an error string, error code and other information. See Error and Status Codes for more information on errors.