Register WhatsApp consent
An approved template does not establish recipient consent. Your website’s backend must register the customer’s actual WhatsApp opt-in before requesting a welcome message. Call this endpoint only after the customer explicitly selects the WhatsApp checkbox; if they decline, skip both calls. Never put your API key in browser JavaScript.
Permissions and scope
Create a key in Settings → API with whatsapp:consent:write and whatsapp:send. Add whatsapp:templates:read to look up templates. Existing keys do not automatically gain the new permission. Consent is for WhatsApp messages from the authenticated merchant, across that merchant’s channels. Do not supply merchant_id, account_id, or phone_number_id to this endpoint.
1. Record the opt-in
Authorization: Bearer {YOUR_API_KEY}
Content-Type: application/json
Accept: application/json
Idempotency-Key: mehad-lead-123-consent
{
"to": "+966500000001",
"opted_in": true,
"occurred_at": "2026-09-05T09:30:00+03:00",
"evidence_reference": "mehad:lead:123",
"consent_text": "أوافق على تلقي رسائل واتساب من مهاد، ويمكنني إلغاء الاشتراك في أي وقت.",
"source_url": "https://mehad.example/lead"
}
All six fields are required. Replace the example with the customer’s number, original opt-in time, exact checkbox wording, actual form URL, and a durable unique submission reference. Store the original submission in your system. Nabbih encrypts this evidence at rest and appends a consent event to the existing recipient policy ledger; it does not create an inbox conversation or send a message.
to: international number, 8–15 digits, optional leading +. No local-format numbers.opted_in: literal JSON true. False, strings and numbers are rejected.occurred_at: ISO 8601 to whole seconds with timezone, such as the example or +00:00. Cannot be in the future; preserve it on retries.evidence_reference: 1–191 characters; starts with a letter or digit and contains only letters, digits, underscore, dot, colon or hyphen. Unique per merchant. Use an opaque reference without customer details.consent_text: exact text accepted by the customer, 1–4096 characters.source_url: HTTP(S) form URL, up to 2048 characters. Avoid sensitive query parameters.Idempotency-Key: required header, 8–255 characters. Persist one stable key per form submission.
{
"data": {
"consent_event_id": 123,
"created": true,
"has_consent": true,
"consent_revoked": false,
"suppressed": false
}
}
2. Request the welcome template
Proceed only after a successful consent response with has_consent true, consent_revoked false and suppressed false. For Mehad’s supplied configuration, use account 9 and template 9 (orderas, Arabic). Nabbih resolves the template’s name and language from its stored ID. The example assumes no body variables; supply parameters in template order when required by the approved template. If the account has multiple sending numbers, explicitly include phone_number_id.
Authorization: Bearer {YOUR_API_KEY}
Content-Type: application/json
Accept: application/json
Idempotency-Key: mehad-lead-123-welcome
{
"account_id": 9,
"to": "+966500000001",
"template_id": 9,
"parameters": []
}
HTTP 202 means queued, not delivered. An identical retry returns HTTP 200 and the same message_id with created false. Poll GET /api/v1/whatsapp/messages/{message_id} using the send permission to track the message. Template approval, account readiness and recipient policy are still checked at send time.
Retries, opt-outs and errors
Use separate persistent keys for consent and welcome. If a response is lost, retry the same endpoint with the same key and payload; do not generate a new timestamp or a new welcome key. Consent and message requests are separate: consent success followed by a send failure requires retrying the send, not creating new consent. Concurrent consent requests are serialized with ledger writes, and database uniqueness prevents duplicate receipts.
An identical consent retry returns the original event ID and the current consent/suppression state. It never grants consent again, including after a STOP message. A new request cannot override existing revocation or suppression, even with a newer opt-in timestamp; resolve those cases through the merchant’s existing consent review process. This API cannot unsuppress a recipient. Suppression or opt-out after registration can still block sending, including an already queued message.
- 401: missing or invalid key. 403: missing permission or unavailable merchant. 404: API access disabled.
- 422 validation errors: missing/invalid evidence or non-true opt-in.
idempotency_key_required: missing or invalid header. - 409
idempotency_conflict: consent key reused with changed evidence. - 409
consent_evidence_conflict: submission reference already registered under another key; use its original key and payload. - 422
recipient_consent_revokedorrecipient_suppressed: new registration blocked by an existing opt-out or suppression. - Send errors retain their existing behavior, including 422
idempotency_conflict. Never bypass a rejected or uncertain send by generating a fresh welcome key.