deliver_sm (command_id 0x00000005) is sent from the SMSC to the ESME to deliver either a mobile-originated (MO) message or a delivery receipt (DLR). Its body mirrors submit_sm. The esm_class field distinguishes the two: bit 0x04 marks a delivery receipt. The ESME must always answer with deliver_sm_resp.
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
One PDU, two jobs
deliver_sm is the SMSC-to-ESME counterpart of submit_sm and shares the same body layout. It carries either an inbound MO message (a subscriber texting your long number or short code) or a delivery receipt reporting the fate of a message you submitted earlier. Your receiver or transceiver bind handles both; you branch on esm_class to route them correctly.
Telling MO from DLR with esm_class
The message-type bits of esm_class identify the payload. A plain MO message has esm_class message-type bits clear. A delivery receipt sets bit 0x04. When 0x04 is set, the short_message contains the Appendix-B receipt text (id, stat, err…) and the receipted_message_id TLV usually carries the original message_id. Do not parse the receipt text as user content.
| esm_class (message-type bits) | Payload |
|---|---|
| 0x00 | Normal mobile-originated (MO) message |
| 0x04 | SMSC delivery receipt (DLR) |
| 0x08 | SME delivery acknowledgement |
| 0x10 | SME manual/user acknowledgement |
| 0x20 | Conversation abort (Korean CDMA) |
| 0x40 | Intermediate delivery notification |
Always respond with deliver_sm_resp
For every deliver_sm the ESME must return a deliver_sm_resp (0x80000005) with matching sequence_number and ESME_ROK. If you do not acknowledge, the SMSC treats the delivery as failed, re-sends it, and — because outstanding un-acked PDUs count against the window — can stall the whole session. Acknowledge promptly and do heavy processing asynchronously.
SMSC → ESME deliver_sm seq=88 esm_class=0x00 (MO: user text)
ESME → SMSC deliver_sm_resp seq=88 status=ESME_ROK
SMSC → ESME deliver_sm seq=89 esm_class=0x04 (DLR: id:... stat:DELIVRD)
ESME → SMSC deliver_sm_resp seq=89 status=ESME_ROKdata_sm as an alternative
data_sm (0x00000103) is a lighter-weight, streamlined operation that can carry MO messages and receipts using TLVs (notably message_payload) instead of the fixed short_message field. Some networks prefer it for interactive or WAP-style traffic. Support is optional and provider-specific — confirm before relying on it.
Frequently asked
How do I distinguish a delivery receipt from an inbound MO message?
Check esm_class on the deliver_sm. If the message-type bit 0x04 is set, it is a delivery receipt and short_message holds the Appendix-B receipt text. If those bits are clear, it is a normal mobile-originated message from a subscriber.
What happens if I don't send deliver_sm_resp?
The SMSC assumes the delivery failed and re-sends the deliver_sm. Unacknowledged PDUs also consume your window, so failing to respond can stall the session and produce duplicate MO/DLR processing.
Does deliver_sm have the same fields as submit_sm?
Yes — deliver_sm reuses the submit_sm body layout (service_type, TON/NPI addressing, esm_class, data_coding, short_message, and so on). Only the direction and the interpretation of the payload differ.
Can a single MO message be concatenated?
Yes. Long inbound messages arrive as multiple deliver_sm PDUs with a UDH concatenation header (esm_class UDHI bit 0x40 set) or SAR TLVs. Reassemble them by reference number and sequence just as you would outbound segments.
Source specifications
The published standards this page is grounded in. Opens in a new tab.