Skip to main content

Send Messages Guide

This guide shows how to send WhatsApp messages via the Pilot Status API. All sends go through a single endpoint:
Authentication uses the x-api-key: ps_... header (or x-api-key-id) with a number-scoped key — see API Authentication. There is no Bearer-token auth.
Sending from the dashboard Message page

You can also send from the dashboard Message page — it calls the same POST /v1/messages/send endpoint and shows a copy-ready curl.

The endpoint has three mutually exclusive modes: template send (templateId), free-form text (text), and direct media (media + mediaType). Full reference: POST /v1/messages/send.

Prerequisites

  1. A connected WhatsApp number (dashboard /numbers).
  2. An API key for that number (dashboard /api-keys).
  3. For template sends: a template created in /templates (Meta numbers require Meta approval).

1. Send a template message

The most reliable mode — works at any time, including outside the 24h window on Meta numbers.

2. Send free-form text

Send plain text with the text field (no templateId).
On Meta numbers, free-form messages only work within the WhatsApp 24h conversation window (i.e. after the recipient messaged you in the last 24 hours). Outside the window, the send fails asynchronously with META_OUTSIDE_24H_WINDOW in the message.failed webhook — use an approved template instead. Check whether the window is open before sending with GET /v1/service-window.
You can add up to 3 buttons (and, with buttons, a header/footer) to free-form messages — see the send reference.

3. Send direct media

Send an image, video, document, or audio on its own — provide media + mediaType, with no templateId and no text. An optional caption is supported for image/video/document (not audio or voice). Use mediaType: "voice" for a WhatsApp voice note (PTT) on any number; mediaType: "audio" arrives as an audio file on official (Meta Cloud API) numbers and as a voice note on unofficial numbers — see Audio and voice notes.
Base64 data URIs are accepted on Meta Cloud API and on unofficial (Pilot Status web) numbers. On unofficial numbers, Pilot Status uploads the decoded file to its own storage and sends the provider a URL; if that upload fails, the message fails with MEDIA_REHOST_FAILED. For stickers on unofficial numbers, use a public http(s) URL. Base64 goes up to 50 MiB decoded for a document and 16 MiB for every other type — send larger files by URL.

4. Track delivery

The 202 response returns an id. Persist it and:
  • Poll GET /v1/messages/{id} for QUEUED → SENT → DELIVERED → READ → PLAYED (or FAILED / CANCELED), or
  • Consume webhooks — the response id matches the id field in the message.sent, message.delivered, message.read, and message.failed events.

Next steps