# SMPP delivery receipts (DLR) format

> 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.

- Canonical URL: https://www.broadnet.me/reference/smpp-delivery-receipts-dlr
- Language: en
- Last updated: 2026-07-18
- Publisher: BroadNet (https://www.broadnet.me)

The Appendix-B delivery-receipt text format inside deliver_sm: id, sub, dlvrd, submit date, done date, stat, err and Text — plus the stat keywords and their message_state numbers.

## 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.

*A delivered receipt (short_message contents)*

```text
id:0a1b2c3d4e sub:001 dlvrd:001 submit date:2607181432 done date:2607181433 stat:DELIVRD err:000 Text:Your code is 4
```

## Field 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.

*Delivery-receipt fields (Appendix B)*

| 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 keywords ↔ message_state*

| 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 questions

### 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.

## Sources

- [SMPP v3.4 specification — Appendix B (delivery receipt)](https://smpp.org/SMPP_v3_4_Issue1_2.pdf)
- [3GPP TS 23.040 — SMS status report](https://www.3gpp.org/dynareport/23040.htm)

## Related

- [DLR decoder (free tool)](https://www.broadnet.me/tools/dlr-decoder)
- [SMPP deliver_sm & MO messages](https://www.broadnet.me/reference/smpp-deliver-sm)
- [SMPP TLV optional parameters](https://www.broadnet.me/reference/smpp-tlv-parameters)
- [SMPP integration checklist (guide)](https://www.broadnet.me/guides/smpp-integration-checklist)
- [SMS API product](https://www.broadnet.me/products/sms-api)
