/templates) or via the public REST API (/v1/templates) and the MCP server (templates_create / templates_update / templates_delete). When sending, reference the template by templateId and pass a variables object with matching keys.
All requests use the
x-api-key: ps_... header (or x-api-key-id). Base URL: https://pilotstatus.com.br/v1.Category
Set at creation time; cannot be changed later.- MARKETING — promotional messages (more sensitive to WhatsApp policies).
- UTILITY — transactional messages (account updates, alerts, reminders).
- OTP — one-time / verification code messages.
Template structure
Only body is required.Header
- REST API: pass either
header.url(public http(s) URL) orheader.base64(data URI) — base64 is re-hosted server-side automatically. - MCP:
header.urlonly — base64 is not supported over MCP.
There is no
LOCATION header.Body
- Up to 1024 characters.
- Variables written as
{{nome}}(named style). - The body must not start or end with a variable.
- Emojis and multiple variables allowed.
Footer
Static text up to 60 characters. No variables.Buttons
Up to 10 buttons total; quick-reply and CTA buttons can be mixed.- Dynamic URL button: URL ends with a variable (e.g.
https://loja.com/promo/{{link}}) — one variable max, never in the domain. Sample value goes inexamples. - Copy-code: value goes on the button as
example(array, e.g.["PROMO10"]), alphanumeric only, up to 15 chars. Not for PIX keys or e-mails — put those in the body as a{{variable}}instead. - Buttons are allowed together with a video or document (PDF) header.
Variables & examples (required)
When creating/updating via REST or MCP you must include anexamples object mapping every variable used (body + header text + dynamic URL) to a real sample value. The copy-code value is the only exception (it lives on the button).
GET /v1/templates/{id} returns all detected keys in the top-level variables array (a string[]) — supply all of them in variables on send. There is no latestVersion object in the public API response.
Character limits
Create via REST API
bodymay be an object (recommended), a JSON string, or plain text (body-only templates).- Edit with
PUT /v1/templates/{id}(same shape); remove withDELETE /v1/templates/{id}(also deletes from Meta for Meta templates; returns{ deleted: true, id }). GET /v1/templates/GET /v1/templates/{id}returnsource(META|PILOT_STATUS),metaStatus(APPROVED|PENDING|REJECTED|DISABLED|null),metaLanguage, andsendable— on a Meta number onlyMETAtemplates withmetaStatus: "APPROVED"are sendable.
Approval
- Meta numbers: templates are submitted to Meta for review (“Submit to Meta” in
/templates, or on save). Categories, language and status follow Meta’s rules. - Unofficial (Pilot Status web) numbers: templates are created locally and immediately usable — no approval step.
Not supported
FLOW, LOCATION (header or button), CAROUSEL, CATALOG/MPM, LIMITED_TIME_OFFER, OTP autofill/one-tap/zero-tap, VOICE_CALL buttons, and the NAMED parameter_format.
Submit & rejection errors
Link/URL buttons accept a single variable that must be at the end of the URL and never in the domain; call buttons need the country code (e.g.+55).
Checked before submitting to Meta
API-side validation
Meta rejected the submission
Rejected after review
Blocks when sending (even approved)
Common error when sending
404 — template without an approved version (doesn’t exist for the key, or Meta template has no approved version yet).