WhatsApp Message Templates via the API: The Complete Guide
TL;DR
Message templates are pre-written messages approved by Meta, and they’re the only way to reach a customer outside the 24-hour window or in a broadcast send. This article explains when you need a template, how the three categories work (Marketing, Utility, Authentication), which components a template can contain, and how to pass approval the first time. One critical point: a template can’t be edited after it’s created — fixing one always means deleting it and creating a new one.
Why message templates exist in the first place
Meta’s WhatsApp Business platform is built around a 24-hour conversation window: the moment a customer sends a business a message, a 24-hour window opens during which the business can reply with anything — text, media, buttons, whatever it needs. Once the window closes, or when the business wants to reach out first to a customer who hasn’t written, the only thing it’s allowed to send is a message template pre-approved by Meta.
Every business-initiated outreach in Mumble — a campaign, a reminder, an OTP, a shipping notification, a personal message in the inbox outside the window — goes through a template. That’s why building your template library correctly isn’t a one-time task at account setup, but infrastructure that stays with the business throughout its use of Mumble.
The three categories, and what each one allows
Meta classifies every template into one of three categories. The category affects two things: the cost to send, and what’s allowed in the message. Choosing the wrong category is the most common reason for rejection and for a higher-than-expected charge.
| Category | When to use | Relative cost |
|---|---|---|
| Authentication | OTP codes, login verification, password reset | Lowest (in Israel, usually free or nearly free) |
| Utility | Order updates, shipping tracking, appointment reminders, payment confirmations | Medium |
| Marketing | Promotions, launches, cart abandonment, surveys, remarketing | Highest |
Authentication — what’s allowed and what isn’t
- Content: a verification code only, up to 15 characters, inside a variable (
{{1}}). - Not allowed: links, images, emojis, marketing text, and no long greeting wrapped around the code.
- Allowed: a single button to copy the code or autofill it in the app.
- Rejection risk: low, as long as the message really just delivers a code and doesn’t try to promote a product alongside it.
Utility — what’s allowed and what isn’t
- Content: an update about an action the customer initiated themselves — an order, an appointment, a payment, a status change.
- Not allowed: any word of promo. Even “and by the way, we have 10% off” will reclassify the message as Marketing.
- Media: an image, video, or document is allowed, but only when it serves the service purpose (a shipping slip as a PDF — fine; a promotional banner — no).
- Rejection risk: medium. Most failures come from mixing a marketing pitch with a service update.
Marketing — what’s allowed and what isn’t
- Content: almost any business-initiated outreach — promotions, launches, remarketing, satisfaction surveys.
- Allowed: emojis, links, media, multiple buttons, free-form wording.
- Required: the customer must have an approved opt-in. Sending to an unfiltered list is a fast way to hurt the number’s quality rating.
- Rejection risk: low in terms of content, higher in terms of quality — marketing messages that get a lot of blocks or spam reports lower the quality of the entire sending number.
The classification trap: if a message mixes utility content with a single marketing sentence, Meta classifies it as Marketing — the higher price category. When in doubt, split it into two separate templates.
Components of a message template
Every template is built from up to four components, some required and some optional. Knowing the components and their limits saves most rejection rounds.
Header — optional
- One of: text, image, video, or document.
- A text header can’t contain variables — that’s a Meta restriction.
- In marketing, a header with an image significantly increases the open rate. In utility, it’s best to stick with plain text or no header at all.
Body — required
- Up to 1,024 characters. The counter appears in the corner of the field on the template creation screen in Mumble.
- Supports positional variables in the format
{{1}},{{2}},{{3}}— in sequence, with no gaps. - The body can’t begin or end with a variable.
- Two variables can’t be adjacent, e.g.
{{1}}{{2}}— there must be fixed text between them. - A value injected into a variable can’t contain a newline, a tab, or more than 4 consecutive spaces.
Footer — optional
- Plain text only, up to 60 characters, no variables and no media.
- Classic use: an opt-out instruction (“Reply STOP to unsubscribe”) in marketing messages, or a short signature in utility.
Buttons — optional
Up to 10 buttons total in a single message, in flexible combinations:
- Quick Reply — a button that returns fixed text into the system. Useful mainly in the chatbot, because it lets you branch based on the customer’s choice.
- Call to Action — URL — opens a link to a website. Up to one allowed per message.
- Call to Action — Phone — dials a phone number. Up to one allowed per message.
You can combine many Quick Reply buttons with a single URL button and a single phone button in the same message, as long as the total doesn’t exceed 10.
Rules for names, language, and variables
Template name
- Up to 30 characters, in English only.
- No spaces — use an underscore (
order_shipped_v2,otp_login_he). - Lowercase letters, numbers, and underscores only. Hebrew, uppercase, or special characters are rejected automatically.
- The name must be unique within the account. Trying to save a template with a name that already exists returns an error.
- This check runs before Meta’s content review, so a name error fails immediately.
Language
- One language per template. You can’t mix Hebrew and English in the same body.
- To communicate with customers in different languages, create a separate template for each language (usually with a similar name and a suffix:
welcome_he,welcome_en).
Variables
- Format:
{{1}},{{2}},{{3}}— positional, not named. - Syntax like
{name}or{{first_name}}isn’t supported in templates. (That syntax belongs to the chatbot canvas, which is a different concept.) - When sending — via a campaign, the inbox, or the API — you fill in the values in order.
The approval process
- You save the template in Mumble. On the “Message templates” screen, the status “Pending approval” appears.
- Mumble forwards the request to Meta automatically.
- Meta approves or rejects. In practice, approval takes anywhere from a few minutes to about 24 hours — depending on the category and Meta’s load.
- An approved template moves to “Approved” status and becomes available for sending via a campaign, the inbox, or the API.
- A rejected template moves to “Rejected” status with the reason for rejection.
Fixing a rejected template: delete and recreate
This is the most important point in this article, because it runs counter to intuition: a message template can’t be edited after it’s created. After saving the template in Mumble — whether it’s in “Approved”, “Pending approval”, or “Rejected” status — the only thing you can do with it is delete it and create a new one.
So dealing with a rejected template always looks like this:
- Open the template in Mumble and read the rejection reason.
- Delete the template.
- Create a new template with a new name (since names are unique) and the relevant fix.
- Wait again for Meta’s approval.
The practical takeaway: treat every template as a permanent record. Double-check the name, category, body, and variables before saving. A small library of vetted templates beats dozens of half-working variations.
Examples
A Utility example — shipping confirmation
Name: order_shipped_he
Category: Utility
Body:
Hi {{1}},
Your order #{{2}} has shipped and will arrive on {{3}}.
You can track the shipment using the link in the button below.
Footer: “Our store, customer service Sun–Thu”
Button: Call to Action — URL, “Track shipment”, pointing to the tracking page.
This example passes approval because it refers to an action the customer initiated (an order), contains no marketing content, and the variables aren’t at the start or end of a sentence.
A Marketing example — end-of-season sale
Name: summer_sale_2026
Category: Marketing
Header: Image — sale banner
Body:
Hi {{1}}, it’s end of season here — 30% off the whole collection until {{2}}.
Worth a look before the sizes run out. Your coupon: {{3}} 🎉
Footer: “Reply STOP to unsubscribe”
Buttons: Quick Reply “Show me” + Call to Action — URL “Shop now”.
This example fits Marketing: there’s a clear value offer, an action button, an expiry date, and a clear opt-out option. The emoji appears inside the content itself — where it’s allowed and even customary.
Common issues
The template was rejected — “Wrong category”
Symptom: a message worded as a service update was submitted as Utility and rejected, or the reverse — a marketing message was submitted as Utility.
Reason: Meta scans the content and compares it to the category you chose. Even a single marketing sentence inside a service message will classify the entire message as Marketing.
Fix: delete it, recreate it with the correct category, or split it into two separate templates if the content really is mixed.
The template was rejected — variable at the start or end of the body
Symptom: immediate rejection, with a generic “content format” reason.
Reason: a Meta rule — the body can’t begin or end with a variable. {{1}}, your order has shipped will fail.
Fix: add fixed text around the variables. Hi {{1}}, your order has shipped. will pass.
The template was rejected — two adjacent variables
Symptom: rejection of {{1}}{{2}} in sequence.
Reason: Meta requires fixed text between any two variables, so one variable’s value doesn’t bleed into the next.
Fix: separate them with a word, comma, or space — for example {{1}} ({{2}}).
The template name isn’t accepted
Symptom: the save in Mumble fails before the request even reaches Meta.
Reason: the name contains Hebrew, spaces, uppercase letters, or other invalid characters. It may also already be taken in the account.
Fix: an English-only name, lowercase letters, numbers, and underscores. If the name is taken, add a version suffix (_v2, _he).
Sending the message via the API returns an error even though it’s approved
Symptom: the template shows as “Approved” but the API call returns an error.
Reason: usually an invalid phone number format, a mismatch between the number of variables sent in the call and the number defined in the body, or an attempt to send a marketing message to a customer without an opt-in.
Fix: an international-format number with no + and no leading 0 (972501234567); the same number of variables in the call as in the body; and a customer with a valid opt-in for Marketing.
The template was approved once, and now it’s gone into “Paused” status
Symptom: a template that worked for a long time was moved to Paused by Meta.
Reason: a drop in quality — blocks, spam reports, a below-average read rate.
Fix: narrow the reach, make sure every recipient has opted in, review the wording. After a period of stable quality, Meta will return the template to approved status.
Related articles
- Creating a WhatsApp message template
- Message templates: statuses, rules, and the quality rating
- Template rejected: a guide to fixing and appealing
- The complete guide to sending a WhatsApp campaign
- The Mumble API, the complete guide
- Message template library
The bottom line
A message template is a permanent record: getting the name, category, and content right the first time saves rejection rounds, because a fix always means deleting and recreating — not editing.