Templates
We recommend using the Channels application for template management since this offers a relatively easy-to-use solution where we safeguard your templates' validity when Meta's terms, conditions and features change in the future.
This guide partially describes models, omitting fields/properties that're either read-only, not relevant or don't require explanation beyond the existing API docs.
We strongly recommended you to consider our system's design, capabilities and intended use to prevent updating your implementation in the future.
Templates & languages
Our API provides all necessary facilities to programmatically manage your templates if you so desire.
Although the API allows for different/exotic workflows, future updates and extensions are built and validated against some basic principles.
Templates (CM.com) consist of Languages (Meta "Templates").
Templates
Templates contain Languages which are mapped to Meta "Templates" when validation is requested.
- Minimum is 1 language, maximum is the amount of languages supported by WhatsApp (Meta)
- A single language (e.g. "en_US") can be defined only once per template
- Templates contain fields for basic settings that are applied to its Languages
- Templates contain properties with advanced settings that are applied to its Languages
Template fields (API)
Field | Description | Type | Required |
---|---|---|---|
name | Template name. | string | yes |
templateCategoryId | Template category identifier (API). | string (guid) | yes |
generatedLayout * | Template generated layout. | string (enum) | no |
enabledLanguages | List of enabled languages (API). | array <string (guid)> | yes |
* Our endpoint to get the available template categories (API) returns the options per Meta category (Meta).
Template properties
Property | Description | Type | Required |
---|---|---|---|
headerSettings | Template header settings, shared between Languages. | object | yes |
settings | Template body settings, shared between Languages. | object | yes |
interactiveSettings | Template interactive settings, shared between Languages. | object | yes |
languages | Template Languages. | dictionary <object> | yes |
Field | Description | Type | Required |
---|---|---|---|
format | Sets the header type for all Languages. - NONE - TEXT - IMAGE - DOCUMENT - VIDEO | string (enum) | yes |
replacementFields * | Add/remove variables that must be added to the header text of all Languages. | array <object> | no |
* TEXT header format only
Body settings (Meta)
Field | Description | Type | Required |
---|---|---|---|
replacementFields * | Add/remove variables that must be added to the body text of all Languages. | array <object> | no |
* Management of fields requires the usage of separate endpoints, Add (API), Update (API) and Remove (API).
Field | Description | Type | Required |
---|---|---|---|
buttons | Definition of basic buttons (i.e. grouping of buttons (Meta)). | array <object> | no, with exceptions |
Interactive settings - button
Field | Description | Type | Required |
---|---|---|---|
type | Button type. - PHONENUMBER - URL - QUICK_REPLY - OTP_COPY - CODE_COPY | string (enum) | yes |
urlType | Button URL type. - STATIC - DYNAMIC | string (enum) | when type is URL |
Replacement field
Field | Description | Type | Required |
---|---|---|---|
id | Field identifier, system-generated. | string (guid) | yes |
index | Field index, system-generated. Messages containing fields must have replacements declared in ascending order throughout it's content. | integer | yes |
name | Placeholder name of the field. Used as example value during Meta validation. | string | yes |
type | Field type. - TEXT - CURRENCY - DATETIME | string (enum) | yes |
Languages
Languages contain translated (by you) content for its layout elements.
Field | Description | Type | Required |
---|---|---|---|
header | Language header settings. | object | yes |
body | Language body settings. | object | yes |
footer | Language footer settings. | object | yes |
interactiveSettings | Language interactive settings. | object | no, with exceptions |
carouselLayoutSettings | Language carousel settings. | object | no, with exceptions |
limitedTimeOffer | Language limited-time-offer settings. | object | no, with exceptions |
Field | Description | Type | Required |
---|---|---|---|
content | Text to appear in the message "header" when sent. | string | no * |
* Required if Template header settings format is set to TEXT
Field | Description | Type | Required |
---|---|---|---|
content * | Text to appear in the message "body" when sent. | string | yes |
* Supports multiple replacements fields
Field | Description | Type | Required |
---|---|---|---|
content | Text to appear in the message immediately after the body text ("footer") when sent. | string | no |
otpSettings * | Settings for some Authentication category templates. | object | no, with exceptions |
Footer element - otpSettings
Field | Description | Type | Required |
---|---|---|---|
copyCodeExpirationMinutes * | Expiration warning text in minutes to appear in the message immediately after the body text ("footer") when sent. | integer | no |
* Only for Authentication category templates with Copy Code layout option
Field | Description | Type | Required |
---|---|---|---|
buttons * | Collection of buttons, based on Template settings. | array <object> | yes |
* It is required to create Template settings upfront, your changes are omitted when you reference buttons that are missing on Template level.
Interactive settings element - button
Field | Description | Type | Required |
---|---|---|---|
id | Button identifier, system-generated when creating buttons via Template interactive settings. | string (guid) | yes |
type | Button type. - PHONENUMBER - URL - QUICK_REPLY - OTP_COPY - CODE_COPY | string (enum) | yes |
urlType | Button URL type. - STATIC - DYNAMIC | string (enum) | when type is URL |
buttonText | Button text, visible in the sent message. | string | yes |
url | Button URL, a web location that's navigated to on button click. | string | when type is URL |
phoneNumber | Button phone number, set as recipient in phone application on button click. | string | when type is PHONENUMBER |
Carousel element - card
Field | Description | Type | Required |
---|---|---|---|
header * | The Carousel Media Type (Image/ Video) set/overridden by the Language carousel settings that are applied to all Cards in your carousel. - IMAGE - VIDEO | string (enum) | yes |
body | Sets the card body text. | string | yes |
buttons * | Collection of button definitions. | array <object> | yes |
Carousel element - settings (API)
Field | Description | Type | Required |
---|---|---|---|
header.format | Carousel card header. - IMAGE - VIDEO | string (enum) | yes |
buttonsSettings | Definition of (Template interactive settings) buttons for all Cards in the carousel. | array <object> | yes |
* CarouselSettings are created per Language via a separate endpoint (API). Settings are applied to all cards in your carousel, system will not assist on carousel validity when settings are NULL.
Field | Description | Type | Required |
---|---|---|---|
content | Sets the limited time offer text. | string | yes |
hasExpiration | Sets offer expiration details. | boolean | yes |
Status & validation
Languages have independent statuses assigned, based on their state.
Status | Description |
---|---|
Incomplete | Language is not conforming to layout and/or content requirements. Layout, e.g. shared template settings require all of your languages to contain header and/or footer content, buttons of certain type and content. Content, e.g. body content cannot be empty or exceed character limit, quick reply buttons must have their button text set. |
Eligible | Language's layout & content conforms to basic and/or shared requirements. |
Pending/Processing | Validation is requested but we have not yet received Meta's callback. |
Rejected | Meta rejected the language's layout and/or content. API response now includes the rejection reason. |
Active | Meta approved the language's layout & content. |
Meta validation process
Requesting validation will lock the layout & content of a Language.
Only after rejection a language's content will unlock again.
Template validation can be requested when all (excluding Active
/Pending
/Processing
) Languages are Eligible
.
When a Language is rejected we include Meta's reason to our API response for you to review.
Template shared layout settings (applied to all Languages) will be locked the moment the first language becomes Active.
Meta approval status, callback history & analytics
Meta's callback history regarding status and rating is exposed by providing the optional "includeMetaCallbackHistory" parameter.
An endpoint (API) to retrieve Meta's template analytics (Meta) is available, returning a Meta raw response for all Languages in your Template or for a single Language by providing the optional language id filter.
Categories & layouts
The level of optimization and automation by our system depends on the template category (API) you choose to create.
Meta will approve or reject your templates based on their rules and regulations (Meta) which are linked to categories or even pre-defined layouts within a category.
When you narrow down to a specific use-case/intention with your template, Meta will increase strictness on general layout and content validation. Our system therefore optimizes and automates more, when strictness increases.
From our system's perspective we can identify 2 template flavors.
- Free-form, i.e. a blank layout template where you have maximum control over your layout and content, e.g.
- Marketing category template without "Predefined" layout option
- Utility category template without "Predefined" layout option
- Predefined, i.e. a generated layout template where, based on Meta's guidelines, certain layout and content elements are predefined and/or locked
- Authentication category templates, this category requires you to choose a generated layout
- Marketing category template with Carousel layout option
- Utility category template with Carousel layout option
Our endpoint to get the available template categories (API) returns the options per Meta category.
Predefined/generated layouts
We offer advanced automations for templates that have strict layout and content requirements by Meta.
These templates are marked as "generated layouts" in our system and a layout is always linked to a category.
Generated layout templates must be instantiated by providing a layout option during creation or update of a Template.
Category (name) | Generated layouts | Meta reference |
---|---|---|
Authentication | AUTHENTICATION_OTP_COPY | Copy Code Authentication |
Marketing | MARKETING_CAROUSEL MARKETING_COUPONS MARKETING_LIMITED_TIME_OFFER | Carousel Templates Coupon Code Templates Limited-Time Offer Templates |
Utility | UTILITY_CAROUSEL | Carousel Templates |
Our system generates the necessary layout/content for all Languages in a Template when a layout option is provided during Template creation or update.
Generated layout/content can not be changed or removed from Template/Languages as long as a generated layout is active.
Some message elements are restricted to specific layouts only and are ignored when used outside of their intended layouts.
Restrictions | OTP_COPY | COUPONS | LIMITED_TIME_OFFER | CAROUSEL |
---|---|---|---|---|
header | format = NONE content = NULL | - | format = NONE /IMAGE /VIDEO | format = NONE content = NULL |
body | content = NULL | - | - | - |
footer | content = NULL otpSettings = {} | - | content = NULL | content = NULL |
buttons | single OTP_COPY button | 1x CODE_COPY button | 1x CODE_COPY button1x URL button | none allowed |
additional | - | - | limitedTimeOffer required | carousel required |
Automation
We want to optimize your chances on instant Meta approval of your templates and therefore our system will assist you by generating uniform Languages within in your Templates where possible.
When automation is triggered, Languages in your Template will be updated to conform to Meta's rules & regulations automatically.
Layout & content might be lost during automations, minimize impact by setting Template level settings before setting Language content.
Follow the steps described here
You will find that changing certain Template level settings will automatically update your Languages in the process.
More about shared settings here.
Combining button types is allowed in some situations but Meta's rules & regulations regarding button grouping changes over time.
Our system will automatically re-group and/or repair when necessary.
More about interactive settings here.
The use of "predefined/generated layouts" triggers advanced automation and potentially introduces severe limitations you must be aware off.
More about layouts here
Meta sometimes requires you to provide example values for dynamic values e.g. "Header image/video/document" and "Body variables", our system will automate this where possible by using the "useDefaultHeaderMediaExample" option when requesting validation (API).
Create a Template
Please follow below steps to create Templates with one or more Languages.
Prevent working against our automation by using a request's response as body for the next update request.
- Create Template (API) and declare it's fields
- Optional, Update Template (API) **
- Changes to Template fields
- Changes to Template properties
headerSettings
(API) *settings
*interactiveSettings
(API) *
- Update Language(s) (API) **
- Changes to Language elements
- Conditional, changes to
generatedLayout
elements
- Request Meta approval process (API)
- Check Meta approval status (API)
* Changes might trigger automation.
** Although combining updates to Template and Languages settings is supported, we strongly recommend you not to. Triggering automation via this endpoint might lead to the system omitting your Language changes in the process.
Updated 8 months ago