What is SMPP? The SMS session protocol
SMPP explained without the jargon: binds, windows, PDUs and the receipt path, and why the session shape matters at volume.
SMPP is the protocol a platform uses to exchange short messages with a message center over a persistent session. A bind declares the direction, the session carries a throughput window, and delivery receipts return as PDUs. It is not a request-and-response API.
Key facts
- SMPP is a persistent session with a declared bind direction.
- A bind carries a throughput allocation and a window of outstanding requests.
- A PDU has a 16-byte header and a command-specific body.
- Delivery receipts arrive asynchronously over the session; match them by message ID.
On this page
A session, not a call
SMPP keeps a connection open between your platform and a message center. The platform authenticates once, declares what it wants to do, and then submits messages and receives events over the same session. The message center does not wait for a new request to send a receipt or an inbound message; it pushes a PDU when it has something to report.
That shape suits a steady stream. The per-message overhead is small because the session state is already established, and the receipt channel is already open. It also means your client owns state that an HTTP client does not: bind status, the in-flight window, keep-alive timing and reconnect behavior.
Binds declare a direction
A bind is the authenticated session plus a direction. A transmitter bind submits messages. A receiver bind receives mobile-originated messages and receipts. A transceiver bind does both over one session. The provider issues credentials for each bind and may limit how many binds you can open.
Scale by adding binds, not by pushing one bind past its allocation. One bind carries one throughput allocation and one window of outstanding requests. If your peak needs more than that, ask for another bind and spread the traffic. A single bind driven past its window produces throttling, timeouts and retries that look like a network fault but start in the client.
Bind, submit, receipt
- Application (ESME)
- bind_transceiver Open the session
- SMSC
- submit_sm_resp Accepted for delivery
- Delivery receipt
Text description
The application opens a bind and the message center answers. The application submits a short message with submit_sm and receives submit_sm_resp with a message ID. Later, the message center sends a deliver_sm PDU that carries the delivery receipt. The application acknowledges it with deliver_sm_resp. An unbind closes the session when the work is done.
The window is the contract
The window is the number of requests your client may have outstanding before it waits for responses. It is not a suggestion. Submit more than the window allows and the message center throttles you; keep retrying at the same rate and the queue grows. Read the response code for each submit, slow down on throttle, and let the window drain before the next burst.
Keep-alive traffic holds the session open. A client that never sends enquire_link can sit on a dead connection until the first submit fails. A client that reconnects immediately after every drop can hammer the provider. Use a backoff, cap the reconnect rate and alert when the bind has been down longer than your traffic can tolerate.
One PDU, field by field
- command_length
- 53
- command_id
- 0x00000004
- command_status
- 0x00000000
- sequence_number
- 1
- service_type
- source_addr_ton
- 1
- source_addr_npi
- 1
- source_addr
- 12345
- dest_addr_ton
- 1
- dest_addr_npi
- 1
- destination_addr
- 15551234567
- esm_class
- 0x00
- protocol_id
- 0x00
- priority_flag
- 0
- schedule_delivery_time
- validity_period
- registered_delivery
- 0x01
- replace_if_present_flag
- 0x00
- data_coding
- 0x00
- sm_default_msg_id
- 0x00
- sm_length
- 4
- short_message
- 54657374
- Text
- Test
Text description
Every PDU starts with a four-byte command length, a four-byte command ID, a four-byte command status and a four-byte sequence number. The body follows. For submit_sm it carries the source and destination addresses, the short message, the data coding and the registered-delivery flag. Optional parameters travel as tag-length-value fields.
A day in the life of a message
The client opens a transceiver bind and reads the bind response. It submits a message and stores the message ID from the response. The message center routes the message to the destination network. Minutes later, a deliver_sm PDU arrives with the receipt: the original message ID, a state and often a network code. The client acknowledges the receipt and reconciles the state with its own record.
Each step has a failure mode. A bind can be rejected for bad credentials or a wrong interface version. A submit can be throttled, rejected, or accepted and then fail in the receipt. A receipt can arrive after the code has expired. Design the client to store the message ID, accept a late receipt and leave the application's own state as the source of truth for what the user did.
Decode a receipt before you debug a route
Paste a delivery receipt into the SMPP and DLR decoder and read the fields. Check the message ID, the state, the done date and the error code. If the state is not DELIVRD, the error code, read against the provider's code table, can indicate whether the number, the handset or the network refused the message. Do that before you ask the provider to change the route.
Receipts and debugging
A receipt is asynchronous. It arrives on the session as a deliver_sm PDU, and its format depends on the message center. Newer implementations carry the state in a message_state tag-length-value field. Older ones put a text receipt in the short message field, with key-value pairs such as id, stat and err. Parse both rather than assuming one.
Match by message ID, not by arrival order. Two messages submitted a second apart can return in the opposite order, and a retry can produce a duplicate. Store the ID at submit, update the record when the receipt arrives, and ignore a second receipt for the same ID unless its state is newer. The connection guide turns this into an operating sequence.
Check what you learned
-
Why does a second bind help more than a larger retry rate?
A bind carries one window. Adding a bind adds capacity; retrying against a full window adds queue and delay.
-
Where does the message ID come from?
The message center returns it in submit_sm_resp. Store it and match the later receipt by that ID.
-
What does a delivered receipt prove?
That the network accepted and delivered the message to the handset path. It does not prove that a person read it.
Answers are revealed on request. Nothing is scored, stored or sent.
FAQ
Do we need SMPP to start?
What is a bind?
What is a PDU?
Can we use SMPP over the public internet?
How are long messages handled?
Related
- Connecting over SMPP and HTTP
Take a test route to production without breaking binds, windows or receipts: bind, throughput, keep-alive, encoding, callbacks and failure handling.
- RFQ and RFP template pack
Field lists for SMS wholesale, eSIM and data, IoT and China connectivity requests, plus the online checklist that sends as an RFQ.
- Route test sample report
A desensitized static sample of a route-test report: what a route test checks, how failures read, and what triggers a route review.
Related products
Put this to work
Tell us the traffic, the destination and the measurement you need; we reply with the next step.