WhatsApp is the most constrained channel Arsel offers, and every constraint comes from Meta rather than from Arsel. Understanding them up front saves a lot of debugging.
You cannot send free text
WhatsApp does not permit business-initiated free-text messages. Every message you send through the API is an approved template, referenced by name, with values filled into its placeholders.
That means the integration work happens before you write any code:
- Connect a WhatsApp Business account in the Arsel Dashboard under WhatsApp > Settings, and fund your WhatsApp balance.
- Create your templates under WhatsApp > Templates.
- Wait for Meta to approve each one. Approval is not instant and templates can be rejected.
- Send by template name.
A template you have not had approved is not sendable, no matter how simple its content.
Sending
curl -X POST "https://api.arsel.sa/v1/whatsapp/send" \
-H "Authorization: Bearer be_your_api_key" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: booking-5521-confirmation" \
-d '{
"to": "+966512345678",
"templateName": "booking_confirmation",
"language": "ar",
"parameters": { "booking_ref": "5521", "date": "12 March" }
}'
to is a single recipient in E.164 format — unlike email and SMS, this endpoint does not take an array.
Filling in parameters
What belongs in parameters depends on the template's category:
| Category | What to pass |
|---|---|
AUTHENTICATION | The one-time code as code. If the template has a copy-code button, the value is repeated into it automatically — you do not pass it twice. |
UTILITY | One entry per {{placeholder}} in the template body, keyed by placeholder name. |
MARKETING | Same as UTILITY, but subject to the recipient's marketing opt-out. |
language is requiredOmit language and Arsel resolves the template by name alone. If you have the same template name approved in more than one language, that is ambiguous and the request returns 409 Conflict. Send the language code explicitly whenever a name exists in multiple languages.
parameters is deliberately absent from every response. For an authentication template that field holds the one-time code, and an endpoint that read codes back out would turn a leaked API key into an account-takeover tool. If you need the code later, keep it on your side.
Delivery status
202 means the provider accepted the message, not that it arrived. Poll GET /whatsapp/:id:
| Status | Meaning |
|---|---|
queued | Accepted by Arsel, not yet handed to the provider |
sent | The provider accepted it and returned a message ID |
delivered | Confirmed delivered to the recipient's device |
read | The recipient opened the message |
failed | See failureReason |
read is not guaranteed to ever arrive — recipients can disable read receipts. Treat delivered as your success condition unless you have a specific reason not to.
Billing
Each message is charged at the rate for the destination country and template category. The charge is held when the message is accepted and settled from the delivery receipt. A message the provider rejects is not charged.
Reference
Send WhatsApp · List · Get