Guides
Message lifecycle
The states a message and a batch move through, and what you can rely on at each one.
How a message moves
Every message starts queued or scheduled and ends in exactly one terminal state. Terminal means terminal: a message that reaches one never transitions again.
| Value | Meaning |
|---|---|
SCHEDULED | Parked until its scheduled time. |
QUEUED | Waiting for the router. |
RETRY_SCHEDULED | A delivery attempt failed and another is scheduled. |
SUBMITTED | Handed to a provider, which has not yet returned a reference. A message stuck here is SMSend's problem, not yours. |
SENT | The provider accepted it and returned a reference. |
DELIVEREDTerminal | The handset confirmed receipt. |
FAILEDTerminal | Delivery failed. The reason is in failed_reason. |
EXPIREDTerminal | No delivery receipt arrived within 48 hours. |
REJECTEDTerminal | The provider or operator refused it. |
CANCELLEDTerminal | Dropped at send time, or cancelled with its batch. |
Why receipts cannot go backwards
Each status carries a rank, and a delivery receipt is applied only if it strictly increases that rank. Operators occasionally deliver receipts out of order, and without this rule a late "submitted" receipt would overwrite a message that had already been confirmed delivered.
This means you can trust a terminal status the moment you see it. It will not be revised later by a receipt that was in flight.
How a batch moves
A batch tracks the work as a whole. Only SETTLED means it is finished and the money is squared.
| Value | Meaning |
|---|---|
VALIDATING | Accepted but not yet priced or paid for. Only reachable on the asynchronous path, and expires after 30 minutes. |
SCHEDULED | Priced and reserved, waiting for its scheduled time. |
QUEUED | Priced and reserved, waiting for the router. |
SENDING | In flight. |
SETTLEDTerminal | Finished, with the money squared and any refund posted. |
REJECTEDTerminal | Every recipient was dropped before anything was reserved. |
FAILEDTerminal | Validation itself failed. |
CANCELLEDTerminal | Cancelled before or during sending, and refunded. |
Reading the counts
The counts object on a batch reports how many messages have ever reached each state. The failed figure aggregates failed, expired and rejected messages, because for reconciliation purposes those are one category.
Counts are cumulative, not current
These counters only ever increase. queued: 948 does not mean 948 messages are queued right now — it means 948 have been queued at some point. Do not compute what is in flight by subtracting them from each other.
Settlement
A batch settles when every message has reached a terminal state, or when 72 hours have passed since it was due to send and some messages are still stranded. Both cases produce a BATCH_SETTLED event; the trigger field tells you which one it was.
Settlement is the only moment a refund figure exists. SMSend reserves money for the whole batch up front and refunds the difference once at the end, so no single message can tell you what it cost or what came back — which is why per-message events deliberately carry no money fields at all.