Creates a broadcast, records one message per recipient, atomically reserves
credit (prepaid), and queues it for delivery over the WhatsApp Business Platform. Status updates reach your registered webhook URL.
Required scope: send_whatsapp
Rate limit: 10 requests / 15 min / client
Status lifecycle: pending → enqueued → accepted → sent → [delivered | read | failed]
accepted is an internal acknowledgement from the upstream provider and does
not emit a webhook. The events you receive are sent, delivered, read,
and failed.
Template requirement
WhatsApp messages are template-only - templateName is required and must
reference an approved template owned by your client. Templates are
managed in the Teekrr dashboard and pass through the platform’s approval flow.
If your client does not have its own WhatsApp Business Account (WABA),
Teekrr falls back to the platform-default shared WABA automatically.
Variables
Template values are supplied as a single named map. There are no
per-component (header / body / button) arrays and no positional
parameters:
The keys are the {{name}} placeholders the template declares. Variable
names must start with a letter or underscore and contain only letters,
digits, and underscores.
The variables object is strict - it accepts templateParams and nothing
else. Sending header, body, button, headerImage, headerVideo,
headerDocument, or bodyParams is rejected with 400, not ignored.
Media headers and dynamic URL buttons are ordinary named variables.
Upload the asset via POST /whatsapp/upload-header-image, then pass the
returned url as the value of whatever the template named that variable:
In dynamic mode, variables is required on every recipientVariables row.
Variable completeness
Every variable the template declares must be supplied with a non-empty value -
an empty string or whitespace counts as missing. Placeholders are declared across the
template’s header text, media-header URL, body, and buttons.
A template with no declared variables accepts a request with no variables at all.
Missing values are rejected with 400 before any credit is reserved:
- Standard mode -
Template "<name>" requires values for: a, b. Declared variables: a, b.
- Dynamic mode -
Template "<name>" requires: a, b, with an errors array naming
the offending rows. Only the first 10 offending rows are reported, even when more fail.