SendrinSendrin Docsv1.0 (Current)
Channels

WhatsApp Messaging

Enterprise WhatsApp Business messaging via Meta Cloud API with template mapping and mandatory opt-in validation.

Dispatch high-engagement notifications via the official Meta Cloud API WhatsApp adapter.

⚡ Integrate with AI

1. Prerequisites & Meta Cloud Setup

WhatsApp Business requires strict template and user-consent compliance enforced by Meta:

  1. WhatsApp provider: Connect your WhatsApp Business number on the Providers page of the Sendrin Console, either with one-click Meta signup or through your Twilio account. Through Twilio, every WhatsApp template also needs its Twilio Content SID, and WhatsApp OTP isn't available. See Bring Your Own Provider.
  2. Approved Meta Templates: Create your message templates in Meta Business Suite (e.g. shipping_update_v2). Sendrin links your event template to the approved Meta template name.
  3. Mandatory Opt-In: Meta policy mandates explicit user consent. Sendrin keeps a consent ledger: a WhatsApp send is refused with 422 whatsapp_opt_in_required until the recipient has an active opt-in (see "Recording consent" below).
  4. Template category: every WhatsApp template's content must include category (marketing, utility or authentication), matching the category Meta approved for that template. Meta prices conversations by category; messages through your own provider are billed by Meta or your provider, not with Sendrin credits.

2. Dispatching a WhatsApp Message (POST /api/v1/notifications)

Send your notification with channel: "whatsapp". In the recipient object, provide the recipient's E.164 phone number and your internal consent tracker in opt_in_reference.

curl -X POST "https://api.sendrin.com/api/v1/notifications" \
-H "Authorization: Bearer sendrin_a1b2c3d4e5f6.xY7z..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: e6c1d420-5c3a-4467-872f-52eb321d2345" \
-d '{
  "event_key": "shipping_update",
  "channel": "whatsapp",
  "recipient": {
    "phone": "+14155552671",
    "opt_in_reference": "optin_checkout_202609"
  },
  "data": {
    "customer_name": "Taylor",
    "tracking_code": "TRK-98174"
  }
}'

3. Asynchronous Acceptance Response (202 Accepted)

Like all asynchronous channels in Sendrin, the API validates the payload, checks required recipient fields and JSON schema compatibility, and returns 202 Accepted:

Response
202 Accepted
{
"id": "notif_01HXYZ99AA88BB77CC66DD55EE",
"application_id": "app_01HXYZ11223344556677889900",
"event_key": "shipping_update",
"channel": "whatsapp",
"recipient": {
  "phone": "+14155552671",
  "opt_in_reference": "optin_checkout_202609"
},
"event_data": {
  "customer_name": "Taylor",
  "tracking_code": "TRK-98174"
},
"metadata_json": {},
"locale": "en",
"variant": "default",
"priority": 5,
"status": "pending",
"correlation_id": null,
"scheduled_at": null,
"next_attempt_at": "2026-09-16T02:00:00Z",
"failure_code": null,
"created_at": "2026-09-16T02:00:00Z",
"updated_at": "2026-09-16T02:00:00Z"
}

4. Meta Webhooks & Delivery Receipts

Which callback URL you give Meta depends on whose Meta app the number is connected through:

  • Connected with "Connect WhatsApp" (Sendrin's Meta app): in Meta's App Dashboard, WhatsApp, Configuration, set the callback URL to https://<your-api>/api/v1/callbacks/meta/shared and the verify token to the value of SENDRIN_META_WEBHOOK_VERIFY_TOKEN, then subscribe to the messages field. Sendrin verifies every call's X-Hub-Signature-256 with the Sendrin Meta app secret and finds your provider from the WABA and phone-number ids in the payload.
  • Your own Meta app (manual provider): post to POST /api/v1/callbacks/meta/{provider_id} (the provider_id you registered), verified against that provider's app secret. Meta also runs a one-time GET /api/v1/callbacks/meta/{provider_id} verification challenge when you register the URL.

Either way, sent, delivered and failed receipts update the notification; a read receipt is recorded but never regresses a message already marked delivered. If a recipient replies STOP (as the whole message), their consent is revoked (see "Recording consent").

  • Customer Webhooks: To forward WhatsApp delivery receipts to your systems, subscribe to the notification.delivered event in Outbound Webhooks.

5. WhatsApp-Specific Error Codes

Status CodeError CodeDescription & Solution
422 Unprocessablewhatsapp_opt_in_requiredThe recipient has no active, recorded WhatsApp consent. Record one with POST /api/v1/whatsapp/opt-ins (your application API key) before sending. See "Recording consent".
422 UnprocessableWHATSAPP_OPT_IN_REQUIREDThe recipient payload is missing opt_in_reference. Add consent reference metadata.
422 Unprocessableinvalid_recipientThe phone number does not conform to E.164 format.
409 Conflicttemplate_not_approvedThe template mapped in Sendrin is pending or rejected in Meta Business Suite.
404 Not Foundevent_not_foundThe requested event_key does not exist or is inactive.

Record consent at the moment the customer opts in, with the same API key you send with (notifications:send):

curl -X POST "https://api.sendrin.com/api/v1/whatsapp/opt-ins" \
  -H "Authorization: Bearer $SENDRIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phone_e164": "+14155552671", "source": "checkout", "reference": "order-42"}'

source is one of checkout, web_form, ivr, import. If the recipient replies STOP (or unsubscribe, opt out, optout as the whole message), Sendrin revokes their consent and remembers it: recording a new opt-in afterwards needs an evidence_url from a fresh opt-in (not an import), otherwise the API returns 409 whatsapp_recipient_stopped.

7. WhatsApp OTP

Authentication messages use your approved Meta Authentication template (SENDRIN_WHATSAPP_OTP_TEMPLATE_NAME, default otp_code). Meta Authentication templates (copy-code or one-tap) take the code in the body and again in the button, and Sendrin sends both; set SENDRIN_WHATSAPP_OTP_TEMPLATE_BUTTON=false only for a legacy body-only template.

On this page