Skip to main content
Meta reviews the template after it is created, but rejects right away anything that is out of shape. The rules below are the ones that show up most, with the error code each one produces.
Whatever the payload structure already states (character limits, accepted types, counts) is declared in the API reference schema: the playground shows it field by field. This page is for the rules the schema cannot express.

Character limits

The name accepts lowercase letters, digits and underscore, and it does not change after creation.

Line breaks

Only the message accepts line breaks. Header, footer and button text are single-line: \n, \r and tabs there are grounds for rejection, and so is more than four spaces in a row. In the message, avoid a blank line at the end and more than two breaks in a row.

Variables

By far the biggest source of rejections.

A variable cannot open or close the text

This applies to the header and to the message. Meta calls it a dangling parameter, and the code is 2388299.

Every variable needs an example

Without example, Meta rejects with missing expected field(s) (example), code 2388043. The example is what the reviewer reads to understand the template.

In positional format, numbering is sequential and starts at 1

The example travels as a list, and Meta matches each item by position. With {{1}} and {{3}}, the third one ends up without an example, and the rejection talks about a missing field without mentioning numbering.
{{1}} with {{3}} is rejected. Use {{1}} and {{2}}.

The header accepts one variable

Just one. The second comes back as “The Header field can only have up to 1 variable(s)”, code 2388029. Meta treats the footer as plain text: a variable there is not replaced and goes literally to the customer.

Short text with many variables is rejected

Meta compares how many variables there are against the length of the text, and rejects what is out of proportion, with code 2388293. It does not publish the formula. From our measurements, with two variables or more, count three words of text per variable, plus one.
Two variables glued together, with no text between them, are usually rejected as well.

Buttons

Quick replies stay together

Meta doesn’t require them to come first: it requires the buttons to sit in two groups, the quick replies and everything else. A quick reply in the middle of other types is rejected.

URL and phone format

The URL needs http or https. www.yourstore.com without the protocol is rejected, and the error cites the button index in the payload. The phone number goes in international format, with the country code: +5511988881234. Without the + and the country, the rejection is (#192) ... is not a valid phone number.

Variables in buttons

The URL button accepts one variable, and only at the end of the address:
Phone numbers and coupon codes accept no variables.

Labels Meta writes

On catalog, multi-product, single product, checkout, order and on the authentication code, the button text belongs to Meta. The text field is still required: what changes is that the value isn’t yours. Sending a different one is rejected with code 2388153, and the response says which one was right.
There is no language rule here. On the same pt_BR template, Meta demands Ver for SPM and View items, in English, for MPM. Both were measured in rejections. When it rejects, the message states the required text: use that one.
The WhatsApp app translates the label into the recipient’s language, so the value you send at creation is not what the customer reads.
  • 2 to 10 cards on the media carousel. On the product one, exactly 2 at creation, and up to 10 at send time.
  • Every card with the same components. As a consequence: if one card has text, all of them need text; the set of buttons (type and order) is the same across cards. What changes from one card to the next is the button text and the destination.
  • On the media carousel, every card needs media.
  • The product card has a {"format": "PRODUCT"} header and a single button, with no card text. Sending two buttons or a body comes back as component of type BODY is required, code 2388045, which does not describe the cause.

Media

In the header and in the cards, the media reference is the handle obtained in Upload media, or the public link to the file, which we convert to a handle before creating the template.
The link Meta returns when you read a template (domains whatsapp.net, fbcdn.net, fbsbx.com) is not valid as a sample going back: resent, it is rejected with invalid media sample, code 2388215. This happens in every flow that reads a template and resends what it read.
The link has to open for a server, not only in a browser. Stores and blogs often block automated downloads, and then Meta answers media download failed, code 380. The header image is displayed at 1.91:1, landscape. Anything outside that ratio is not rejected: WhatsApp crops the excess to fit, from the center. Worth building the artwork at that size, or accepting that the edges disappear on the customer’s phone.

Delivery window

message_send_ttl_seconds has a range per category: The value -1 is a shortcut for 30 days. On authentication, the delivery window cannot be shorter than the code validity: if the message stops being delivered first, the customer loses both.

How many templates fit in the account

The limits below belong to the account, not to the template you are creating. That is why their rejection is confusing: it does not mention anything that is in your payload. The name is unique per WABA and language: the same name in pt_BR and in en_US are two templates, and both are accepted. Repeating name and language in the same account comes back as already exists — including when the other one was deleted less than 30 days ago, because deleting reserves the name for that period.
Going over 100 creations per hour is not a payload error: it is a queue. If you are migrating a whole catalog of templates at once, create them in batches and wait between them, instead of retrying right away.

Editing and deleting

  • An approved template accepts up to 10 edits in 30 days, and one every 24 hours. Rejected and paused have no such cap.
  • Only approved, rejected and paused templates can be edited.
  • Name and language do not change. Neither does the category of an approved template.
  • An edit replaces all components: send the complete set, because whatever is left out is erased.
  • After an edit, the template goes back into the review queue on its own.
  • Deleting an approved template reserves its name for 30 days.

Meta errors, and what each one means

When the rejection comes from Meta, we return her original message along with the traceId. Keep both: they are what support uses to identify the case.