Sends a WhatsApp message to an existing contact, in one of two forms you
choose:
- Freeform: send
message. Only allowed while the contact is inside WhatsApp’s 24-hour
customer-service window (they wrote to your WhatsApp line in the last 24 hours). Outside
it, the call fails with 422 OUTSIDE_24H_WINDOW before the cap is touched or the telephony carrier is
called.
- Template: send
templateId and optional templateVariables. Works whether or not the
window is open, but the template must be approved. When both are sent, the template wins.
If you cannot know the window state, as with an AI agent, use POST /api/whatsapp/reach,
which picks the form for you.
The message goes out from the workspace’s ONLINE WhatsApp sender, preferring the line the
contact last wrote to so the reply stays in the same thread. status is the carrier’s initial status (usually queued). Delivery updates arrive later through the carrier’s status callbacks.
The message is not added to a conversation thread. To have it recorded, use
POST /api/conversations or POST /api/conversations/{conversationId}/messages.
Checks, in order: contact exists in the workspace with a whatsapp_number
(NO_WHATSAPP_NUMBER otherwise, even for an unknown contactId), compliance rules
(COMPLIANCE_BLOCKED), opt-out (CONTACT_OPTED_OUT), template or window, daily send cap
(DAILY_CAP_REACHED), then sender resolution (SENDER_NOT_REGISTERED).
Side effects. Sends a real WhatsApp message that WhatsApp bills to the workspace’s WhatsApp
account, since a template opens a business-initiated conversation. Consumes one unit of the
daily WhatsApp send cap: 1,000 per UTC day by default, 25,000 on plans with no monthly
limit. The unit is refunded if the telephony carrier rejects the send. Does not draw on the AI-message
allowance. Writes an audit entry.
Idempotency. Not idempotent. There is no dedup, so a retry after a timeout can deliver
the message twice. Treat a timeout as “possibly sent”.
Webhook events. audit.log_recorded for subscribers that selected it explicitly. See Webhooks.
Access
- Required scope:
write.
- Rate limit: Outbound — 20 requests/min per workspace, fail-closed, counted on every
/api/whatsapp request and the configuration-mutations limiter — 10 requests/min per workspace, shared with other configuration mutations. See Rate limits.
- Plan: Available on every plan. Requires a WhatsApp sender in
ONLINE status.