POST /v1/messages. The type field decides the shape of the rest of the body. It defaults to text.
The 24-hour window
This governs everything else on this page.Window open
The contact messaged you within the last 24 hours. Send anything — free-form text,
media, interactive.
Window closed
Only an approved template will go out. Free-form sends are
refused.
Addressing a recipient
By phone number, in E.164:"type": "group_id" (see Group chats). Contacts who adopt a WhatsApp username may only have a BSUID; see Identity, privacy and data.
Types
- Text
- Template
- Media
- Location
- Contacts
- Interactive
- Reaction
Replying to a specific message
Quote the message you are answering, so it threads in the recipient’s client:Service window
Free-form messages only land within 24 hours of the contact’s last inbound message. Outside that window, send a template.GET /v1/contacts/{contact} includes service_window so you can choose the right message type before sending:
state is open, expiring (less than two hours left) or closed. If you send anyway and the window is closed, the refusal carries code: customer_service_window_closed. See Errors.
Scheduling
Addsend_at and the response becomes 202 with a scheduled id instead of a sent message:
ttl_seconds drops the message if it could not be sent within that window — better than a reminder arriving six hours late. List with GET /v1/messages/scheduled and cancel with DELETE.
How send_at is interpreted
There is no separate timezone field. The instant is taken from the string you send:
These three schedule the same instant (09:00 India Standard Time):
Z.
Responses return send_at as ISO 8601. Convert to the viewer’s timezone at display time; do not assume it comes back in the offset you sent.
LazyApp does not offer profile “queues” that drip-feed posts into recurring slots. For a batch of reminders, compute each send_at yourself (or stagger in your worker) and create one scheduled message per send.
Statuses and webhooks for scheduled vs sent messages are covered in Message lifecycle.
Confirming a send
Fetch any message by uuid withGET /v1/messages/{uuid}. Prefer webhooks in production; the GET is for confirmation and debugging.
Metadata
Attach up to 20 string values. They come back on webhooks, which makes reconciliation easy without a lookup table:Direct send
Numbers enrolled in Meta’s direct-send programme can sendutility and authentication content without a pre-approved template, via POST /v1/messages/direct-send. Marketing is not eligible. Check capabilities before relying on it. See Direct Send for buttons, media headers and business-named templates.