WhatsApp Pre-Submission Inspect
WhatsApp Inspect is a pre-submission format checker. It catches the issues that cause Meta (WhatsApp Business Platform) to reject a template — placeholder rules, component limits, category — before you submit the template for approval, so you avoid a rejection round-trip.
Inspect is not WABA approval, and Synapse does not submit templates to Meta for you. You create the template in your Meta / provider console and submit it there; Synapse references the approved template by its provider SID. WhatsApp Inspect runs inside Synapse against your stored template and tells you whether it is likely to pass Meta's format rules. A clean Inspect result does not guarantee Meta approval, and it does not send anything.
What it checks
WhatsApp Inspect runs a single stage of pre-submission analysis against your stored WhatsApp template (body_nlt, variable_schema, category, language). It falls into three groups:
- Meta placeholder rules — the
{{1}},{{2}}positional-variable constraints Meta enforces at submission time. Getting these wrong is the most common cause of a hard rejection. - Component limits — Meta's character limits on the body (and, in future, header / footer / button components).
- NLT rendering — the same plain-English expression checks the other channels use, against a sample contact.
Severity discipline
WhatsApp Inspect is advisory: it does not gate a Synapse send (the send gate is Meta approval plus the 24-hour customer-service window). Because of that, almost everything is a warning. The only critical is a required NLT miss, which is a real whole-message drop at send time.
Variable / placeholder rules
Meta requires positional variables in a template body to follow strict rules. Violating any of them is a hard rejection on submission.
| Finding | Severity | Fires when |
|---|---|---|
WA_VARIABLE_COUNT_MISMATCH | warning | The number of distinct {{n}} placeholders in the body does not equal the number of variables declared in variable_schema. |
WA_PLACEHOLDER_NOT_SEQUENTIAL | warning | Placeholders are not a gapless sequence starting at 1 (e.g. {{1}} and {{3}} with {{2}} missing, or a body starting at {{2}}). |
WA_PLACEHOLDER_ADJACENT_OR_EDGE | warning | Two placeholders are separated only by whitespace, or a placeholder sits at the very start or end of the body. |
WA_VARIABLE_COUNT_MISMATCH
Meta requires every positional variable used in the body to be declared, and the two counts to agree. The Synapse send-time binder does not cross-check this, so this is a genuinely new pre-submission check.
Fix: Reconcile the body placeholders with variable_schema — every {{n}} in the body must have a corresponding declared variable, and vice versa.
The finding context reports both sides so you can see the mismatch:
WA_PLACEHOLDER_NOT_SEQUENTIAL
Meta requires positional variables to be "numbered sequentially without skipping integers." A body using {{1}} and {{3}} (no {{2}}), or one starting at {{2}}, will be rejected.
Fix: Renumber the placeholders so they form a gapless sequence starting at 1 — {{1}}, {{2}}, {{3}}, …
WA_PLACEHOLDER_ADJACENT_OR_EDGE
Meta rejects templates where variables are adjacent (only whitespace between two {{n}} tokens) or appear at the very start or end of the body string.
Fix: Add literal text between adjacent placeholders and ensure the body does not begin or end with a {{n}} token. For example:
Hi {{1}}, your code is {{2}}. Thanks.
Body limit
WA_BODY_OVER_LIMIT
Severity: warning — fires when body_nlt is longer than 1024 characters, Meta's maximum for a WhatsApp template body. Meta rejects the template on submission.
The measured length is the raw pre-submission source, where {{n}} tokens count as their short literal form. Meta's limit applies to the rendered message, so test with realistic variable values too.
Fix: Shorten the body to 1024 characters or fewer.
Category
WA_CATEGORY_INVALID
Severity: warning — fires when the template category is not one of Meta's allowed values: marketing, utility, or authentication.
This normally cannot happen through the API — the create / update schema already blocks an unknown category. It is defense-in-depth for a value written by a migration, seed, or direct database path.
Fix: Set the category to marketing, utility, or authentication.
NLT rendering
These use the same plain-English rendering checks as the other channels, run against a sample contact. They each have a dedicated finding page:
| Finding | Severity | Page |
|---|---|---|
WA_NLT_REQUIRED_MISS | critical | WA_NLT_REQUIRED_MISS |
WA_NLT_UNRESOLVED | warning | WA_NLT_UNRESOLVED |
Component limits (reserved)
The finding catalog defines three more component-limit checks. They do not fire today because the WhatsApp template model currently stores the message body only — it has no header, footer, or button components. These codes are reserved for when component storage is added, and are listed here for completeness:
| Finding | Meta limit | Status |
|---|---|---|
WA_HEADER_OVER_LIMIT | 60 characters (text header) | Reserved — no header component is stored today, so this cannot fire. |
WA_FOOTER_OVER_LIMIT | 60 characters (footer) | Reserved — no footer component is stored today, so this cannot fire. |
WA_BUTTON_LABEL_OVER_LIMIT | 25 characters (button label) | Reserved — no button component is stored today, so this cannot fire. |
These three checks are defensive placeholders in the catalog. They are documented here so the catalog is complete, but on today's templates they never produce a finding.
Running a WhatsApp Inspect
Trigger a run against a WhatsApp template by ID or slug:
The template is inspected regardless of its approval status — a pending or even rejected template is fully inspectable, since the whole point is catching format issues before (or after) a Meta rejection. See the Inspect API reference for the full request and response shape.