SMPP
The Short Message Peer-to-Peer (SMPP) protocol is an open, industry-standard protocol used by the telecommunication industry. It exchanges SMS messages between SMS application systems and Short Message Service Centers (SMSC).
The connection between the application and the Infobip SMPP server is SMPP version 3.4 (versions 3.3 and 5.0 are not supported).
SMPP traffic security
Use a dedicated user with credentials intended only for broadcasting SMPP API traffic. This ensures proper account administration and keeps your SMPP API traffic secure.
If your SMPP traffic originates from static IP addresses, contact your account manager. Provide a list of source IP addresses to be safelisted for the user responsible for broadcasting SMPP API traffic. To connect to the Infobip SMPP server, use the hostnames listed in the Bind parameters section. For a secure connection, send the bind request to the encrypted SSL/TLS endpoint: smpp2.infobip.com:8887.
Do not pin the Infobip TLS server certificate or CA public keys. Infobip rotates certificates regularly, and a pinned certificate causes an outage when it is renewed. For more information, see REST API traffic encryption.
For mutual TLS (mTLS) with client certificate verification, connect on port 8890. To set it up, send your client CA certificate to Support.
Bind parameters
Use the following parameters to bind to the Infobip SMPP server:
| Name | Mandatory | Description |
|---|---|---|
system_id | Yes | The username of a user with SMPP access enabled. See API access. |
password | Yes | Provided for each client. Infobip does not limit the length of the system_id or the password (the SMPP v3.4 protocol suggests 8 characters). The maximum length depends on your SMPP library, so use a library that supports values longer than 8 characters. To adjust the password strength policy on your account, contact Support. |
| Hostname | Yes | Primary: smpp3.infobip.com · Secondary: smpp1.infobip.com · SSL: smpp2.infobip.com · For different accounts, choose the hostname based on the Data Center (DC) location to ensure logs are properly displayed (for example, use smpp-id1.infobip.com for accounts located in Indonesia) |
port | Yes | 8888 (primary and secondary) · 8887 (SSL) · 8890 (mTLS) |
| Session timeout | Yes | 75 seconds. If no other PDU is sent, send enquire_link at least every 30 seconds (see Keeping the session alive) |
system_type | No | Set to HLR for Number Lookup over SMPP. Otherwise optional. |
You can bind as a transmitter, a receiver, or a transceiver, and by default you can open up to 10 sessions. To receive delivery reports, bind as a transceiver or a receiver. Delivery reports are sent only if your route provides delivery reporting, and they are distributed equally across all of your sessions capable of receiving them. For how sessions and window size affect your send rate, see Throughput and windowing.
Bind types and session lifecycle [#bind-types-and-session-lifecycle-bind-parameters]
A session begins in the open state, becomes bound after a successful bind, and returns to closed after unbind or disconnection. The bind type sets the direction of traffic on that session:
| Bind type | PDU | Direction |
|---|---|---|
| Transmitter | bind_transmitter | Client → SMSC only (submit messages; cannot receive) |
| Receiver | bind_receiver | SMSC → client only (receive deliver_sm: inbound messages and delivery reports) |
| Transceiver | bind_transceiver | Both directions on one session |
To both send messages and receive delivery reports on a single connection, bind as a transceiver. To close a session cleanly, send unbind and wait for unbind_resp before disconnecting.
The optional system_type bind field is a label categorizing the ESME (for example, a service class). It is optional on Infobip (see Bind parameters) and is also used to select Number Lookup by setting system_type = HLR (see Number Lookup over SMPP).
Keeping the session alive (enquire_link) [#keeping-the-session-alive-enquirelink-bind-parameters]
enquire_link is the SMPP keepalive. The client and server exchange it to confirm the connection is still active. If no PDU (including enquire_link) is exchanged within the 75-second session timeout, the bind is dropped and must be re-established. When no other PDU is sent, send enquire_link at least every 30 seconds.
enquire_link works in both directions. Infobip also sends enquire_link to a client that has been idle, and closes the session if the client does not respond within the session timeout. Send your own enquire_link anyway, regardless of the keepalives Infobip sends. This keeps NAT devices, firewalls, and proxies on your side from closing the connection.
Reconnection and recovery [#reconnection-and-recovery-bind-parameters]
An SMPP session can drop for several reasons: network issues, a missed keepalive, or an SMSC restart. Recovering a dropped session means re-binding and resuming. A message that received no confirmed submit_sm_resp before the drop has an unknown outcome. On reconnection, it can be resubmitted and correlated by message_id when responses return.
When your account has reached its maximum number of sessions, a new bind request is rejected with ESME_RBINDFAIL (0x0000000D) and the connection is closed. The account is not locked, and there is no waiting period: the next bind succeeds as soon as one of your sessions closes. Track your open sessions in your application, and do not open a new bind when the session limit is reached. Retrying binds in a tight loop does not help and floods the connection with rejected requests.
PDU types
Infobip supports the following PDUs.
Session and lifecycle:
bind_transmitter/bind_receiver/bind_transceiver(and their_resp)unbind(andunbind_resp)enquire_link(andenquire_link_resp): Keepalivegeneric_nack: Returned when a PDU cannot be parsed or is invalid at the protocol level
Messaging:
submit_sm: Submit a single message (andsubmit_sm_resp)deliver_sm: Inbound mobile-originated messages and delivery reports (anddeliver_sm_resp)
Data coding schemes
The data_coding field on submit_sm sets the character encoding, which also determines the per-message character limit.
The following table lists the supported data coding schemes.
| DCS | Encoding | Single-message limit |
|---|---|---|
| 0 or 1 | IA5/GSM-7 (default) | 160 characters |
| 3 | Latin1 (ISO-8859-1) | 140 bytes |
| 8 | Unicode/UCS-2 (ISO/IEC-10646) | 70 characters |
This table is the SMPP-transport view of encoding. For GSM-7 and Unicode, concatenation (153 and 67 characters per part), and how encoding affects cost, see Send messages in multiple languages.
esm_class
The esm_class field on submit_sm controls the message mode and features. The bit that matters most for integration is the UDHI (User Data Header Indicator) bit 0x40. It tells the SMSC that the message payload begins with a User Data Header. This is required for concatenated messages and for National Language Shift Tables.
The following table describes the esm_class values.
esm_class value | Meaning |
|---|---|
0 | Default message, no UDH |
0x40 (64) | Message payload contains a UDH (UDHI set); used for concatenation and National Language Shift Tables |
0x04 (4) | Set on inbound deliver_sm PDUs that carry a delivery receipt |
Long and concatenated messages
A message longer than a single segment is split into multiple parts and reassembled on the handset. Segment sizes depend on the encoding:
| Encoding | Single message | Per segment when concatenated |
|---|---|---|
| GSM-7 | 160 characters | 153 characters |
| UCS-2 (Unicode) | 70 characters | 67 characters |
The reduced per-segment size is because a User Data Header (UDH) carrying the concatenation reference occupies part of each segment. There are two ways to signal concatenation over SMPP:
- UDH in the message body: Set the UDHI bit in
esm_class(0x40). Prefix the payload of each segment with a concatenation UDH (reference number, total parts, part number). - SAR optional parameters (TLVs): Send the concatenation metadata as TLVs instead of embedding a UDH:
sar_msg_ref_num,sar_total_segments,sar_segment_seqnum.
The two methods are mutually exclusive. Use one or the other for a given message, not both.
When you use SAR TLVs, you still need to account for the UDH when splitting the message. Keep each segment within the per-segment limit for your data coding: 153 characters for GSM-7, 67 for UCS-2.
Infobip does not split a long message that you place in the short_message field. Segment it on your side, with UDH concatenation or SAR TLVs. A message can have up to 10 segments: 1,530 characters in GSM-7 or 670 in UCS-2.
Alternatively, send the full text in the message_payload optional parameter (0x0424) of a single submit_sm. Infobip then splits the message and adds the concatenation headers.
Send all segments of a message through sessions in the same data center. Infobip does not combine segments of one message across regions.
National Language Shift Tables
National Language Shift Tables are a GSM-standard mechanism (3GPP TS 23.038(opens in new tab), Release 8 onward). They let a message carry language-specific characters at GSM-7 cost, instead of forcing the whole message to Unicode. A shift table replaces the GSM 7-bit default alphabet with a language-specific one, selected through the User Data Header (UDH) of the message. With a shift table, the single-part limit stays at 155 characters rather than the 70 of Unicode. Available over SMPP, Broadcast, and HTTP API.
For the sender-facing feature overview (supported languages, enabling it, languageCode), see Send messages in multiple languages. The rest of this section is the protocol-level (UDH byte) detail.
How shift tables work [#how-shift-tables-work-national-language-shift-tables]
- Locking shift: Characters from the extended set do not reduce the message length (it stays 155 characters).
- Single shift: Each extended character requires an escape character, which reduces the available message length by 1.
- Example: In Spanish, the letter Ú is only in the single shift set. Using 3 such characters reduces the length from 155 to 152 characters.
- Example encoding:
1B55, where1Bis the escape character and55is Ú from the extended set.
To use a shift table:
- Select the language in the UDH, with the Information Element Identifier (IEI) for single or locking shift.
- Set
esm_classto 64. - Set
data_codingto 0 or 1.
Example UDHs [#example-udhs-national-language-shift-tables]
The following table shows an example UDH that selects the Turkish locking shift table.
| UDH length | IEI (Information Element Identifier) | IE length | Selected shift |
|---|---|---|---|
| 03 | 25 | 01 | 01 |
| Remaining UDH length in bytes | National Language Locking Shift | Locking shift (Turkish) |
The following table shows an example UDH that selects the Spanish single shift table.
| UDH length | IEI (Information Element Identifier) | IE length | Selected shift |
|---|---|---|---|
| 03 | 24 | 01 | 02 |
| Remaining UDH length in bytes | National Language Single Shift | Single shift (Spanish) |
National Language Identifier reference [#national-language-identifier-reference-national-language-shift-tables]
The following table lists the shift tables and UDH identifier for each language.
| Language | Single shift | Locking shift | UDH identifier |
|---|---|---|---|
| Reserved | Basic | Basic | 0x00 |
| Turkish | Turkish | Turkish | 0x01 |
| Spanish | Basic | Spanish | 0x02 |
| Portuguese | Portuguese | Portuguese | 0x03 |
| Bengali | Bengali | Bengali | 0x04 |
| Gujarati | Gujarati | Gujarati | 0x05 |
| Hindi | Hindi | Hindi | 0x06 |
| Kannada | Kannada | Kannada | 0x07 |
| Malayalam | Malayalam | Malayalam | 0x08 |
| Oriya | Oriya | Oriya | 0x09 |
| Punjabi | Punjabi | Punjabi | 0x0A |
| Tamil | Tamil | Tamil | 0x0B |
| Telugu | Telugu | Telugu | 0x0C |
| Urdu | Urdu | Urdu | 0x0D |
For the detailed GSM-7 character set, see GSM 7-bit default alphabet (GSM 03.38, Wikipedia)(opens in new tab).
Scheduled delivery and validity period
Two submit_sm time fields use the same SMPP time format. Both can be absolute (a fixed date and time) or relative (an offset from now); leaving a field empty applies the SMSC default.
schedule_delivery_time: When the SMSC first attempts delivery. Use it to schedule a message for later. You can schedule a message up to 180 days ahead.validity_period: How long the SMSC keeps trying before the message expires undelivered. The maximum is 48 hours, which is also the default.
The relative format is YYMMDDhhmmsstnnp, where the trailing R marks it relative:
This means 1 day and 12 hours from now. An absolute time uses the same digits with a +/- UTC offset instead of the trailing R.
Requesting delivery receipts
A delivery receipt (DLR) is not returned by default. Request one by setting the registered_delivery field on the submit_sm PDU:
registered_delivery | Meaning |
|---|---|
0 | No delivery receipt (default) |
1 | Delivery receipt requested on final delivery or failure |
2 | Delivery receipt requested on failure only |
You must also be bound as a transceiver or receiver to receive the resulting deliver_sm. For the receipt layout, see Delivery report format.
Delivery report format
The delivery report is returned in the short_message field of the deliver_sm PDU, in this format:
To correlate a delivery report with the message you sent, match the id field to the message_id returned in the original submit_sm_resp. SMPP v3.4 also defines two optional parameters (TLVs) on the deliver_sm receipt for this. receipted_message_id is the ID of the original message, and message_state is a numeric code for the delivery status. When present, these are the more reliable way to correlate and read state than parsing the receipt text.
When enabled for your account, Infobip populates the receipted_message_id (0x001E) and message_state (0x0427) optional parameters on delivery receipts. Use receipted_message_id to correlate the receipt with your request.
Treat the message_id as an opaque string: do not assume a fixed length or a numeric-only format. A common integration bug is a format mismatch between the message_id in submit_sm_resp and the id in the delivery receipt. For example, one is decimal and the other hexadecimal. Match on the exact string returned.
Delivery statuses:
The following table lists the delivery statuses returned in the stat field.
| Status | Meaning |
|---|---|
| ENROUTE | Message is in transit |
| DELIVRD | Message delivered to handset |
| EXPIRED | Message expired before delivery |
| UNDELIV | Undeliverable |
| ACCEPTD | Message accepted (for example, manually read on behalf of the subscriber) |
| UNKNOWN | Unknown status |
| REJECTD | Message rejected |
GSM error codes are returned in delivery receipts (DLRs), the status reports the network returns for a sent message. They explain the status of the message, whether intermediate or final. The error code is returned in the short_message as part of delivery information, or (if enabled by Infobip specialists) in Optional TLV 0x423. For the codes, see the Error code reference.
Command status
Each request to the Infobip system receives an acknowledgement per the SMPP v3.4 standard, including a command_status. The following table lists the most relevant command statuses, including Infobip-specific ones.
command_status | PDU | Description |
|---|---|---|
0x0000000E | bind_resp | Password missing from the bind request |
0x0000000F | bind_resp | Invalid credentials (returned for an invalid system_id or an invalid password) |
0x00000022/34 | submit_sm_resp | Network not covered |
0x000000FF/255 | submit_sm_resp | Account has insufficient balance |
0x0000000A | submit_sm_resp | Invalid source address |
0x0000000B | submit_sm_resp | Invalid destination address |
0x0000000C | submit_sm_resp | Duplicate or invalid messageID |
0x000004A1 | submit_sm_resp | System error or channel disabled |
0x0000009F | submit_sm_resp | Invalid optional parameter length |
Throughput and windowing
SMPP throughput is governed by more than raw connection speed. Two factors set your effective send rate:
- Sessions (binds): By default you can open up to 10 sessions, and the number of binds can be increased on request. Submissions and delivery reports are distributed across your available sessions.
- Window size: The window is the number of PDUs you can have in flight awaiting a response (for example,
submit_smPDUs awaiting theirsubmit_sm_resp). With synchronous submission the client waits for each response before sending the next PDU, which caps throughput at one PDU per round trip. With asynchronous (windowed) submission the client sends up to the window size without waiting, which is how high throughput is achieved. You configure the window size on your client; it does not need to match a value on the Infobip side. sequence_number: Every PDU carries asequence_number, and its response echoes it. In asynchronous mode, responses can arrive out of order. The client must match each response to its request bysequence_number, rather than assuming responses come back in send order.
There is no fixed TPS cap defined on the Infobip side. Effective submit speed depends primarily on the network latency between your system and Infobip, and on your window size and number of binds. If you need higher throughput, request additional binds.
Flash notifications
Send Flash notifications using your default system_id and password, setting data_coding to 16 (or 24 for Unicode). These are the Flash equivalents of 0 and 8 in Data coding schemes. Flash notifications are immediately displayed on screen and not stored in device memory.
Number Lookup over SMPP
You can run a Number Lookup (HLR lookup) over this SMPP connection by binding with system_type = HLR. The full procedure, the returned TLV fields, and examples are documented in Number Lookup access methods. SMPP is one of four access methods for the same capability (web interface, REST API, SMPP, and ENUM).
URL shortening and tracking
You can use your SMPP connection in conjunction with the URL Shortening functionality using the following TLVs.
| Field | Type | Hex | Decimal | Value | Notes |
|---|---|---|---|---|---|
| Shorten URL | TLVString | 0x1494 | 5268 | Any value will enable | Not required if Custom Domain TLV is set |
| Custom Domain | TLVString | 0x1495 | 5269 | http:// or https:// are not required in the custom domain | |
| Remove Protocol | TLVString | 0x1496 | 5270 | Boolean | |
| Track Clicks | TLVString | 0x149B | 5275 | Boolean | To receive click events, set up a subscription using the Subscriptions API or Subscriptions Management in the Infobip web interface. Alternatively, use Reports to view click data without a subscription. |
ENUM
Run HLR lookups using the Infobip ENUM interface with standard DNS NAPTR queries.
Network connectivity troubleshooting
Test the connection to the SMPP host and port when a bind fails.
Platform status and incidents
Subscribe to SMPP incident notifications for your region.
Was this page helpful?