A delivery receipt (DLR) is a deliver_sm whose esm_class marks it as a receipt. The short_message carries a fixed-format text — id, sub, dlvrd, submit date, done date, stat, err, Text — defined in SMPP v3.4 Appendix B. The stat field (DELIVRD, EXPIRED, UNDELIV, REJECTD…) is the message's terminal status.
bind_transceiverOpen and authenticate the sessionbind_transceiver_respSession acceptedsubmit_smSend a messagesubmit_sm_respAccepted, message ID returneddeliver_smDelivery receipt or inbound messagedeliver_sm_respAcknowledgedenquire_linkKeepalive while idle
The Appendix-B receipt text
When the SMSC reports a message's outcome, it sends a deliver_sm with the receipt bit set in esm_class (0x04) and puts a structured text string in short_message. The format is defined in Appendix B of the v3.4 spec. Each field is a key followed by a value; the id field ties the receipt back to your submit_sm_resp message_id.
id:0a1b2c3d4e sub:001 dlvrd:001 submit date:2607181432 done date:2607181433 stat:DELIVRD err:000 Text:Your code is 4Field by field
The receipt is compact but every field matters for reconciliation. Dates use the format YYMMDDhhmm. sub and dlvrd count segments submitted and delivered. stat is the seven-character terminal state. err is a network/SMSC-specific error code (000 on success). Text is the first 20 characters of the original message.
| Field | Meaning |
|---|---|
| id | SMSC message_id of the original submit_sm |
| sub | Number of short messages submitted (segments) |
| dlvrd | Number of short messages delivered |
| submit date | When the message was submitted (YYMMDDhhmm) |
| done date | When the message reached its final state (YYMMDDhhmm) |
| stat | Final message state — 7-char keyword (see below) |
| err | Network/SMSC-specific error code (000 = none) |
| Text | First 20 characters of the original message |
stat keywords and message_state numbers
The stat keyword is the human-readable terminal status; the message_state TLV (0x0427) carries the same information as a number. Treat DELIVRD as the only unambiguous success; EXPIRED, UNDELIV, REJECTD, DELETED and UNKNOWN are terminal failures. ACCEPTD and ENROUTE are non-final and should not close a message.
| stat | message_state | Final? | Meaning |
|---|---|---|---|
| ENROUTE | 1 | No | In transit |
| DELIVRD | 2 | Yes | Delivered to handset |
| EXPIRED | 3 | Yes | Validity period elapsed |
| DELETED | 4 | Yes | Message deleted |
| UNDELIV | 5 | Yes | Undeliverable |
| ACCEPTD | 6 | No | Accepted / manually read |
| UNKNOWN | 7 | Yes | State unknown |
| REJECTD | 8 | Yes | Rejected by network |
Parsing safely
Parse the receipt from the deliver_sm short_message, but correlate on the receipted_message_id TLV (0x001E) rather than only the id text, and normalise hex vs decimal id formats. Distinguish intermediate receipts (esm_class intermediate-notification bit) from final states, and map the err code to a normalised taxonomy — absent subscriber, handset busy, spam-blocked, invalid number — since raw err values vary by route. Always answer deliver_sm_resp.
Frequently asked
What does stat:DELIVRD mean?
DELIVRD is the terminal status meaning the message reached the recipient handset. It corresponds to message_state 2 and is the only stat value that unambiguously represents success.
Where in the PDU is the delivery-receipt text?
In the short_message field of a deliver_sm whose esm_class has the delivery-receipt bit (0x04) set. The text follows the Appendix-B format: id, sub, dlvrd, submit date, done date, stat, err, Text.
What is the err field in a DLR?
err is a network- or SMSC-specific error code giving the reason for a non-delivery (000 means none). Because values differ by route, map them to a normalised internal taxonomy for consistent quality reporting.
Why doesn't my DLR id match my submit_sm_resp message_id?
Usually a format mismatch: some SMSCs return the message_id in hexadecimal on submit_sm_resp but decimal in the receipt (or vice versa). Normalise both to one representation before comparing, and prefer the receipted_message_id TLV.
Are all delivery receipts final?
No. ENROUTE and ACCEPTD are intermediate states, and some networks send intermediate notifications. Only close a message on a final stat such as DELIVRD, EXPIRED, UNDELIV, REJECTD, DELETED or UNKNOWN.
Source specifications
The published standards this page is grounded in. Opens in a new tab.