logo
enes

Create template

Last update: 5 hours ago by Irais Aguirre

Create WhatsApp message templates.

Integration summary

  • Base URL: https://{{url}}/whatsapp-bsp-admin-ext-endpoint-ws/services
  • Token: admin token, in the Authorization: Bearer {{admin-token}} header (how to generate it)
  • Endpoints on this page:
    • POST /v1/template: Create template

Create template

Request

Create template request:

URLhttps://{{url}}/whatsapp-bsp-admin-ext-endpoint-ws/services/v1/template
MethodPOST
Typeapplication/json

Headers

Create template headers:

NameDescriptionTypeRequirements
Content-Typeapplication/jsonStringRequired
AuthorizationAdmin token. See Generate authentication token.StringRequired

Body

Create template body fields:

NameDescriptionTypeRequirements
wba_idWhatsApp Business Account (WABA) ID. It must be the WABA linked to your token. Digits only.StringRequired
nameTemplate name. Only letters, numbers, and underscores (_) are allowed.StringRequired
languageTemplate language and locale code. Example: es, es_MX, en_US. See the languages supported by Meta.StringRequired
categoryTemplate category:
  • AUTHENTICATION
  • MARKETING
  • UTILITY
StringRequired
allowCategoryChangeIf true, Meta can automatically assign the appropriate category to the template. Default: true. Send this field as allowCategoryChange (camelCase).BooleanOptional
message_send_ttl_secondsTime to live (TTL) in seconds: the maximum time WhatsApp keeps trying to deliver a message sent with this template. Allowed ranges by category:
  • MARKETING: 43200 to 2592000 (12 hours to 30 days).
  • UTILITY: 30 to 43200 (30 seconds to 12 hours).
  • AUTHENTICATION: 30 to 900 (30 seconds to 15 minutes).
Only applied to MARKETING templates from WABAs with MM Lite enabled.
IntegerOptional
degrees_of_freedom_specPass-through object forwarded to Meta to control template flexibility options. Optional; used for advanced template configurations.ObjectOptional
optimization_specPass-through object forwarded to Meta to control template optimization. Optional; used for advanced template configurations.ObjectOptional
structureTemplate structure.Structure objectRequired

Structure object

NameDescriptionTypeRequirements
headerTemplate header.Header objectOptional
bodyTemplate body.Body objectRequired
footerTemplate footer. Not used in AUTHENTICATION templates.StringOptional
footer_code_expiration_minutesCode expiration time, in minutes, shown in the footer. AUTHENTICATION templates only. Minimum 1, maximum 90.IntegerOptional
buttonsButtons the template can include.Array of buttons objectsOptional
limited_time_offerLimited-time offer component. Lets you show expiration dates and countdown timers for offer codes in template messages.Limited_time_offer objectOptional
carouselCarousel component. Lets you send a single text message along with a set of up to 10 cards in a horizontally scrollable view.Carousel objectOptional
call_permission_requestIf true, adds a button to the template so the user can grant call permission. See Create a template with a call permission request. Default: false.BooleanOptional

Header object

NameDescriptionTypeRequirements
formatHeader format. Accepted values:
  • TEXT
  • IMAGE
  • DOCUMENT
  • VIDEO
  • LOCATION
  • GIF
Carousel card headers only accept IMAGE and VIDEO. GIF only applies to MARKETING templates from WABAs with MM Lite enabled; otherwise it's sent as VIDEO.
StringRequired
textHeader text.StringRequired if format is TEXT
exampleSample values for the header variables or sample header media.Header example objectRequired if format is IMAGE, DOCUMENT, VIDEO, or GIF

Header example object

NameDescriptionTypeRequirements
header_handleSample header media (image, video, or document). You can send it in one of two ways:
  • The public URL where the file is hosted. The file is uploaded to Meta when the template is created.
  • The file ID you get from Upload header media.
For carousel templates, we recommend using the ID to reduce the chance of timeout errors while the template is created. For the GIF format, only URLs of MP4 files are accepted.
Array of stringsConditional
header_textSample values for the header text variables.Array of stringsOptional

Body object

NameDescriptionTypeRequirements
textBody text. It can't start or end with a variable. Not used in AUTHENTICATION templates, because Meta defines the text.StringRequired, except in AUTHENTICATION templates
add_security_recommendationIf true, the security recommendation text is added to the body. AUTHENTICATION templates only.BooleanOptional
exampleSample values for the template variables.Body example objectOptional

Body example object

NameDescriptionTypeRequirements
body_textSample variable values. Include one value for each variable in the body text.Array of string arraysOptional

Buttons object

NameDescriptionTypeRequirements
typeButton type. Accepted values:
  • PHONE_NUMBER
  • URL
  • QUICK_REPLY
  • COPY_CODE
  • OTP: one-time password button for AUTHENTICATION templates.
  • FLOW
  • REQUEST_CONTACT_INFO: asks the user to share their phone number.
  • CATALOG: opens the business catalog.
  • SEND_LOCATION: prompts the WhatsApp user to share their location.
  • ORDER_DETAILS: starts an order and payment flow. See Payments Brazil templates.
  • PAYMENT_REQUEST: see Create a payment request template.
StringRequired
textButton text. Not used in COPY_CODE buttons.StringRequired for PHONE_NUMBER, URL, QUICK_REPLY, FLOW, and ORDER_DETAILS.
urlURL the user is redirected to when they tap the button. It must be a valid URL.StringRequired for URL.
phone_numberPhone number dialed when the user taps the button.StringRequired for PHONE_NUMBER.
example
  • For URL buttons: sample dynamic URL.
  • For COPY_CODE buttons: coupon code copied when the user taps the button. Maximum 15 characters.
Array of stringsOptional for URL.
Required for COPY_CODE.
otp_typeOne-time password type. Accepted values:
  • copy_code: copy code.
  • one_tap: one-tap autofill.
  • zero_tap: zero-tap autofill.
StringRequired for OTP.
autofill_textLabel of the one-tap autofill button.StringOptional
package_namePackage name of your Android app. You can use supported_apps instead.StringOptional
signature_hashSigning key hash of your app. You can use supported_apps instead.StringOptional
zero_tap_terms_acceptedSetting this to true confirms you understand that using zero-tap authentication is subject to the WhatsApp Business Terms of Service, and that it's your responsibility to make sure your customers expect the code to be filled in automatically when they choose to receive it through WhatsApp. If set to false, the template isn't created.BooleanRequired if otp_type is zero_tap.
supported_appsPackage name and signing key hash pairs for up to five apps. Useful if you have different builds of your app and want each of them to be able to start the handshake.Array of supported_apps objectsRequired if otp_type is zero_tap.
flow_idUnique Flow ID provided by WhatsApp.StringRequired for FLOW.
flow_action
  • navigate: predefines the first screen as part of the template message.
  • data_exchange: for advanced use cases where your endpoint provides the first screen.
StringRequired for FLOW.
navigate_screenID of the first screen of the Flow.StringRequired for FLOW only if flow_action is navigate.
payment_settingPayment method for the button. See Create a payment request template.ObjectRequired for PAYMENT_REQUEST.

Supported_apps object

NameDescriptionTypeRequirements
package_namePackage name of your Android app. It must have at least two segments separated by periods, and each segment must start with a letter. Only alphanumeric characters and underscores (a-zA-Z0-9_) are allowed. Maximum 224 characters.StringRequired
signature_hashSigning key hash of your app. Only alphanumeric characters, +, /, and = (a-zA-Z0-9+/=) are allowed. It must be exactly 11 characters long. To learn how to get it, see Meta's documentation.StringRequired

Limited_time_offer object

NameDescriptionTypeRequirements
textOffer details text. Maximum 16 characters.StringRequired
has_expirationIf true, the offer's expiration details appear in the sent message. If false, the expiration details don't appear and the "copy code" button component becomes optional.
If you include the copy code button, it must be the first item in the buttons array.
BooleanRequired

Carousel object

The carousel component can be sent under either the carousel key or the carousel_cards key. Both are accepted and map to the same component.

NameDescriptionTypeRequirements
cardsCarousel cards. Maximum 10 cards.Array of cards objectsRequired

Cards object

NameDescriptionTypeRequirements
headerCard header. Only the IMAGE and VIDEO formats are accepted, and all cards must use the same format.Header objectRequired
bodyCard body. Maximum 160 characters.Body objectRequired
buttonsCard buttons. Minimum 1 and maximum 2 buttons of type PHONE_NUMBER, URL, or QUICK_REPLY. All cards must have the same number and type of buttons.Array of buttons objectsRequired

Example

Complete Create template examples. Each body below is a valid -d payload for the request above; send one of them instead of the General body.

General body

curl -X POST "https://{{url}}/whatsapp-bsp-admin-ext-endpoint-ws/services/v1/template" \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer {{admin-token}}' \
-d '{
"wba_id": "1234567899870",
"name": "notificacion_de_pedido",
"language": "es_MX",
"category": "AUTHENTICATION|MARKETING|UTILITY",
"structure":
{
"header":
{
"format": "TEXT|IMAGE|DOCUMENT|VIDEO|LOCATION|GIF",
"text": "ORDER: {{1}}",
"example":
{
"header_handle":
[
"file-handle"
],
"header_text":
[
"header-example"
]
}
},
"body":
{
"text": "Your order {{1}} is about to arrive",
"example":
{
"body_text":
[
[ "123"]
]
}
},
"footer": "My company",
"buttons":
[
{
"type": "PHONE_NUMBER|URL|QUICK_REPLY|COPY_CODE|FLOW",
"text": "phone-button-text|url-button-text",
"url": "https://www.website.com/{{1}}",
"phone_number": "+52(1) 555-1111",
"example":
[
"https://www.website.com/dynamic-url-example"
]
}
]
}
}'

Custom text-header body

A MARKETING template with a TEXT header, a body with parameters, a footer, and QUICK_REPLY + URL buttons.

{
"wba_id": "1234567899870",
"name": "marketing_custom_text",
"language": "es_MX",
"category": "MARKETING",
"structure": {
"header": {
"format": "TEXT",
"text": "Big sale, {{1}}!",
"example": {
"header_text": [
"Ana"
]
}
},
"body": {
"text": "Hi {{1}}, enjoy {{2}} off your next order this weekend only.",
"example": {
"body_text": [
[
"Ana",
"20%"
]
]
}
},
"footer": "My Company",
"buttons": [
{
"type": "QUICK_REPLY",
"text": "Stop promotions"
},
{
"type": "URL",
"text": "Shop now",
"url": "https://www.website.com/{{1}}",
"example": [
"https://www.website.com/sale"
]
}
]
}
}

Flows body

{
"name": "lead_cj_cm_dudas",
"language": "es_MX",
"category": "MARKETING",
"structure":
{
"body":
{
"text": "Connect with your customers on the right channel at the right time. SMS, RCS, WhatsApp, Messenger, Email, Voice, Chatbot, and much more."
},
"buttons":
[
{
"type": "FLOW",
"text": "Sign up",
"flow_id": "1636507303762565",
"navigate_screen": "CONTACT_INFO",
"flow_action": "navigate"
}
]
},
"wba_id": "1234567899870",
"allowCategoryChange": false
}

Carousel body with media by URL

{
"wba_id": "1234567899870",
"allowCategoryChange": false,
"name": "ejemplo_plantilla_carrusel",
"language": "es_MX",
"category": "MARKETING",
"structure":
{
"body":
{
"text": "Give your customers the best experience on their favorite channels. Use code {{1}} to get {{2}} off when you sign up.",
"example":
{
"body_text":
[
[
"DESCUENTO2024",
"25%"
]
]
}
},
"carousel":
{
"cards":
[
{
"header":
{
"format": "IMAGE",
"example":
{
"header_handle":
[
"https://iili.io/HDQOyc7.jpg"
]
}
},
"body":
{
"text": "Connect with your customers on the right channel at the right time. SMS, RCS..."
},
"buttons":
[
{
"type": "URL",
"text": "Sign up",
"url": "https://www.conceptomovil.com/producto_broadcastermobile.html"
}
]
},
{
"header":
{
"format": "IMAGE",
"example":
{
"header_handle":
[
"https://iili.io/HDQOyc7.jpg"
]
}
},
"body":
{
"text": "Serve your customers with chatbots and agents through WhatsApp conversations"
},
"buttons":
[
{
"type": "URL",
"text": "Sign up",
"url": "https://www.conceptomovil.com/producto_broadcasterbot.html"
}
]
}
]
}
}
}

Carousel body with media by ID

The header_handle value is the ID you get from Upload header media.

{
"wba_id": "1234567899870",
"allowCategoryChange": false,
"name": "coupon_code_fall2023_25off_02",
"language": "en_US",
"category": "MARKETING",
"structure":
{
"body":
{
"text": "Give your customers the best experience on their favorite channels. Use code {{1}} to get {{2}} off when you sign up.",
"example":
{
"body_text":
[
[
"Juan Pablo",
"25OFF"
]
]
}
},
"carousel":
{
"cards":
[
{
"header":
{
"format": "IMAGE",
"example":
{
"header_handle":
[
"4::aW1hZ2UvcG5n:ARZExampleHandle1:e:1771350704:1234567890:1234567890:ARZExample"
]
}
},
"body":
{
"text": "Connect with your customers on the right channel at the right time. SMS, RCS..."
},
"buttons":
[
{
"type": "URL",
"text": "Sign up",
"url": "https://www.conceptomovil.com/producto_broadcastermobile.html",
"example":
[
"https://www.conceptomovil.com/producto_broadcastermobile.html"
]
}
]
},
{
"header":
{
"format": "IMAGE",
"example":
{
"header_handle":
[
"4::aW1hZ2UvcG5n:ARZExampleHandle2:e:1771350704:1234567890:1234567890:ARZExample"
]
}
},
"body":
{
"text": "Serve your customers with chatbots and agents through WhatsApp conversations"
},
"buttons":
[
{
"type": "URL",
"text": "Sign up",
"url": "https://www.conceptomovil.com/producto_broadcasterbot.html",
"example":
[
"https://www.conceptomovil.com/producto_broadcasterbot.html"
]
}
]
},
{
"header":
{
"format": "IMAGE",
"example":
{
"header_handle":
[
"4::aW1hZ2UvcG5n:ARZExampleHandle3:e:1771350704:1234567890:1234567890:ARZExample"
]
}
},
"body":
{
"text": "The smart platform for managing your promotional campaigns"
},
"buttons":
[
{
"type": "URL",
"text": "Sign up",
"url": "https://www.conceptomovil.com/producto_cmmkt.html",
"example":
[
"https://www.conceptomovil.com/producto_cmmkt.html"
]
}
]
}
]
}
}
}

Media card carousel body (carousel_cards)

Up to 10 cards. All cards must use the same header format (IMAGE or VIDEO) and the same button list (count, types and order). Each card allows a maximum of 2 buttons of type PHONE_NUMBER, URL or QUICK_REPLY. This example uses the carousel_cards alias of the carousel component.

{
"wba_id": "1234567899870",
"name": "marketing_media_carousel",
"language": "es_MX",
"category": "MARKETING",
"structure": {
"body": {
"text": "Hi {{1}}, check out this week's featured deals!",
"example": {
"body_text": [
[
"Ana"
]
]
}
},
"carousel_cards": {
"cards": [
{
"header": {
"format": "IMAGE",
"example": {
"header_handle": [
"https://www.website.com/card1.jpg"
]
}
},
"body": {
"text": "Summer jacket, now {{1}} off.",
"example": {
"body_text": [
[
"30%"
]
]
}
},
"buttons": [
{
"type": "QUICK_REPLY",
"text": "More info"
},
{
"type": "URL",
"text": "Buy now",
"url": "https://www.website.com/jacket"
}
]
},
{
"header": {
"format": "IMAGE",
"example": {
"header_handle": [
"https://www.website.com/card2.jpg"
]
}
},
"body": {
"text": "Running shoes, now {{1}} off.",
"example": {
"body_text": [
[
"25%"
]
]
}
},
"buttons": [
{
"type": "QUICK_REPLY",
"text": "More info"
},
{
"type": "URL",
"text": "Buy now",
"url": "https://www.website.com/shoes"
}
]
}
]
}
}
}

Limited-time offer body

{
"wba_id": "1234567899870",
"allowCategoryChange": false,
"name": "coupon_code_fall2023_25off_02",
"language": "en_US",
"category": "MARKETING",
"structure":
{
"header":
{
"format": "IMAGE",
"example":
{
"header_handle":
[
"https://iili.io/HDQOyc7.jpg"
]
}
},
"limited_time_offer":
{
"text": "Ends soon!",
"has_expiration": true
},
"body":
{
"text": "Today only, {{1}}! Use code {{2}} to get a big discount when you sign up!",
"example":
{
"body_text":
[
[
"Juan Pablo",
"25OFF"
]
]
}
},
"buttons":
[
{
"type": "COPY_CODE",
"example":
[
"1234"
]
},
{
"type": "URL",
"text": "Sign up!",
"url": "https://www.conceptomovil.com/producto_broadcasterdata.html"
}
]
}
}

Zero-tap authentication body

To implement zero-tap authentication in your Android app, see Meta's documentation.

{
"wba_id": "1234567899870",
"allowCategoryChange": true,
"name": "zero_tap_example",
"language": "en_US",
"category": "AUTHENTICATION",
"structure":
{
"body":
{
"add_security_recommendation": true
},
"footer_code_expiration_minutes": 5,
"buttons":
[
{
"type": "OTP",
"otp_type": "zero_tap",
"text": "Copy Code",
"autofill_text": "Autofill",
"zero_tap_terms_accepted": true,
"supported_apps":
[
{
"package_name": "com.example.luckyshrub",
"signature_hash": "K8a/AINcGX7"
}
]
}
]
}
}

Request contact info body

Asks WhatsApp users who have an active username to share their phone number.

{
"wba_id": "1234567899870",
"name": "request_contact_template",
"language": "es_MX",
"category": "MARKETING",
"structure":
{
"body":
{
"text": "We'd like your contact details so we can keep you posted on what's new. If you want to receive updates and promotions, share your contact information with us."
},
"buttons":
[
{
"type": "REQUEST_CONTACT_INFO"
}
]
}
}

Custom body with media header (IMAGE)

The endpoint downloads the header_handle URL and uploads it to Meta, replacing it with the returned media ID. VIDEO, DOCUMENT and GIF headers work the same way (GIF is sent as VIDEO when MM Lite is not applicable).

{
"wba_id": "1234567899870",
"name": "marketing_custom_image",
"language": "es_MX",
"category": "MARKETING",
"structure": {
"header": {
"format": "IMAGE",
"example": {
"header_handle": [
"https://www.website.com/promo-banner.jpg"
]
}
},
"body": {
"text": "Hi {{1}}, our new collection is here. Tap below to explore.",
"example": {
"body_text": [
[
"Ana"
]
]
}
},
"footer": "My Company",
"buttons": [
{
"type": "URL",
"text": "View collection",
"url": "https://www.website.com/collection"
}
]
}
}

Coupon code body (COPY_CODE)

The COPY_CODE button copies the code in example[0] to the customer's clipboard when tapped.

{
"wba_id": "1234567899870",
"name": "marketing_coupon_code",
"language": "es_MX",
"category": "MARKETING",
"structure": {
"body": {
"text": "Hi {{1}}, use the code below to get 25% off your next purchase.",
"example": {
"body_text": [
[
"Ana"
]
]
}
},
"footer": "Offer valid until stock lasts",
"buttons": [
{
"type": "QUICK_REPLY",
"text": "Stop promotions"
},
{
"type": "COPY_CODE",
"example": [
"SAVE25"
]
}
]
}
}

Location header body

A UTILITY template with a LOCATION header. The location pin is populated when the template message is sent.

{
"wba_id": "1234567899870",
"name": "utility_order_delivery_update",
"language": "en_US",
"category": "UTILITY",
"structure": {
"header": {
"format": "LOCATION"
},
"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"
]
]
}
},
"footer": "To stop receiving delivery updates, tap the button below.",
"buttons": [
{
"type": "QUICK_REPLY",
"text": "Stop Delivery Updates"
}
]
}
}

Copy-code authentication body

{
"wba_id": "1234567899870",
"name": "authentication_code_copy_code_button",
"language": "en_US",
"category": "AUTHENTICATION",
"structure": {
"body": {
"add_security_recommendation": true
},
"footer_code_expiration_minutes": 10,
"buttons": [
{
"type": "OTP",
"otp_type": "copy_code",
"text": "Copy Code"
}
]
}
}

One-tap authentication body

{
"wba_id": "1234567899870",
"name": "authentication_code_autofill_button",
"language": "en_US",
"category": "AUTHENTICATION",
"structure": {
"body": {
"add_security_recommendation": true
},
"footer_code_expiration_minutes": 15,
"buttons": [
{
"type": "OTP",
"otp_type": "one_tap",
"text": "Copy Code",
"autofill_text": "Autofill",
"supported_apps": [
{
"package_name": "com.example.luckyshrub",
"signature_hash": "K8a/AINcGX7"
}
]
}
]
}
}

Catalog button body

The CATALOG button opens the business catalog linked to the WABA.

{
"wba_id": "1234567899870",
"name": "marketing_catalog_button",
"language": "es_MX",
"category": "MARKETING",
"structure": {
"body": {
"text": "Hi {{1}}, explore our full product catalog and find your next favorite item.",
"example": {
"body_text": [
[
"Ana"
]
]
}
},
"footer": "My Company",
"buttons": [
{
"type": "CATALOG",
"text": "View catalog"
}
]
}
}

Send location button body

The SEND_LOCATION button prompts the WhatsApp user to share their location.

{
"wba_id": "1234567899870",
"name": "marketing_send_location_button",
"language": "es_MX",
"category": "MARKETING",
"structure": {
"body": {
"text": "Hi {{1}}, share your location so we can find the nearest store for you.",
"example": {
"body_text": [
[
"Ana"
]
]
}
},
"buttons": [
{
"type": "SEND_LOCATION"
}
]
}
}

Order details button body

The ORDER_DETAILS button starts an order and payment flow. See Payments Brazil templates.

{
"wba_id": "1234567899870",
"name": "order_details_template",
"language": "es_MX",
"category": "UTILITY",
"structure": {
"body": {
"text": "Review the details of your order and pay."
},
"buttons": [
{
"type": "ORDER_DETAILS",
"text": "Review and pay"
}
]
}
}

Response

Create template response:

If the template is created successfully, the service responds with HTTP status code 201 and the template data.

NameDescriptionType
idTemplate ID.String
nameTemplate name.String
languageTemplate language and locale code.String
statusTemplate status. A new template is usually PENDING while Meta reviews it.String
namespaceTemplate namespace of the WABA.String
wba_idWhatsApp Business Account (WABA) ID.String
categoryCategory assigned to the template.String
allowCategoryChangeWhether Meta can automatically assign the template category.Boolean
message_send_ttl_secondsTTL in seconds. Only included if sent in the request.Integer

Note: the response may include extra optional fields (for example message_send_ttl_seconds) when they were sent in the request.


{
"id": "572279198452421",
"name": "ejemplo_respuesta",
"language": "es_MX",
"status": "PENDING",
"namespace": "2d2354d2_54fd_123r_842f_2d5b215188fa",
"wba_id": "1234567899870",
"category": "MARKETING",
"allowCategoryChange": true
}


WhatsApp — Previous
Template management
Next
Get and delete templates