Delivery reports, errors and troubleshooting
What happens to a message after it is accepted, how its final state is reported, and how to investigate messages that fail or arrive late.
Download this guide (PDF)Same content as this page, for offline reading and sharing.
Accepted is not delivered
A message passes through several stages: your system submits it, the provider accepts it, it is routed to the destination network, and that network tries to deliver it to the handset. The response to a submission only confirms the first step. The final result arrives later in a delivery report (DLR), also called a delivery receipt.
| Stage | What it means |
|---|---|
| Accepted | The provider has taken the message and returned an identifier. |
| En route | The message is queued or on its way to the destination network. |
| Delivered | The destination network reports that the handset received it. |
| Undeliverable or rejected | The network or provider could not or would not deliver it. |
| Expired | Delivery kept failing until the validity period ended, for example because the phone was off. |
| Unknown | No final result was reported. |
Delivery receipts over SMPP
In SMPP 3.4, the client asks for a receipt by setting registered_delivery in submit_sm. The receipt arrives later as a deliver_sm with the delivery-receipt flag set in esm_class. Many platforms put the result in the short message text using the informal format shown in an appendix of the specification, and also in optional fields such as receipted_message_id and message_state.
id:0123456789 sub:001 dlvrd:001 submit date:2610281430 done date:2610281431 stat:DELIVRD err:000 text:Your code is 1| stat value | Meaning |
|---|---|
DELIVRD | Delivered to the handset. |
ACCEPTD | Accepted on behalf of the recipient, for example by an operator system. |
EXPIRED | The validity period ended before delivery. |
UNDELIV | Undeliverable, for example an invalid or inactive number. |
REJECTD | Rejected, for example by policy or a firewall. |
DELETED | Deleted before delivery. |
UNKNOWN | No valid final state. |
The err value is network- or platform-specific. Ask your provider for its list rather than assuming a meaning.
Delivery reports over HTTP and webhooks
HTTP-based platforms report results in two ways: the client polls a status endpoint, or the platform sends each result to the client's own HTTPS address, called a webhook or callback URL. Webhooks avoid constant polling but need careful handling:
- Authenticate every call. Verify a signature, for example an HMAC-SHA256 of the timestamp and body using a shared secret (RFC 2104), before trusting the content.
- Reject old or repeated calls. Refuse requests whose timestamp is too old, and ignore events you have already processed.
- Answer quickly. Return a 2xx status as soon as the event is stored, and process it afterwards, so the sender does not retry unnecessarily.
- Expect retries, delays and any order. A report can arrive twice, late, or before your own system has saved the submission.
POST /hooks/sms-status HTTP/1.1
Host: your-app.example.com
Content-Type: application/json
X-Signature: t=1793197860,v1=<hex-hmac>
{ "id": "msg-0001", "status": "delivered", "done_at": "2026-10-28T14:31:00Z" }Errors at submission time
Some problems are reported immediately, in the response to the submission, rather than in a later receipt.
SMPP command status
Every SMPP response carries a command_status. Zero means success. Some standard SMPP 3.4 values:
| Value | Name | Usual cause and action |
|---|---|---|
| 0x00000008 | ESME_RSYSERR | System error on the server side. Retry later. |
| 0x0000000A | ESME_RINVSRCADR | Invalid source address (sender ID). Check format and registration. |
| 0x0000000B | ESME_RINVDSTADR | Invalid destination number. Check E.164 format. |
| 0x0000000D | ESME_RBINDFAIL | Bind failed. Check credentials, bind type and source IP. |
| 0x0000000E | ESME_RINVPASWD | Wrong password. |
| 0x0000000F | ESME_RINVSYSID | Unknown system ID. |
| 0x00000014 | ESME_RMSGQFUL | Message queue full. Slow down and retry. |
| 0x00000058 | ESME_RTHROTTLED | Throughput limit exceeded. Reduce the send rate and retry. |
| 0x00000061 | ESME_RINVSCHED | Invalid scheduled delivery time. |
| 0x00000062 | ESME_RINVEXPIRY | Invalid validity period. |
Providers can add their own values in the vendor-specific range. Ask for the provider's full list.
HTTP errors
HTTP APIs report problems with status codes, often with a body that names the field and the reason. Fix 4xx errors before resending; retry 429 and 5xx errors later with increasing delays. See messaging API concepts.
Troubleshooting checklist
| Symptom | What to check |
|---|---|
| Cannot connect or bind | Correct host and port, credentials, bind type, and whether your public IP is on the provider's allow-list. See IP access. |
| Accepted but never delivered | Validity period, destination number status, sender ID rules in the destination country, and the final receipt state. |
| Garbled or replaced characters | Encoding (GSM-7 or UCS-2) and data_coding value. See SMS encoding. |
| Message split unexpectedly | Message length per encoding, and extension characters that count twice. |
| Sender ID changed on the handset | Destination rules: some countries require registration or replace unregistered sender IDs. |
| Throttling errors | Your send rate against the agreed limit and window size. |
| Receipts missing | Whether a receipt was requested, whether your receiver session or webhook is reachable, and matching of message IDs. |
What to send to support
For each affected message: the message ID, destination number (it can be partly masked), sender ID, submission time with time zone, the error or receipt state, and the connection used. Do not send passwords or the full content of sensitive messages. Email support@wisenetwork.co.
Related
Talk to our carrier team
Tell us which destinations, volumes or networks you are working with. A member of our team will reply by email.
- Email: sales@wisenetwork.co
- Phone: +961 3 085 999