Create template
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:
| URL | https://{{url}}/whatsapp-bsp-admin-ext-endpoint-ws/services/v1/template |
| Method | POST |
| Type | application/json |
Headers
Create template headers:
| Name | Description | Type | Requirements |
|---|---|---|---|
| Content-Type | application/json | String | Required |
| Authorization | Admin token. See Generate authentication token. | String | Required |
Body
Create template body fields:
| Name | Description | Type | Requirements |
|---|---|---|---|
| wba_id | WhatsApp Business Account (WABA) ID. It must be the WABA linked to your token. Digits only. | String | Required |
| name | Template name. Only letters, numbers, and underscores (_) are allowed. | String | Required |
| language | Template language and locale code. Example: es, es_MX, en_US. See the languages supported by Meta. | String | Required |
| category | Template category:
| String | Required |
| allowCategoryChange | If true, Meta can automatically assign the appropriate category to the template. Default: true. Send this field as allowCategoryChange (camelCase). | Boolean | Optional |
| message_send_ttl_seconds | Time to live (TTL) in seconds: the maximum time WhatsApp keeps trying to deliver a message sent with this template. Allowed ranges by category:
| Integer | Optional |
| degrees_of_freedom_spec | Pass-through object forwarded to Meta to control template flexibility options. Optional; used for advanced template configurations. | Object | Optional |
| optimization_spec | Pass-through object forwarded to Meta to control template optimization. Optional; used for advanced template configurations. | Object | Optional |
| structure | Template structure. | Structure object | Required |
Structure object
| Name | Description | Type | Requirements |
|---|---|---|---|
| header | Template header. | Header object | Optional |
| body | Template body. | Body object | Required |
| footer | Template footer. Not used in AUTHENTICATION templates. | String | Optional |
| footer_code_expiration_minutes | Code expiration time, in minutes, shown in the footer. AUTHENTICATION templates only. Minimum 1, maximum 90. | Integer | Optional |
| buttons | Buttons the template can include. | Array of buttons objects | Optional |
| limited_time_offer | Limited-time offer component. Lets you show expiration dates and countdown timers for offer codes in template messages. | Limited_time_offer object | Optional |
| carousel | Carousel component. Lets you send a single text message along with a set of up to 10 cards in a horizontally scrollable view. | Carousel object | Optional |
| call_permission_request | If 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. | Boolean | Optional |
Header object
| Name | Description | Type | Requirements |
|---|---|---|---|
| format | Header format. Accepted values:
| String | Required |
| text | Header text. | String | Required if format is TEXT |
| example | Sample values for the header variables or sample header media. | Header example object | Required if format is IMAGE, DOCUMENT, VIDEO, or GIF |
Header example object
| Name | Description | Type | Requirements |
|---|---|---|---|
| header_handle | Sample header media (image, video, or document). You can send it in one of two ways:
| Array of strings | Conditional |
| header_text | Sample values for the header text variables. | Array of strings | Optional |
Body object
| Name | Description | Type | Requirements |
|---|---|---|---|
| text | Body text. It can't start or end with a variable. Not used in AUTHENTICATION templates, because Meta defines the text. | String | Required, except in AUTHENTICATION templates |
| add_security_recommendation | If true, the security recommendation text is added to the body. AUTHENTICATION templates only. | Boolean | Optional |
| example | Sample values for the template variables. | Body example object | Optional |
Body example object
| Name | Description | Type | Requirements |
|---|---|---|---|
| body_text | Sample variable values. Include one value for each variable in the body text. | Array of string arrays | Optional |
Supported_apps object
| Name | Description | Type | Requirements |
|---|---|---|---|
| package_name | Package 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. | String | Required |
| signature_hash | Signing 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. | String | Required |
Limited_time_offer object
| Name | Description | Type | Requirements |
|---|---|---|---|
| text | Offer details text. Maximum 16 characters. | String | Required |
| has_expiration | If 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. | Boolean | Required |
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.
| Name | Description | Type | Requirements |
|---|---|---|---|
| cards | Carousel cards. Maximum 10 cards. | Array of cards objects | Required |
Cards object
| Name | Description | Type | Requirements |
|---|---|---|---|
| header | Card header. Only the IMAGE and VIDEO formats are accepted, and all cards must use the same format. | Header object | Required |
| body | Card body. Maximum 160 characters. | Body object | Required |
| buttons | Card 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 objects | Required |
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"}]}]}}
Response
Create template response:
If the template is created successfully, the service responds with HTTP status code 201 and the template data.
| Name | Description | Type |
|---|---|---|
| id | Template ID. | String |
| name | Template name. | String |
| language | Template language and locale code. | String |
| status | Template status. A new template is usually PENDING while Meta reviews it. | String |
| namespace | Template namespace of the WABA. | String |
| wba_id | WhatsApp Business Account (WABA) ID. | String |
| category | Category assigned to the template. | String |
| allowCategoryChange | Whether Meta can automatically assign the template category. | Boolean |
| message_send_ttl_seconds | TTL 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}
