We are making changes to the WhatsApp Business Platform pricing model.

Effective July 1, 2025 for all businesses on our platform:

See Pricing Updates on the WhatsApp Business Platform for additional details.

Template Components

Templates are made up of four primary components which you define when you create a template: header, body, footer, and buttons. The components you choose for each of your templates should be based on your business needs. The only required component is the body component.

Some components support variables, whose values you can supply when using the Cloud API or On-Premises API to send the template in a template message. If your templates use variables, you must include sample variable values upon template creation.

Headers

Headers are optional components that appear at the top of template messages. Headers support text, media (images, videos, documents), and locations.

All templates are limited to one header component

Text Headers

You can choose to add header text to your message template. The message text in the header component accepts parameters for programmatic configuration.

Text parameters can be configured in one of two formats:

  • Positional — Pass in an array of parameters that correspond to numeric positions in the body text with examples
    • For example: “Hello John, your account balance is {{1}}” | [ “$1,000” ]
  • Named — Pass in JSON objects that contain a parameter name and examples
    • For example: { "param_name": "account_balance", "example": "$1,000" }

Component Syntax

Add this header component object into the ”components”[] object array when calling the POST <WHATSAPP_BUSINESS_ACCOUNT_ID>/message_templates endpoint. Substitute the placeholder properties below using the properties table.

Learn more about sending text-based templates here

{
  "type": "HEADER",
  "format": "TEXT",
  "text": "<HEADER_TEXT>",

  "example": {
    "header_text": [
       // You must provide one of the inputs below when the <HEADER_TEXT> string contains parameters
       <POSITIONAL_PARAM_EXAMPLES>
       <BODY_TEXT_NAMED_PARAMS>
    ]
  }
}

Properties


PlaceholderDescriptionExample Value

<HEADER_TEXT>

String | Required

Plain text string. Can support 1 parameter.

If this string contains parameters, you must include the example property and example parameter values as shown in <POSITIONAL_PARAM_EXAMPLES> and <HEADER_TEXT_NAMED_PARAMS> below.

60 character maximum.

“Our Holiday sale starts December 1st!”

“Our new sale starts {{1}}”

“Our new sale starts {{sale_start_date}}!”

<POSITIONAL_PARAM_EXAMPLES>

[String] | Optional

Required when using positional parameters in your header text.

Array of String in which each string is meant to illustrate the text likely to be passed in as a parameter during message send time, for example a bank account balance, or a customer name.

The number of strings must match the number of variables included in the string.

["December 1st"]

<HEADER_TEXT_NAMED_PARAMS>

[JSON Object] | Optional

Required when using named variables in your header text.

Array of JSON objects that contain param_name and example strings.

  • “param_name” — Your custom parameter name. Must be lowercase letters and underscores only.
  • “example” — The illustrative sample text for the parameter.
[{
 "param_name": "sale_start_date",
 "example": "December 1st"
}]
          

Positional Parameter Example

{
  "type": "HEADER",
  "format": "TEXT",
  "text": "Our new sale starts {{1}}!",
  "example": {
    "header_text": [
      "December 1st"
    ]
  }
}

Named Parameter Example

{
  "type": "HEADER",
  "format": "TEXT",
  "text": "Our new sale starts {{sale_start_date}}!",
  "example": {
    "header_text_named_params": [
      {
        "param_name": "sale_start_date",
        "example": "December 1st"
      }
    ]
  }
}

Media Headers

Media headers can be an image, video, or a document such as a PDF. All media must be uploaded with the Resumable Upload API. The syntax for defining a media header is the same for all media types.

Syntax

{
  "type": "HEADER",
  "format": "<FORMAT>",
  "example": {
    "header_handle": [
      "<HEADER_HANDLE>"
    ]
  }
}

Properties


PlaceholderDescriptionExample Value

<FORMAT>

Indicates media asset type. Set to IMAGE, VIDEO, or DOCUMENT.

IMAGE

<HEADER_HANDLE>

Uploaded media asset handle. Use the Resumable Upload API to generate an asset handle.

4::aW...

Example

{
  "type": "HEADER",
  "format": "IMAGE",
  "example": {
    "header_handle": [
      "4::aW..."
    ]
  }
}

Location Headers

Location headers appear as generic maps at the top of the template and are useful for order tracking, delivery updates, ride hailing pickup/dropoff, locating physical stores, etc. When tapped, the app user's default map app will open and load the specified location. Locations are specified when you send the template using the Cloud API or On-Premises API.

Location headers can only be used in templates categorized as UTILITY or MARKETING. Real-time locations are not supported.

Syntax

{
  "type": "HEADER",
  "format": "LOCATION"
}

Properties

Property values cannot be customized.

Example

{
  "type": "HEADER",
  "format": "LOCATION"
}

Body

The body component represents the core text of your message template and is a text-only template component. It is required for all templates.

The message text in the body component accepts parameters for programmatic configuration.

Text parameters can be configured in one of two formats:

  • Positional — Pass in an array of numbered positional parameters that correspond to numeric positions in the body text with examples
    • For example: “Hello {{1}}, your account balance is {{2}}” | [ “John”, “$1,000” ]
  • Named — Pass in JSON objects that contain a parameter name and examples
    • For example: { "param_name": "order_id", "example": "335628"}

All templates are limited to one body component.

Component Syntax

Add this body component object into the ”components”[] object array when calling the POST <WHATSAPP_BUSINESS_ACCOUNT_ID>/message_templates endpoint. Substitute the placeholder properties below using the properties table.

Learn more about sending text-based templates here

{
  "type": "body",
  "text": "<BODY_TEXT>",
  "example": {
    "body_text": [
      [
       // You must provide one of the inputs below when the <BODY_TEXT> string contains parameters
       <POSITIONAL_PARAM_EXAMPLES>
       <BODY_TEXT_NAMED_PARAMS>
      ]
    ]
  }
}

Properties

PlaceholderDescriptionExample Value

<HEADER_TEXT>

String | Required

Plain text string. Can support multiple parameters.

If this string contains parameters, you must include the example property and example parameter values as shown in <POSITIONAL_PARAM_EXAMPLES> and <BODY_TEXT_NAMED_PARAMS> below.

1024 character maximum.

“Shop our Holiday sale now!”

“Shop now through {{1}} and use code {{2}} to get {{3}} off of all merchandise.”

“Your {{order_id}}, is ready {{customer_name}}”

<POSITIONAL_PARAM_EXAMPLES>

[String] | Optional

Required when using positional parameters in your body text.

Array of string in which each string is meant to illustrate the text likely to be passed in as a parameter during message send time, for example a bank account balance, or a customer name.

The number of strings must match the number of variables included in the string.

["the end of August","25OFF","25%"]

<BODY_TEXT_NAMED_PARAMS>

[JSON Object] | Optional

Required when using named variables in your body text.

Array of JSON objects that contain param_name and example strings.

  • “param_name” — Your custom parameter name. Must be lowercase letters and underscores only.
  • “example” — The illustrative sample text for the parameter.
[{
 "param_name": "order_id",
 "example": "335628"
},
{
 "param_name": "customer_name",
 "example": "Shiva"
}]
          

Positional Parameter Example

{
  "type": "BODY",
  "text": "Shop now through {{1}} and use code {{2}} to get {{3}} off of all merchandise.",
  "example": {
    "header_text": [
      "the end of August","25OFF","25%"
    ]
  }
}

Named Parameter Example

{
  "type": "BODY",
  "text": "Your {{order_id}}, is ready {{customer_name}}.",
  "example": {
    "header_text_named_params": [
      {
        "param_name": "order_id",
        "example": "335628"
      },
      {
        "param_name": "customer_name",
        "example": "Shiva"
      }
    ]
  }
}

Footer

Footers are optional text-only components that appear immediately after the body component. Templates are limited to one footer component.

Syntax

{
  "type": "FOOTER",
  "text": "<TEXT>"
}

Properties


PlaceholderDescriptionExample Value

<TEXT>

Text to appear in template footer when sent.


60 characters maximum.

Use the buttons below to manage your marketing subscriptions

Example

{
  "type": "FOOTER",
  "text": "Use the buttons below to manage your marketing subscriptions"
}

Buttons

Buttons are optional interactive components that perform specific actions when tapped. Templates can have a mixture of up to 10 button components total, although there are limits to individual buttons of the same type as well as combination limits. These limits are described below.

Buttons are defined within a single buttons component object, packed into a single buttons array. For example, this template uses a phone number button and a URL button:

{
  "type": "BUTTONS",
  "buttons": [
    {
      "type": "PHONE_NUMBER",
      "text": "Call",
      "phone_number": "15550051310"
    },
    {
      "type": "URL",
      "text": "Shop Now",
      "url": "https://www.luckyshrub.com/shop/"
    }
  ]
}

If a template has more than three buttons, two buttons will appear in the delivered message and the remaining buttons will be replaced with a See all options button. Tapping the See all options button reveals the remaining buttons.

Copy Code Buttons

Copy code buttons copy a text string (defined when the template is sent in a template message) to the device's clipboard when tapped by the app user. Templates are limited to one copy code button.

Syntax

{
  "type": "COPY_CODE",
  "example": "<EXAMPLE>"
}

Properties


PlaceholderDescriptionExample Value

<EXAMPLE>

String to be copied to device's clipboard when tapped by the app user.


Maximum 15 characters.

250FF

Example

{
  "type": "COPY_CODE",
  "example": "250FF"
}

Flows Buttons

Flows buttons are for sending Flows Messages as templates.

Flows can quickly be built in the playground and attached as JSON, or an existing Flow ID can be specified.

Syntax

{
  "type": "FLOW",
  "text": "<TEXT>",
  "flow_id": "<FLOW_ID>",
  "flow_name": "<FLOW_NAME>",
  "flow_json": "<FLOW_JSON>", 
  "flow_action": "<FLOW_ACTION>",
  "navigate_screen": "<NAVIGATE_SCREEN>",
  "icon": "<ICON>"
}

Properties


PlaceholderDescriptionExample Value

<TEXT>

Button label text.


25 characters maximum.

Sign up

<FLOW_ID>

Unique identifier of the Flow provided by WhatsApp. The Flow must be published.

Cannot be used if the FLOW_JSON or FLOW_NAME attributes are provided. Only one of the parameters is allowed.

123456789012345

<FLOW_NAME>

The name of the Flow. Supported in Cloud API only. The Flow ID is stored in the message template, not the name, so changing the Flow name will not affect existing message templates. The Flow must be published.

Cannot be used if the FLOW_JSON or FLOW_ID attributes are provided. Only one of the parameters is allowed.

Survey_Flow

<FLOW_JSON>

The Flow JSON encoded as string specifying the layout of the flow to be attached to the Template. The Flow JSON can be quickly generated in the Flow playground. For full reference see Flow JSON documentation

Cannot be used if the FLOW_ID or FLOW_NAME attributes are provided. Only one of the parameters is allowed.

"{\"version\": \"3.1\", \"screens\": [...]}"

<FLOW_ACTION>

navigate or data_exchange. Use navigate to predefine the first screen as part of the template message. Use data_exchange for advanced use-cases where the first screen is provided by your endpoint.


Optional. Default: navigate

navigate

<NAVIGATE_SCREEN>

Optional only if flow_action is navigate. The id of the entry screen of the Flow.


Optional. Default: FIRST_ENTRY_SCREEN

flow_json_first_screen

<ICON>

Optional. A default icon will be displayed next to the button if not provided. Allowed values are: DOCUMENT, PROMOTION, REVIEW.

PROMOTION

Example

{
  "type": "FLOW",
  "text": "Sign up",
  "icon": "PROMOTION",
  "flow_json" : {
    "version": "6.0",
    "screens": [
        {
            "id": "WELCOME_SCREEN",
            "layout": {
                "type": "SingleColumnLayout",
                "children": [
                    {
                        "type": "TextHeading",
                        "text": "Hello World"
                    },
                    {
                        "type": "TextBody",
                        "text": "Let's start building things!"
                    },
                    {
                        "type": "Footer",
                        "label": "Complete",
                        "on-click-action": {
                            "name": "complete",
                            "payload": {}
                        }
                    }
                ]
            },
            "title": "Welcome",
            "terminal": true,
            "success": true,
            "data": {}
        }
    ]
  }
}

MPM Buttons

Multi-product message (MPM) buttons are special, non-customizable buttons that, when tapped, display up to 30 products from your ecommerce catalog, organized in up to 10 sections, in a single message. See Multi-Product Message Templates.

OTP Buttons

One-time password (OTP) buttons are a special type of URL button component used with authentication templates. See Authentication Templates.

Phone Number Buttons

Phone number buttons call the specified business phone number when tapped by the app user. Templates are limited to one phone number button.

Syntax

{
  "type": "PHONE_NUMBER",
  "text": "<TEXT>",
  "phone_number": "<PHONE_NUMBER>"
}

Properties


PlaceholderDescriptionExample Value

<PHONE_NUMBER>

Alphanumeric string. Business phone number to be called when the user taps the button.

Note that some countries have special phone numbers that have leading zeros after the country calling code (e.g., +55-0-955-585-95436). If you assign one of these numbers to the button, the leading zero will be stripped from the number. If your number will not work without the leading zero, assign an alternate number to the button, or add the number as message body text.

20 characters maximum.

15550051310

<TEXT>

Button label text.


25 characters maximum.

Call

Example

{
  "type": "PHONE_NUMBER",
  "text": "Call",
  "phone_number": "15550051310"
}

Quick Reply Buttons

Quick reply buttons are custom text-only buttons that immediately message you with the specified text string when tapped by the app user. A common use case-case is a button that allows your customer to easily opt-out of any marketing messages.

Templates are limited to 10 quick reply buttons. If using quick reply buttons with other buttons, buttons must be organized into two groups: quick reply buttons and non-quick reply buttons. If grouped incorrectly, the API will return an error indicating an invalid combination.

Examples of valid groupings:

  • Quick Reply, Quick Reply
  • Quick Reply, Quick Reply, URL, Phone
  • URL, Phone, Quick Reply, Quick Reply

Examples of invalid groupings:

  • Quick Reply, URL, Quick Reply
  • URL, Quick Reply, URL

When using the Cloud API or On-Premises API to send a template that has multiple quick reply buttons, you can use the index property to designate the order in which buttons appear in the template message.

Syntax

{
  "type": "QUICK_REPLY",
  "text": "<TEXT>"
}

Properties


PlaceholderDescriptionExample Value

<TEXT>

Button label text.


25 characters maximum.

Unsubscribe

Example

{
  "type": "QUICK_REPLY",
  "text": "Unsubscribe from Promos"
}

SPM Buttons

Single-product message (SPM) buttons are special, non-customizable buttons that can be mapped to a product in your product catalog. When tapped, they load details about the product, which it pulls from your catalog. Users can then add the product to their cart and place an order. See Single-Product Message Templates and Product Card Carousel Templates.

URL Buttons

URL buttons load the specified URL in the device's default web browser when tapped by the app user. Templates are limited to two URL buttons.

Syntax

{
  "type": "URL",
  "text": "<TEXT>",
  "url": "<URL>",

  # Required if <URL> contains a variable
  "example": [
    "<EXAMPLE>"
  ]
}

Properties


PlaceholderDescriptionExample Value

<EXAMPLE>

URL of website. Supports 1 variable.


If using a variable, add sample variable property to the end of the URL string. The URL loads in the device's default mobile web browser when the customer taps the button.


2000 characters maximum.

https://www.luckyshrub.com/shop?promo=summer2023

<TEXT>

Button label text. 25 characters maximum.

Shop Now

<URL>

URL of website that loads in the device's default mobile web browser when the button is tapped by the app user.


Supports 1 variable, appended to the end of the URL string.


2000 characters maximum.

https://www.luckyshrub.com/shop?promo={{1}}

Example

{
  "type": "URL",
  "text": "Shop Now",
  "url": "https://www.luckyshrub.com/shop?promo={{1}}",
  "example": [
    "summer2023"
  ]
}

Limited-Time Offer

Limited-Time Offer components are special components used to create limited-time offer templates.

Example Requests

Seasonal Promotion

An example request to create a marketing template with the following components:

  • a text header with a variable and sample value
  • a text body with variables and sample values
  • a text footer
  • two quick-reply buttons
curl -L 'https://graph.facebook.com/v22.0/102290129340398/message_templates' \
-H 'Authorization: Bearer EAAJB...' \
-H 'Content-Type: application/json' \
-d '
{
  "name": "seasonal_promotion",
  "language": "en_US",
  "category": "MARKETING",
  "components": [
    {
      "type": "HEADER",
      "format": "TEXT",
      "text": "Our {{1}} is on!",
      "example": {
        "header_text": [
          "Summer Sale"
        ]
      }
    },
    {
      "type": "BODY",
      "text": "Shop now through {{1}} and use code {{2}} to get {{3}} off of all merchandise.",
      "example": {
        "body_text": [
          [
            "the end of August","25OFF","25%"
          ]
        ]
      }
    },
    {
      "type": "FOOTER",
      "text": "Use the buttons below to manage your marketing subscriptions"
    },
    {
      "type":"BUTTONS",
      "buttons": [
        {
          "type": "QUICK_REPLY",
          "text": "Unsubscribe from Promos"
        },
        {
          "type":"QUICK_REPLY",
          "text": "Unsubscribe from All"
        }
      ]
    }
  ]
}'

Order Confirmation

An example request to create a utility template with the following components:

  • a document header with a sample value
  • a text body with variables and sample values
  • a phone number button
  • a URL button
curl -L 'https://graph.facebook.com/v16.0/102290129340398/message_templates' \
-H 'Authorization: Bearer EAAJB...' \
-H 'Content-Type: application/json' \
-d '
{
  "name": "order_confirmation",
  "language": "en_US",
  "category": "UTILITY",
  "components": [
    {
      "type": "HEADER",
      "format": "DOCUMENT",
      "example": {
        "header_handle": [
          "4::YX..."
        ]
      }
    },
    {
      "type": "BODY",
      "text": "Thank you for your order, {{1}}! Your order number is {{2}}. Tap the PDF linked above to view your receipt. If you have any questions, please use the buttons below to contact support. Thank you for being a customer!",
      "example": {
        "body_text": [
          [
            "Pablo","860198-230332"
          ]
        ]
      }
    },
    {
      "type": "BUTTONS",
      "buttons": [
        {
          "type": "PHONE_NUMBER",
          "text": "Call",
          "phone_number": "15550051310"
        },
        {
          "type": "URL",
          "text": "Contact Support",
          "url": "https://www.luckyshrub.com/support"
        }
      ]
    }
  ]
}'

Order Delivery Update

An example request to create a utility template with the following components:

  • a location header
  • a text body with variables and sample values
  • a footer
  • a quick reply button
curl 'https://graph.facebook.com/v22.0/102290129340398/message_templates' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer EAAJB...' \
-d '
{
  "name": "order_delivery_update",
  "language": "en_US",
  "category": "UTILITY",
  "components": [
    {
      "type": "HEADER",
      "format": "LOCATION"
    },
    {
      "type": "BODY",
      "text": "Good news {{1}}! Your order #{{2}} is on its way to the location above. Thank you for your order!",
      "example": {
        "body_text": [
          [
            "Mark",
            "566701"
          ]
        ]
      }
    },
    {
      "type": "FOOTER",
      "text": "To stop receiving delivery updates, tap the button below."
    },
    {
      "type":"BUTTONS",
      "buttons": [
        {
          "type": "QUICK_REPLY",
          "text": "Stop Delivery Updates"
        }
      ]
    }
  ]
}'

Component Update Webhook

Subscribe to the message_template_components_update webhook field to receive notification of changes to a template's components, like a change in title or body, or an addition of a button.

Webhook Response Shape

"message_template_id": <id>,
"message_template_name": <string>,
"message_template_language": <string>,
"message_template_title": <string>,
"message_template_element": <string>,
"message_template_footer": <string>,
"message_template_buttons": [
  {
    "message_template_button_type": <string>,
    "message_template_button_text": <string>,
    "message_template_button_url": <string>,
    "message_template_button_phone_number": <string>
  }
]

Example Webhook Response

"message_template_id": 1234567890,
"message_template_name": “promo_summer_sale_11_en”,
"message_template_language": “en_US”,
"message_template_title": “header”,
"message_template_element": “body”,
"message_template_footer": “footer”,
"message_template_buttons": [
  {
    "message_template_button_type": URL,
    "message_template_button_text": “click me”,
    "message_template_button_url": “https://www.example.com”,
    "message_template_button_phone_number": “+1(123)4565678”
  }
]

Webhook Response Fields

FieldDescription

message_template_id

id

The template ID.

message_template_name

String

The template name.

message_template_language

String

The template language

message_template_title

String

The new template header after the change.

Remains empty if the user did not enter a header.

message_template_element

String

The new template body after the change.

Remains empty if the user did not enter new body text.

message_template_footer

String

The new template footer after the change.

Remains empty if the user did not enter new footer text.

message_template_buttons

Array [Button]

The new list of buttons on the template after the change.

Only URL type and Phone number type buttons are supported for this webhook.