Discover the template
Templates are listed as Meta holds them, with the placeholders each one expects, so your code can discover what to send without opening WhatsApp Manager. The list is cached for five minutes.id is Meta’s id of that language of the template: GET /v1/whatsapp/templates/{template_id} reads it in full. managed is false for a key you create.
Send
Every placeholder the template declares is required, extra keys are refused, and values are strings of 1 to 1024 characters without newlines or control characters. Givelang when the template exists in more than one language.
202 Accepted. Meta has taken the message; the status arrives afterwards.
Text headers
A template whose text header has a placeholder lists it underplaceholders.header:
header.text, not in params. A header has one placeholder at most, and its value follows the same rules as a body value: 1 to 1024 characters, no newline.
header for a template without a header placeholder answers 422 invalid_params, and so does a missing one for a template that has it.
Image headers
A template can open with an image (its header is an image Meta reviewed with the template). Each message carries its own: give the image’s public link inheader.image.link. Meta fetches it when it sends, so it must answer at once with a JPG or a PNG of at most 5 MB.
https, at most 2048 characters, without spaces. A template that opens with an image and a send without header.image.link answers 422 invalid_params (`header.image.link` is required: this template opens with an image); an image for a template that does not open with one answers 422 invalid_params too. The field is optional for every other template, so existing integrations are unchanged.
Document headers
A template can open with a document, a PDF attachment: an invoice, a contract, an attendance sheet, a ticket (see Send a PDF attachment). Each message carries its own file: give its link inheader.document.link and, optionally, the name the customer sees in header.document.filename. Meta downloads the file from the link when it sends, so the link must open without a sign-in at that moment; for a file that holds personal data, a signed link that lives a few minutes is enough.
A template that opens with a document and a send without
header.document.link answers 422 invalid_params, and so does a link that is not https or is too long, a document for a template that does not open with one, or an image for a template that opens with a document. A header of another shape (document that is not an object, a link that is not a string, extra keys, text beside document) answers 400 invalid_request. The message is charged and recorded like any other send, with the link and the file name it carried. The whole flow, from the template to the send, is in Send a PDF attachment.
Video and location headers are not sent yet: such a template answers 422 unsupported_template with message media_header.
A named placeholder is at most 20 characters at send time: Meta approves a template with a longer name, such as {{subscription_start_date}}, then refuses every message from it. Such a template answers 422 unsupported_template with message long_placeholder_name, and nothing is sent or charged. Rename the placeholder ({{start_date}}) in a new template or an edit.
Marketing and opt-outs
A customer who turns off your offers inside WhatsApp is opted out the first time Meta refuses a marketing message to them (Meta’s error131050). From then on a template whose category is MARKETING to that number answers 422 consent_opted_out, and nothing is sent or charged. Utility and authentication templates still go: order news and codes are the service the customer asked for.
Authentication templates
An authentication template sends a one-time code from your own number (see Templates). It takes exactly one value,params.code: 4 to 15 letters or digits. Tawked puts the code in Meta’s text and on the button, so send no buttons and no header. The listing shows the template as "placeholders": { "kind": "named", "header": [], "body": ["code"], "buttons": [] }.
202 Accepted as any send:
code outside 4 to 15 letters or digits, any other key in params, buttons or header answers 422 invalid_params with message naming the field. Tawked does not check the code: comparing what the customer types is your code’s job. Only Meta receives the code; Notifications → Messages and its Tawked Chat conversation show •••••• in its place. For codes by SMS, with the check done for you, use Tawked Verify.
Statuses and webhooks
accepted then sent, delivered, read, or failed from any of the first three. Statuses arrive from Meta within about a minute, are applied in order and never go backwards. A message stops being tracked 48 hours after the send and keeps its last status.
Read the current state with GET /v1/whatsapp/messages/{id}:
message.* events, signed and retried exactly like verification.* events. Only the status reached is announced: a message that jumps straight to read gets one message.read. to is masked in webhooks the way the console shows it, so keep your own copy of the destination next to the returned id or your reference.