Skip to content

How sending works

Every message type sent with POST /v1/{phone_number_id}/messages is accepted onto Hello’s send queue and dispatched fairly across your organization’s traffic, then delivered to WhatsApp by a worker.

Response When
202 Accepted with messages: [{ id, message_status: "queued" }] Default: the message is queued
200 OK with message_status: "sent" and wamid ?sync=true and WhatsApp accepted it within the wait

Keep the id and poll GET /v1/messages/{id} for the outcome. A queued message can still end up failed, for example if WhatsApp rejects the template parameters — a 202 is not a delivery guarantee.

Add ?sync=true to wait for the result in the same request:

Terminal window
curl -X POST "$HELLO_API_URL/v1/$PHONE_NUMBER_ID/messages?sync=true" ...
  • If the send finishes within 10 seconds, you get 200 with message_status: "sent" and WhatsApp’s wamid.
  • If it fails within that time, you get 422 with code SEND_FAILED.
  • If it takes longer, you still get 202 with message_status: "queued". Poll as usual.

sync accepts true/false, 1/0 and t/f.

Send an Idempotency-Key header to make retries safe: a retry with the same key returns the original message instead of sending a duplicate.

WhatsApp only lets a business send free-form messages to someone who has recently interacted with it. For each recipient, the window is open for 24 hours after the most recent of:

  • a message from the recipient to your number, or
  • a template message you sent to them.
Message type Needs an open window?
template No. Templates can start or re-open a conversation.
Every other type (text, image, video, audio, document, sticker, location, contacts, interactive, reaction) Yes

Sending a non-template message outside the window returns 403:

{
"message": "Cannot send text message outside 24-hour window; use a template",
"code": "OUTSIDE_24H_WINDOW"
}

To reach the recipient, send an approved template first.

Send to with a leading + and the country code, for example +919999999999 or +16505551234. A number without one is rejected with 400 VALIDATION_ERROR.

The response echoes your input in contacts[0].input and gives the normalized digits (no +) as contacts[0].wa_id. Sending, window checks and message history all key off the normalized number, so it doesn’t matter whether you always write the same recipient identically — Hello normalizes on the way in.

Your plan can limit what you may send, such as message volume, destination countries or template categories. A send your plan doesn’t allow is rejected with 403 before it’s queued. See plan errors.