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)

FieldDescriptionTypeRequired
nameTemplate name.stringyes
templateCategoryIdTemplate category identifier (API).string (guid)yes
generatedLayout *Template generated layout.string (enum)no
enabledLanguagesList 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

PropertyDescriptionTypeRequired
headerSettingsTemplate header settings, shared between Languages.objectyes
settingsTemplate body settings, shared between Languages.objectyes
interactiveSettingsTemplate interactive settings, shared between Languages.objectyes
languagesTemplate Languages.dictionary <object>yes

Header settings (API / Meta)

FieldDescriptionTypeRequired
formatSets 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)

FieldDescriptionTypeRequired
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).


Interactive settings (API / Meta)

FieldDescriptionTypeRequired
buttonsDefinition of basic buttons (i.e. grouping of buttons (Meta)).array <object>no, with exceptions

Interactive settings - button

FieldDescriptionTypeRequired
typeButton type.
- PHONENUMBER
- URL
- QUICK_REPLY
- OTP_COPY
- CODE_COPY
string (enum)yes
urlTypeButton URL type.
- STATIC
- DYNAMIC
string (enum)when type is URL

Replacement field

FieldDescriptionTypeRequired
idField identifier, system-generated.string (guid)yes
indexField index, system-generated.
Messages containing fields must have replacements declared in ascending order throughout it's content.
integeryes
namePlaceholder name of the field.
Used as example value during Meta validation.
stringyes
typeField type.
- TEXT
- CURRENCY
- DATETIME
string (enum)yes

Languages

Languages contain translated (by you) content for its layout elements.

FieldDescriptionTypeRequired
headerLanguage header settings.objectyes
bodyLanguage body settings.objectyes
footerLanguage footer settings.objectyes
interactiveSettingsLanguage interactive settings.objectno, with exceptions
carouselLayoutSettingsLanguage carousel settings.objectno, with exceptions
limitedTimeOfferLanguage limited-time-offer settings.objectno, with exceptions

Header element (API / Meta)

FieldDescriptionTypeRequired
contentText to appear in the message "header" when sent.stringno *

* Required if Template header settings format is set to TEXT


Body element (API / Meta)

FieldDescriptionTypeRequired
content*Text to appear in the message "body" when sent.stringyes

* Supports multiple replacements fields


Footer element (API / Meta)

FieldDescriptionTypeRequired
contentText to appear in the message immediately after the body text ("footer") when sent.stringno
otpSettings*Settings for some Authentication category templates.objectno, with exceptions

Footer element - otpSettings

FieldDescriptionTypeRequired
copyCodeExpirationMinutes*Expiration warning text in minutes to appear in the message immediately after the body text ("footer") when sent.integerno

* Only for Authentication category templates with Copy Code layout option


Interactive settings element (API / Meta)

FieldDescriptionTypeRequired
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

FieldDescriptionTypeRequired
idButton identifier, system-generated when creating buttons via Template interactive settings.string (guid)yes
typeButton type.
- PHONENUMBER
- URL
- QUICK_REPLY
- OTP_COPY
- CODE_COPY
string (enum)yes
urlTypeButton URL type.
- STATIC
- DYNAMIC
string (enum)when type is URL
buttonTextButton text, visible in the sent message.stringyes
urlButton URL, a web location that's navigated to on button click.stringwhen type is URL
phoneNumberButton phone number, set as recipient in phone application on button click.stringwhen type is PHONENUMBER

Carousel element (API / Meta)

FieldDescriptionTypeRequired
cardsSet of up to 10 carousel Cards displaying either an image or video, alongside with up to 2 buttons per card.array <object>yes
carouselSettingsContains shared card settings *.objectno *

Carousel element - card

FieldDescriptionTypeRequired
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
bodySets the card body text.stringyes
buttons*Collection of button definitions.array <object>yes

Carousel element - settings (API)

FieldDescriptionTypeRequired
header.formatCarousel card header.
- IMAGE
- VIDEO
string (enum)yes
buttonsSettingsDefinition 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.


Limited-Time Offer element (API / Meta)

FieldDescriptionTypeRequired
contentSets the limited time offer text.stringyes
hasExpirationSets offer expiration details.booleanyes



Status & validation

Languages have independent statuses assigned, based on their state.

StatusDescription
IncompleteLanguage 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.
EligibleLanguage's layout & content conforms to basic and/or shared requirements.
Pending/ProcessingValidation is requested but we have not yet received Meta's callback.
RejectedMeta rejected the language's layout and/or content. API response now includes the rejection reason.
ActiveMeta 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.

  • For a single Language (API)
  • For all Template Languages (API) combined

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 layoutsMeta reference
AuthenticationAUTHENTICATION_OTP_COPYCopy Code Authentication
MarketingMARKETING_CAROUSEL
MARKETING_COUPONS
MARKETING_LIMITED_TIME_OFFER
Carousel Templates
Coupon Code Templates
Limited-Time Offer Templates
UtilityUTILITY_CAROUSELCarousel 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.


RestrictionsOTP_COPYCOUPONSLIMITED_TIME_OFFERCAROUSEL
headerformat = NONE
content = NULL
-format = NONE/IMAGE/VIDEOformat = NONE
content = NULL
bodycontent = NULL---
footercontent = NULL
otpSettings = {}
-content = NULLcontent = NULL
buttonssingle OTP_COPY button1x CODE_COPY button1x CODE_COPY button
1x 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.


  1. Create Template (API) and declare it's fields
    1. name
    2. templateCategoryId (+ optional generatedLayout) (API) *
    3. enabledLanguages (API)
  2. Optional, Update Template (API) **
    1. Changes to Template fields
      1. name
      2. templateCategoryId (+ optional generatedLayout) (API) *
      3. enabledLanguages (API)
    2. Changes to Template properties
      1. headerSettings (API) *
      2. settings *
      3. interactiveSettings (API) *
  3. Update Language(s) (API) **
    1. Changes to Language elements
      1. header
      2. body
      3. footer
      4. interactiveSettings
    2. Conditional, changes to generatedLayout elements
      1. carouselLayoutSettings *
      2. limitedTimeOffer
  4. Request Meta approval process (API)
  5. 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.