Appearance
Bulk SMS
The Bulk SMS module lets a tenant build recipient lists, save reusable message templates, and send SMS campaigns out through the Panacea Mobile gateway. It keeps a full send log and a synced inbox for replies (including automatic opt-out detection), and gives admins a place to manage do-not-contact numbers, saved API endpoint definitions, and email-to-SMS sending addresses. It's used by admin staff running marketing or notification campaigns — sending is admin-only in every tenant.
What you can do
- Recipient Lists — create named distribution lists (e.g. "Active Customers", "Q3 Promo") with a description.
- List Numbers — drill into a list to add, view, and remove individual numbers; numbers are normalised to South African MSISDN format (
27XXXXXXXXX) as they're added, and duplicates/invalid numbers are rejected automatically. - Templates — save reusable message bodies under a name, ready to pick when sending a campaign.
- Sent Messages — a searchable log of every outbound SMS: recipient, body, delivery status (sent / failed / disabled / skipped), sender ID, and the gateway's message ID.
- Send Queue — the per-number queue view for messages in flight, showing queued / sent / delivered / failed status and any gateway error.
- Inbox — received replies, synced from Panacea, flagged automatically when a reply looks like an opt-out (e.g. "STOP").
- Opt-outs — a do-not-contact list; numbers here are always excluded from sends.
- API Endpoints — saved definitions of external SMS API calls (name, method, URL, params) for reference/integration use.
- Email-to-SMS — sending email addresses that map through to SMS delivery.
- Gateway status & balance — check whether Panacea is enabled/configured and (where the account permits it) the carrier credit balance.
Common tasks
Build a recipient list Open Recipient Lists → create a new list with a name and optional description. Drill into it (the "Numbers" link) and add numbers one by one or in bulk — each is normalised to
27XXXXXXXXXautomatically, and numbers already on the list are skipped rather than duplicated.Create a reusable template Open Templates → add a new template with a name and message body. Templates can be picked by name when sending a campaign instead of typing the message each time.
Send a campaign From the send action, choose a message (type one directly or pick a template — the template wins if both are given) and choose recipients: one or more Recipient Lists, and/or ad-hoc numbers. The system merges all recipients, de-duplicates them, strips any number on the Opt-outs list, then sends through Panacea. Every attempt — sent, failed, or skipped because the gateway is disabled — is written to Sent Messages.
Check delivery / gateway status Use the status/balance check to confirm Panacea credentials are configured and enabled before sending. Look up an individual message's delivery status using its gateway message ID from the Sent Messages log.
Review replies and opt-outs Open Inbox and sync to pull new replies from Panacea. Replies detected as opt-out requests are flagged; add a number to Opt-outs directly (with an optional reason) to make sure it's never included in a future send.
Manage do-not-contact numbers Open Opt-outs to add or remove numbers manually — useful for handling requests that come in outside of SMS (phone, email, etc.).
Data model
All tables are tenant-scoped (tenant_id) and live under the panel_sms_* prefix:
| Table | Purpose |
|---|---|
panel_sms_lists | A named recipient/distribution list. |
panel_sms_list_numbers | One number belonging to a list. |
panel_sms_templates | A reusable message template (name + body). |
panel_sms_optout | A number that must never be messaged (do-not-contact / STOP). |
panel_sms_messages | The outbound send log — one row per message sent, with status and gateway ID. |
panel_sms_inbox | Received (inbound) messages, synced from the gateway; flags opt-out replies. |
panel_sms_message_queue | Per-number queued sends and their delivery status. |
panel_sms_api | A saved external SMS API endpoint definition (name, method, URL, params). |
panel_sms_email | An email→SMS sending address mapping. |
Configuration & integrations
Sending goes through the Panacea Mobile HTTP gateway (app/services/sms_client.py). Credentials — gateway URL, username, password, and sender ID — come from the tenant's "panacea" Remote Connection, falling back to the PANACEA_SMS_URL / PANACEA_SMS_USERNAME / PANACEA_SMS_PASSWORD / PANACEA_SMS_SENDER environment settings if no overlay is configured. If credentials are missing, sends are silently marked disabled rather than erroring.
Numbers are normalised to South African MSISDN format before every send, and the module can tell mobile numbers apart from landlines/VoIP (06x/07x/081-085 = mobile; 01x-05x and 086/087 = fixed) so automatic sends only go to numbers that can actually receive an SMS. Manual sends typed directly into a send form are not filtered this way.
API reference
Bulk SMS has a dedicated API beyond generic grid CRUD, mounted at /panel/sms (admin role required, tenant-scoped):
| Method & Path | Purpose |
|---|---|
GET /panel/sms/status | Whether the Panacea gateway is enabled and its configured sender. |
GET /panel/sms/balance | Carrier SMS credit balance from Panacea. |
GET /panel/sms/message-status/{message_id} | Delivery status of a sent message. |
GET /panel/sms/lists | List all recipient lists with number counts. |
POST /panel/sms/lists | Create a recipient list. |
PATCH /panel/sms/lists/{list_id} | Rename/update a list. |
DELETE /panel/sms/lists/{list_id} | Soft-delete a list. |
GET /panel/sms/lists/{list_id}/numbers | List numbers on a list. |
POST /panel/sms/lists/{list_id}/numbers | Add numbers to a list (normalised, de-duped). |
DELETE /panel/sms/lists/{list_id}/numbers/{number_id} | Remove a number from a list. |
GET /panel/sms/templates | List message templates. |
POST /panel/sms/templates | Create a template. |
PATCH /panel/sms/templates/{template_id} | Update a template. |
DELETE /panel/sms/templates/{template_id} | Soft-delete a template. |
GET /panel/sms/optout | List opted-out numbers. |
POST /panel/sms/optout | Add numbers to the opt-out list. |
DELETE /panel/sms/optout/{optout_id} | Remove a number from the opt-out list. |
GET /panel/sms/messages | Sent-message log (most recent first). |
GET /panel/sms/inbox | Stored inbound messages; ?sync=true pulls new ones from Panacea first. |
POST /panel/sms/send | Send a campaign — resolves message text (template or raw), gathers recipients from explicit numbers and/or lists, de-dupes, strips opt-outs, sends via Panacea, and logs every attempt. |
The Send Queue, API Endpoints, and Email-to-SMS screens (sms-message-queue, sms-api, sms-email) are not covered by the dedicated API above — they're served through the generic grid CRUD routes (GET/POST/PUT/DELETE /grid/{slug} and /grid/{slug}/data), the same pattern used by every other admin grid in the platform.