Every SMS that leaves your gateway follows the same path: it enters the queue, the gateway chooses a phone and a SIM that can send it right now, the phone hands it to the carrier, and its status follows what happens next. This page explains how to send, how to follow what you sent, and what the gateway does on its own when something goes wrong.
The ways to send
| Way | Where | Typical use |
|---|---|---|
| Quick send | Quick send screen | One message to one number, a small group or a pasted list |
| Reply | Conversations screen | Answer a correspondent in their thread |
| Campaign | Campaigns screen | One message to a whole group, paced, with statistics |
| API | POST /messages |
Your own software sends: order confirmations, codes, reminders |
| Automatic reply | Rules screen and Settings > Auto-responder | The gateway answers by itself when a message matches a rule |
They all share the queue, the routing, the quotas and the retries described below. Campaigns are the only traffic held by the night and Sunday pauses.
See also: Conversations, Campaigns, Automation and the API guide.
Quick send
Quick send sends one message, now or later, to one or several recipients.
Choose the recipients
Pick one of the three modes under Recipients:
| Mode | What you enter |
|---|---|
| Single number | One number in international format, for example +261341234567 |
| Contact group | A group of your directory. Contacts who opted out are left out automatically |
| Pasted list | One number per line, copied from a spreadsheet or another tool. Commas and semicolons also separate numbers |
Numbers are read in international format: a leading + followed by the country code. A number
written with 00 instead of + is accepted and converted, and spaces, dots, dashes and parentheses
are ignored.
A number written the way it is dialled locally (0386231963) is accepted too, as soon as you have
set the local number prefix in Settings, Reception: the gateway completes it into
+261386231963 before sending. Without that prefix it is not recognised, because guessing a country
would file the message under the wrong one. The same rule applies to the contact form, to the
automation tester and to the to field of the API.
As you type, the screen counts valid recipients and the lines ignored, format not recognised. The same number pasted twice is sent only once.
In Contact group mode, the screen reads the whole group before you send, however many members it has, and shows the real number of recipients, plus the opted-out contacts left out. The Send button waits until the count is done. If the group cannot be read, a message says so with a Retry button.
Limits. A quick send takes at most 500 recipients, a whole group included. Beyond that, the screen says so (for a group: "This group has 1,250 contacts, more than the 500 recipients a quick send takes"), refuses to send and suggests a campaign, which is built for large sends: it paces the traffic, respects the night pause and gives you statistics. Nothing is ever sent to only part of a group.
Write the message
The counter under the message shows the number of characters, the number of SMS it will cost and the encoding:
| Encoding | When | One SMS holds | Split into parts of |
|---|---|---|---|
| GSM-7 | Only plain Latin letters, digits and common punctuation | 160 characters | 153 characters |
| Unicode | As soon as one character is outside that set (emoji, some accented letters, non-Latin scripts) | 70 characters | 67 characters |
A long message is never refused: it is split into several SMS that the recipient's phone joins back together. But each part is billed by your carrier and counts against the daily quota of the SIM. The screen warns you beyond six SMS per recipient, and shows the total, for example "3 messages, 6 SMS in total".
Shorten and track links
Under the message, the Shorten and track links switch (off by default) replaces every address
starting with http:// or https:// by a short link served by your gateway, which counts the
clicks. The replacement happens when you click Send; the same address written twice gets one
link, shared by all the recipients. The screen tells you how many links will be made and how the
length changes (characters and SMS per recipient, before and after), and the counter and the total
cost are computed on the text with its short links. The links then appear in Short links. See
Short links.
Choose the phone and the time
| Field | Default | Effect |
|---|---|---|
| Sending device | Automatic | Automatic lets the gateway choose the phone and the SIM (see Routing). Naming a phone forces it: the message leaves from that phone or not at all |
| Send date and time | Empty (now) | Schedules the send. The date is read in the platform time zone, shown under the field, and must be in the future |
Click Send. The confirmation "N messages accepted by the gateway" means the messages are in the queue, not yet delivered. Recent sends, at the bottom of the screen, lists your last outbound messages with their live status.
A scheduled message waits in the queue with the status Queued and the mention "Scheduled for" its date. It leaves at that time, day or night: the night pause does not apply to it.
The queue
The Queue screen lists the messages and lets you relaunch those that did not leave. It opens filtered on Failed messages, since those are the ones that need you.
| Control | Use |
|---|---|
| Status filter | Show one status, or all |
| Device filter | Show the messages of one phone |
| Direction filter | Outbound, Inbound, or both |
| Search | Find a message by words of its content |
| Retry the selection | Tick messages and relaunch them in one go |
| Delete the selection | Tick messages and remove them from the gateway, after a confirmation |
| The menu at the end of a row | Retry now and Delete, for that message alone |
| Export this view as CSV | Download the page you are looking at |
| Per page | How many messages a page holds: 25, 50, 100 or 200 |
| The page numbers | Go straight to a page you have already opened |
The columns show the Status, the Recipient, the Device that carried the message, the number of Attempts, the creation date and the Reason of a failure or a cancellation. On a phone the table scrolls sideways, and the row menu stays pinned to the right edge so it is always within reach.
Moving through the pages
The bottom of the screen shows how many messages a page holds, which messages you are looking at, and the page numbers. Changing a filter or the page size takes you back to the first page. A page you have already opened comes back instantly, without asking the gateway again.
The queue is read page by page rather than counted first, which keeps a long history fast to open: page numbers appear as you go, and the last page is not known in advance. The next arrow fetches one more page, and the dots at the end of the numbers mean there is more after them.
Ticking messages on one page and moving to another keeps your selection: the count next to Retry the selection is what you have ticked in total, across the pages you visited. Per page is remembered in this browser, for your account.
Retry now is offered on a message that failed, or that a SIM quota or a pause is holding back. It is greyed out on the others, and says why: a message already handed to a phone must not be sent twice.
Deleting removes the message from this gateway for good: the queue, its conversation, the history, the searches and the exports. A message still waiting is cancelled first, so it never leaves afterwards. An SMS already handed to your carrier cannot be taken back.
The Reason is a plain sentence in your language, the same one the conversation and the
activity log show, for example "The SIM had no network signal." or
"Withdrawn before leaving: its campaign was cancelled.". Hover it to see the technical code
(NO_SERVICE, CAMPAIGN_CANCELLED...), the one the API returns in errorCode. A code the dashboard
does not know yet, reported by a newer version of the phone app, is shown as "The phone or the
gateway reported an error (CODE).".
Under the Device, a message a SIM refused says so: "SIM 1 of Front desk refused". Hover it to read why each SIM refused. The line stays on a message that finally left, so you can see which SIM turned it away and which one carried it. See When a SIM refuses the message.
When messages are waiting for a SIM daily quota, a banner at the top says how many, with an Edit quotas link to the Devices screen.
A Queued message that waits for the pace of its SIMs says so under its status, with the time of its next try: "Waiting for the SIM cadence, next try at 14:32" (the minimum interval) or "Waiting for the per-minute limit of the SIMs". Nothing is wrong: it leaves on its own at that time.
The statuses
| Status | What it means |
|---|---|
| Queued | Accepted, waiting for its turn, for its scheduled time, for a new attempt, or for the pace of its SIM |
| Dispatched | Handed to a phone, which has not yet confirmed that the network took it |
| Sent | The phone confirms the carrier accepted the SMS |
| Delivered | The carrier confirms the SMS reached the recipient's phone |
| Failed | The message gave up. The Reason column says why. It can be relaunched |
| Quota reached | Every SIM that could carry it has spent its daily quota. It leaves at midnight UTC, or as soon as a quota is raised |
| Paused | A campaign message held by the night or Sunday pause. It leaves when the pause ends |
| Cancelled | Withdrawn before leaving, for example because the recipient opted out in the meantime. It cannot be relaunched |
Sent is not Delivered. "Delivered" depends on a delivery receipt from the recipient's carrier. Some carriers do not send them, or send them late: a message can stay Sent although it was received. A negative receipt, on the other hand, is final: the message moves to Failed.
Retries
When a send goes wrong, the gateway does not give up at once. What it does depends on the cause:
| What happened | What the gateway does | Counts as an attempt |
|---|---|---|
| A SIM refuses the SMS (no credit, no signal, carrier refusal) | Tries the next SIM at once, following your routing priorities | No, until every eligible SIM has refused |
| Every eligible SIM refused this message | Waits, then starts over on the whole fleet | Yes, one for the whole round |
| The phone did not confirm within the acknowledgement timeout | Puts the message back in the queue and tries again | Yes |
| No phone can send right now (all offline or out of the pool) | Waits, then tries again | Yes |
| The phone carrying the message dropped offline | Puts the message back in the queue at once, for another phone | No |
| Every usable SIM reached its daily quota | Moves it to Quota reached until midnight UTC or until a quota is raised | No |
| Every usable SIM reached its per-minute limit | Keeps it Queued and sends it the next minute | No |
| No usable SIM has waited its minimum interval since its last SMS | Keeps it Queued and sends it as soon as the first SIM is free | No |
| A strict routing rule matches and none of its SIMs can send | Keeps it Queued and tries again every minute | No |
| The carrier returns a negative delivery receipt | Failed, final: the carrier gave its verdict | No new attempt |
| The recipient opted out after the message was queued | Cancelled | No |
When the attempts run out, the message moves to Failed. The number of attempts and the waits between them are set in Settings > Sending (see Options).
When a SIM refuses the message
A SIM with no credit left looks perfectly healthy from the gateway: its phone is online, its daily quota is untouched, and nothing says the carrier will turn the message away. You only learn it when the send fails.
So the gateway remembers which SIM refused this message, and sends it from the next one right away, without waiting for the retry delay. Your routing priorities do not change: a phone you named in the send is still the only one used, a reply still keeps the number of the conversation, a prefix rule still tries its SIMs in your order, and a rule set to Wait for these SIMs still never leaves through another SIM. Only the SIM that just refused is skipped, for this message.
Trying five SIMs is one attempt, not five. Otherwise a fleet of five SIMs would burn the whole retry budget in a second. This holds even when you switched Retry failed messages off, or set Max attempts to 1: one attempt is one sweep of your SIMs, so a dead SIM never costs you the message. When every SIM that could carry the message has refused it, the message spends one attempt, waits the usual delay, and forgets the refusals: a SIM may have been topped up in the meantime, and it gets its turn back.
A refused SIM keeps its daily allowance. The daily counter is charged when the message is handed to the radio, but a SIM that turned it down sent nothing, so the gateway gives the unit back. One SMS costs one unit of daily quota on the SIM that actually carried it, however many SIMs it had to try first.
Some failures are not about the SIM: a malformed message, or a recipient every SIM refuses. Those do not sweep your fleet, because the same refusal would come back from every SIM and would hide the real cause. They wait and try again as before.
What you see: the Queue shows, under the device of the message, which SIM refused and, on hover,
why. A message that keeps saying "SIM x of phone y refused" with GENERIC_FAILURE is usually a SIM
to top up. The API returns the same list in the refusedSims field of the message.
In the API, the errorCode field of a failed or cancelled message gives the reason. The
Reason column shows the same codes as sentences:
errorCode |
Set by | Meaning |
|---|---|---|
DEVICE_OFFLINE |
Gateway | No phone could carry the message before its attempts ran out |
MAX_ATTEMPTS_REACHED |
Gateway | Every attempt was spent, typically on phones that never confirmed |
DEVICE_ERROR |
Gateway | The phone reported a failure without saying why |
DELIVERY_FAILED |
Gateway | The carrier returned a negative delivery receipt |
CAMPAIGN_CANCELLED |
Gateway | Cancelled: the campaign it belonged to was cancelled before it left |
CONTACT_BLACKLISTED |
Gateway | Cancelled: the recipient opted out before it left |
NO_SERVICE |
Phone | The SIM had no network signal |
RADIO_OFF |
Phone | The phone's mobile radio is off (airplane mode) |
GENERIC_FAILURE |
Phone | The carrier refused the SMS, most often for lack of credit |
NULL_PDU |
Phone | The phone could not encode the message |
RADIO_ERROR_<n> |
Phone | Another radio error; n is the error number Android gave |
NO_SMS_MANAGER |
Phone | This phone cannot send SMS, for example without a SIM |
INVALID_ARGUMENT |
Phone | The phone refused the message as malformed, often a wrong number |
PERMISSION_DENIED |
Phone | The app is not allowed to send SMS: grant the permission on the phone |
ORDER_EXPIRED |
Phone | The phone received the order too late to send it |
LIMIT_EXCEEDED |
Phone | Android throttled the app: too many SMS in too little time. Lower the per-minute limit of the SIM |
NO_DEFAULT_SMS_APP |
Phone | No default SMS app is set on the phone, and Android refuses to send without one. Set any messaging app as the default in Settings, Apps, Default apps, SMS app. It does not have to be Selfhostsms, which never needs that role |
INVALID_SMSC_ADDRESS |
Phone | The message centre number of this SIM is wrong: check it in the phone's SMS settings |
FDN_CHECK_FAILED |
Phone | The SIM only allows its fixed dialling numbers |
NETWORK_REJECT |
Phone | The carrier's network refused the message |
NETWORK_ERR |
Phone | The carrier's network failed the send. The phone reached it, and it answered with an error |
RADIO_NOT_AVAILABLE |
Phone | The phone's modem was not available; it usually comes back on its own |
NO_MEMORY |
Phone | The phone had no room left to store the message |
INVALID_SMS_FORMAT |
Phone | The carrier refused the format of the message |
OPERATION_NOT_ALLOWED |
Phone | The phone does not allow this send |
USER_NOT_ALLOWED |
Phone | This Android user profile is not allowed to send SMS |
SHORT_CODE_NOT_ALLOWED, SHORT_CODE_NEVER_ALLOWED |
Phone | The phone refuses premium short codes |
RADIO_ERROR_<n> is deliberately not translated into a sentence: the phone returned a code the app
does not know, and showing the number is more honest than inventing a cause. Treat any other code as
a generic failure: a newer version of the phone app may add some.
Relaunch by hand
A message that is Failed, Quota reached or Paused can be relaunched:
- from the Queue, by ticking it and clicking Retry the selection;
- from its conversation, with Retry under the failed message;
- through the API, with
POST /messages/{messageId}/retry.
A relaunched message leaves at once, without waiting for the next scheduled attempt. It is refused if the recipient opted out in the meantime. Delivered, Sent and Cancelled messages cannot be relaunched: that would send them twice.
Choosing the SIM. In the Queue, the menu at the end of a line also offers Retry from a chosen SIM, which lists every SIM in service. Ticking several messages gives the same choice for the whole selection, with From a chosen SIM next to Retry the selection. Pick one and the retry leaves from that card and no other: useful when you know why the previous one failed, a SIM out of credit or a card the operator has throttled.
Naming a SIM is binding. The router is given no other choice, so if that card cannot send, the message waits in the queue instead of leaving from somewhere else. Plain Retry, which replays the routing across your whole fleet, stays the one-click action and the right default.
SIM cadence: a minimum interval between two SMS
You can make each SIM wait a minimum number of seconds between two SMS, in Settings > Sending, field Minimum interval between two SMS per SIM, in seconds. A SIM that sends at a steady, human pace looks less like a spam source to its carrier than one that fires a burst.
How it works.
- It applies to every SMS, whatever its source: API, quick send, campaign, conversation reply, automatic reply, alert by SMS, and retries.
- The interval is counted from the moment the gateway hands the SMS to the phone, not from the phone's confirmation or the delivery receipt.
- You never have to wait for anything: you can send 50 messages at once, they are all accepted, wait in the queue as Queued, and leave on their own, one after the other, as soon as their SIM is free. The Queue screen shows them as "Waiting for the SIM cadence" with the time of their next try.
- Each SIM has its own clock. A SIM that waits never holds back another SIM, not even the second SIM of the same phone: with two SIMs and 30 seconds, two SMS leave every 30 seconds.
- A message addressed to a given phone (
deviceId) keeps it while it waits. - Waiting spends no attempt. A retry after a failure also waits for the interval if needed.
- The acknowledgement timeout starts when the SMS is handed to the phone, so a message waiting for its SIM never times out in the queue.
- The gateway checks the queue every two seconds: a message leaves within about two seconds after the end of the interval.
- Messages waiting for their SIM are sent in order. There is no priority: an alert waits like any other SMS, but a message that arrives while others wait takes the next free slot.
A SIM with its own value. In Devices, the pencil next to a SIM opens a dialog where
Own interval for this SIM replaces the setting for that SIM only (Superadmin). 0 means no wait
on that SIM, even when the setting asks for one; turning the switch off makes the SIM follow the
setting again. A new value applies to the next SMS; messages already waiting keep their time.
How it combines with the other limits. Each limit must allow a send; the strictest one wins.
| Limit | Where | What it caps |
|---|---|---|
| Minimum interval between two SMS per SIM | Settings > Sending, or per SIM in Devices | The gap between two SMS on one SIM |
| Messages per minute and per SIM | Settings > Sending | The number of SMS on one SIM in one minute |
| Pace and Wave size of a campaign | Each campaign | How fast the campaign releases its messages, all SIMs together |
| Daily quota of the SIM | Devices | The number of SMS on one SIM in one day (midnight UTC) |
Examples: with an interval of 10 seconds, a SIM sends at most 6 SMS a minute, so a per-minute limit of 6 or more changes nothing, and a lower one (say 3) still applies. A campaign at 60 messages per minute on two SIMs with an interval of 30 seconds actually sends 4 per minute: the interval is the limit. The daily quota still counts every SMS.
Set to 0, the default, the interval adds no wait: the gateway behaves as before.
Night and Sunday pauses: campaigns only
You can forbid campaigns from sending at night and on Sundays, in Settings > Sending, under Night pause for campaigns. A campaign message due during a pause moves to Paused and leaves automatically when the pause ends.
These pauses only hold campaigns. A quick send, an API call, a conversation reply or an automatic reply leaves at any hour: someone is waiting for it. A campaign is the only traffic nobody asked for at that moment, and a promotional SMS at three in the morning costs you more goodwill than it brings.
The hours are read in the platform time zone, set in the same tab. This time zone also governs the time of scheduled sends and how dates are shown in the dashboard. It is not the time of each phone: the header shows the local time of your phones and warns you when one lives at another hour (see Devices).
Follow the activity
The Dashboard shows how many messages left and arrived, in the Activity over the last 24 hours chart. Choose the period with the 24 h, 7 d, 30 d and 90 d buttons: the chart then shows one bar per hour, per six hours, or per day. Each bar stacks the outbound messages and the inbound ones, and the card gives the totals of the period. Hover or tap a bar for the exact times of the slot.
A message counts at its creation (when it was queued for an outbound one, when the phone received it for an inbound one), whatever its status since. The counts cover every message of the period, not a sample. Slots follow the platform time zone, daylight saving included. The chart refreshes every minute.
Through the API, GET /messages/stats?period=24h (or 7d, 30d, 90d) returns the same counts.
It never returns a message text or a number.
Options
The sending settings are in Settings > Sending, reserved to a Superadmin, and apply to the next message without any restart.
| Option | Default | Allowed values | Effect |
|---|---|---|---|
| Retry on failure | On | On or off | Off, the first failure is final: every message gets a single attempt, whatever Maximum number of attempts says |
| Maximum number of attempts | 4 | 1 to 10 | How many times a message is tried before Failed. Only the causes marked "Yes" in the retries table spend an attempt |
| Waits between attempts, in seconds, comma separated | 30, 120, 600, 3600 |
1 to 10 values, each from 1 second to 86,400 (one day) | The first value is the wait after the first failure, the second after the second, and so on. The last value applies to every attempt beyond the list |
| Device acknowledgement timeout, in seconds | 120 | 10 to 3,600 | How long a Dispatched message waits for the phone's confirmation before going back to the queue. Too short, and slow phones see their messages retried (and possibly sent twice); too long, and a silent phone holds messages longer |
| Messages per minute and per SIM | 0 (no limit) | 0 to 600 | Caps the pace of each SIM. A SIM at its limit is skipped by routing and the gateway uses another; if all are at their limit, the message waits for the next minute without spending an attempt. A burst of hundreds of SMS in a minute is what carriers flag first, well before the daily volume |
| Minimum interval between two SMS per SIM, in seconds | 0 (no wait) | 0 to 3,600 | The least time each SIM waits between two SMS, counted from the moment the SMS is handed to the phone. Messages wait in the queue and leave on their own; a busy SIM never holds back another one. A SIM can have its own value in Devices. See SIM cadence |
| Keep the same SIM for each conversation | On | On or off | On, every message to a correspondent leaves from the SIM that last exchanged with them, so that person always sees the same number; another SIM carries it only when that one cannot send. Off, each message is routed like a first contact and spread over the whole fleet. Turn it off when a SIM can no longer send (no credit, no coverage), so your messages stop coming back to it. See Routing |
| Time zone | UTC | Any time zone of the list | Hours of the night pause, meaning of Sunday, time of scheduled sends, display of every date in the dashboard. It does not move the daily quota reset, which stays at midnight UTC |
| Night pause for campaigns | Off | On or off | On, campaign messages due between From and To are held as Paused |
| From, To | 20:00, 07:00 | Hours and minutes; the pause may cross midnight, the two must differ | Start and end of the night pause, in the platform time zone |
| Pause campaigns on Sunday | Off | On or off | On, campaign messages are held the whole Sunday, from midnight to midnight in the platform time zone |
Other settings that change what you send:
- the daily quota, the in service switch and the own interval of each SIM, in Devices (see Devices);
- the routing rules, which choose the SIM by number prefix (see Routing).
API fields of POST /messages
| Field | Default | Effect |
|---|---|---|
to |
Required | One number, or a list of 1 to 500 numbers in international format, or written the way they are dialled locally when the local number prefix is set |
body |
Required unless templateId |
The text. No length limit: a long text is split into several SMS |
templateId, variables |
None | Use a saved template and fill its variables (see Templates) |
deviceId |
None (automatic) | Forces the phone. The message leaves from it or not at all; the routing rules are not consulted |
simSlot |
None (automatic) | 0 or 1: the SIM of that phone |
scheduledAt |
None (now) | Date and time of the send, in the future |
shortenLinks |
false |
true replaces every http:// or https:// address of the text with a tracked short link before queuing, like the Shorten and track links switch (see Short links) |
The Idempotency-Key header protects a single-recipient send against being queued twice when your
software replays a request after a network error.
The request is checked as a whole before anything is queued: if one recipient is invalid or opted out, the request is refused and nothing is sent, so you always know what to replay.
Troubleshooting
| Symptom | What to check |
|---|---|
| Messages stay Queued | Is a phone Online in Devices, and in the routing pool? Is it a scheduled message? Does a strict routing rule wait for a phone that is offline? |
| Messages stay Queued with "Waiting for the SIM cadence" | The minimum interval between two SMS per SIM is on. They leave on their own, one per SIM and per interval. Lower it in Settings > Sending, or give a SIM its own value in Devices |
| Messages go to Quota reached | Every usable SIM spent its daily quota. Raise a quota in Devices, or wait for midnight UTC |
| Campaign messages are Paused | The night or Sunday pause is on. They leave at the end of the pause |
| Messages stay Dispatched for a while, then retry | The phone does not confirm: check its connection and its battery settings |
Many Failed with NO_SERVICE or GENERIC_FAILURE |
The SIM has no signal, no credit, or its carrier refuses: check it in the phone |
| The Queue repeats "SIM x of phone y refused" | That SIM turns messages away. With GENERIC_FAILURE, top it up; the gateway already sends from the other SIMs meanwhile |
| Messages stay Sent, never Delivered | The carrier sends no delivery receipts. The message was most likely received |
| "This number has opted out." | The recipient sent STOP, or was opted out by hand. See Contacts and groups |
| "The scheduled time must be in the future." | The date is in the past in the platform time zone. Check the zone shown under the field |