MessagePipedocs
Guides/Channels

WhatsApp

WhatsApp Cloud API as a chat-channel provider, credentials, message types, the 24-hour session rule.

WhatsApp is not its own channel. It is a provider delivered over the chat channel, using Meta's Cloud API. You send WhatsApp messages through the chat send endpoint (POST /v1/chat/send) and select WhatsApp by configuring it as your chat provider. The integration is straightforward, but the business rules (24-hour sessions, approved templates, opt-in) are strict and worth reading once.

The chat channel also supports Telegram, Signal, and WhatsApp via Twilio (an alternative to the Cloud API). See Providers for the credentials each one needs.

Credentials

phone_number_id:  123456789012345
access_token:     EAAGm0PX… (system-user permanent token)

Optional config.app_secret enables HMAC verification of the inbound webhook (strongly recommended in production).

Recipient

"to": "16505551234"     // no '+', no dashes

E.164 minus the leading +. Yes, that's what Meta wants.

Sending (free-form text)

Because WhatsApp rides the chat channel, sends go to POST /v1/chat/send with the chat body shape. The body is flat: there is no content wrapper, no channel field, and no recipient field. The number goes in to.

curl https://api.dev.messagepipe.dev/v1/chat/send \
  -H "Authorization: Bearer mp_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "to": "16505551234",
    "body": "Hi Maya! Your order #1234 has shipped."
  }'

To render a stored template, pass template and a data object of variables instead of body:

{
  "to": "16505551234",
  "template": "shipping-update",
  "data": { "order_id": "1234" }
}

A successful send returns 202 Accepted:

{
  "id": "msg_01HZ...",
  "status": "queued",
  "channel": "chat",
  "template_id": null,
  "queued_at": "2026-06-23T12:00:00Z",
  "_links": { "self": "/v1/sends/msg_01HZ..." }
}

The channel is chat (WhatsApp is the provider underneath). The identifier is id. Poll GET /v1/sends/{id} for status. Optional on any send: scheduled_for (RFC3339) and idempotency_key (or the Idempotency-Key header); idempotency is optional.

The 24-hour session rule

You may send a free-form message to a user only if they sent you a message in the last 24 hours. Outside that window, your only option is an approved Message Template (greeting, OTP, shipping update, etc.).

Templates are approved by Meta out-of-band. Reference an approved template by name through the template field on the chat send (with any variables in data), exactly as shown above.

Delivery events

A send moves through queued -> sent -> delivered | bounced | failed. The Cloud API webhook streams status updates that MessagePipe maps onto these canonical statuses:

WhatsAppCanonical
sentsent
delivereddelivered
failedfailed

MessagePipe does not emit opened/clicked events, even though WhatsApp itself reports read receipts. Read the current status with GET /v1/sends/{id}.