Common workflows
SMS, email and failover
Send by SMS and email next to WhatsApp, and let a notification fall back from one channel to the next.
In a nutshell
Set up SMS (Arkesel by default, or Hubtel, under a sender ID - optionally with the business's own Arkesel key) or email (Resend, from an address on a verified domain) per business, then send with channel sms or email. A notification tries its channels in order - WhatsApp, then SMS, then email - and moves on when a channel cannot be used or its message fails.
SMS and email
PaalTech's SMS and Resend accounts send for every business, so there is nothing to connect:
- SMS - Set up SMS or email with a
sender_idand, if you like, aprovider:arkesel(the default) orhubtel. Each business uses one; call again to switch. A business's own sender ID must first be approved by that provider. Arkesel reports delivery back to PaalChat; Hubtel's delivery is checked for two days after sending. - SMS with the business's own Arkesel account - pass its key as
arkesel.api_key. PaalChat checks it with Arkesel (invalid_provider_credentialsif Arkesel refuses it), stores it encrypted and never returns it - the connection showsown_key: true. The business then pays Arkesel itself. Send"arkesel": {"api_key": null}to go back to PaalTech's account. - Email - set it up with a
fromaddress on a domain PaalChat sends for, and optionallyfrom_nameandreply_to. Delivery, bounces and spam complaints come back from Resend; bounced and complaining addresses go on the business's suppression list.
{"provider": "arkesel", "sender_id": "PRESEC", "arkesel": {"api_key": "the-school's-arkesel-key"}}
Then send with Send message and channel:
{"channel": "sms", "to": "+233241234567", "type": "text", "reference": "closing-sms-1",
"text": {"body": "Presec: school closes at 1pm today."}}
{"channel": "email", "to": "parent@example.com", "type": "text", "subject": "Report cards",
"text": {"body": "Report cards are ready at the school office."}}
SMS and email are always business-initiated, so the suppression list, consent, preferences
and quiet hours apply, like WhatsApp templates. message.status callbacks carry channel.
Notifications with failover
Send notification sends one notification on the first channel that takes it:
{"contact_id": 41, "reference": "closing-2026-10-02",
"channels": ["whatsapp", "sms", "email"],
"whatsapp": {"template": {"name": "school_closing", "language": "en_US"}},
"sms": {"text": "Presec: school closes at 1pm today."},
"email": {"subject": "School closes early", "text": "School closes at 1pm today."}}
A channel is passed over when there is no content or address for it, the business has not
set it up, its provider is unavailable, or the send is refused. If the message then fails -
for example the number is not on WhatsApp - the next channel is tried. A message whose fate
is unknown (the provider's answer was lost) never moves on, because it may already have
arrived. notification.updated says how it
ended, and Get notification lists every attempt.
Provider health
Get provider health says whether Meta, Arkesel, Hubtel and Resend work right now; the status page shows the same.