BroadNet
SMPPOperations

SMPP submit_sm: every mandatory field

Updated 4 min readStandards-based
Direct answer

submit_sm (command_id 0x00000004) sends a mobile-terminated message from the ESME to the SMSC. Its body is a fixed sequence of mandatory fields — addressing (TON/NPI + address), esm_class, protocol_id, priority_flag, scheduling, registered_delivery, data_coding, sm_length and short_message — optionally followed by TLVs. submit_sm_resp returns the SMSC message_id.

DiagramAn SMPP session between your platform and BroadNet
Your platform (ESME)
BroadNet SMSC
One persistent TCP/TLS connection
  1. bind_transceiverOpen and authenticate the session
  2. bind_transceiver_respSession accepted
  3. submit_smSend a message
  4. submit_sm_respAccepted, message ID returned
  5. deliver_smDelivery receipt or inbound message
  6. deliver_sm_respAcknowledged
  7. enquire_linkKeepalive while idle
§01

The full mandatory field order

submit_sm's body is a fixed, ordered sequence — there are no field tags, so order and size are everything. The table lists all mandatory parameters in wire order. short_message may be empty when the text is carried in a message_payload TLV instead; do not populate both.

submit_sm mandatory parameters (in wire order)
#FieldTypeNotes
1service_typeC-Octet String (6)Service category; usually empty
2source_addr_tonInteger (1)Type of number of the sender
3source_addr_npiInteger (1)Numbering plan of the sender
4source_addrC-Octet String (21)Sender address / alphanumeric ID
5dest_addr_tonInteger (1)Type of number of the recipient
6dest_addr_npiInteger (1)Numbering plan of the recipient
7destination_addrC-Octet String (21)Recipient MSISDN
8esm_classInteger (1)Message mode + type + UDHI flag
9protocol_idInteger (1)GSM TP-PID; usually 0
10priority_flagInteger (1)0 (normal) – 3 (highest)
11schedule_delivery_timeC-Octet String (1|17)Empty = immediate
12validity_periodC-Octet String (1|17)Empty = SMSC default
13registered_deliveryInteger (1)Request delivery receipt
14replace_if_present_flagInteger (1)0 = no, 1 = replace
15data_codingInteger (1)Encoding / DCS
16sm_default_msg_idInteger (1)Canned message id; usually 0
17sm_lengthInteger (1)Length of short_message (0–254)
18short_messageOctet String (0–254)The message payload
§02

Addressing: TON and NPI

source_addr and destination_addr each carry a Type of Number (TON) and Numbering Plan Indicator (NPI). For an international MSISDN use TON 1 (International) with NPI 1 (ISDN/E.164). For an alphanumeric sender ID use TON 5 (Alphanumeric) — the source_addr then holds up to 11 GSM-7 characters. Getting TON/NPI wrong is a leading cause of undelivered or mis-routed traffic.

Common TON and NPI values
TONMeaningNPIMeaning
0Unknown0Unknown
1International1ISDN (E.163/E.164)
2National3Data (X.121)
3Network specific4Telex (F.69)
4Subscriber number6Land Mobile (E.212)
5Alphanumeric8National
6Abbreviated9Private
§03

esm_class

esm_class is a bit-field that sets the messaging mode, the message type and GSM-specific features. The most important bit for senders is UDHI (0x40): set it when short_message begins with a User Data Header, for example a concatenation header. bit 0x80 requests the GSM reply path.

esm_class bit meanings (selected)
BitsFieldValue → meaning
1–0Messaging mode0 default · 1 datagram · 2 forward · 3 store & forward
5–2Message type0 default · 0x04 delivery receipt · 0x08 delivery ack · 0x10 user ack
6UDHI0x40 = short_message begins with a UDH
7Reply path0x80 = set GSM reply path
§04

data_coding, registered_delivery and validity

data_coding selects the text encoding: 0x00 = SMSC default (typically GSM 7-bit), 0x04 = 8-bit binary, 0x08 = UCS-2 for Unicode. registered_delivery's low two bits control receipts: 0 = none, 1 = receipt on final success or failure, 2 = on failure only. validity_period and schedule_delivery_time use the absolute form YYMMDDhhmmsstnnp or a relative form; an empty string means immediate delivery and the SMSC's default validity. Keep validity_period tight for OTPs so a delayed code expires rather than arriving stale.

data_coding — the values you actually use
ValueEncoding
0x00SMSC default alphabet (usually GSM 7-bit)
0x03Latin-1 (ISO-8859-1)
0x048-bit binary (octet-unspecified)
0x08UCS-2 (UTF-16BE) — Unicode
§05

The response

submit_sm_resp (0x80000004) returns command_status and, on success, a message_id (C-Octet String, up to 65 chars) that the SMSC assigns to the message. Store it: it is the key you match against the receipted_message_id in the delivery receipt. Beware format drift — some SMSCs return the id in hex on submit and decimal in the DLR, so normalise both when correlating.

FAQ

Frequently asked

What TON/NPI do I use for an alphanumeric sender ID?

Use source_addr_ton = 5 (Alphanumeric) and source_addr_npi = 0 (Unknown). The source_addr then holds up to 11 GSM-7 characters. Alphanumeric sender IDs are display-only and cannot receive replies.

How do I request a delivery receipt in submit_sm?

Set registered_delivery = 1 to get a receipt on final delivery or failure, or 2 for failure only. Request receipts only where you actually consume them, since unread DLRs waste throughput.

What is the maximum length of short_message?

The short_message field holds up to 254 octets, with sm_length giving the exact count. For longer text, either segment with a UDH across multiple submit_sm PDUs or carry the whole payload in the message_payload TLV instead of short_message.

Can I set both short_message and message_payload?

No. Populate one or the other. Providers reject a submit_sm that carries the message in both the mandatory short_message field and the message_payload TLV.

How do I send a Unicode message?

Set data_coding = 0x08 (UCS-2) and encode the text as UTF-16 big-endian in short_message. A single UCS-2 SMS holds 70 characters; longer Unicode text is segmented at 67 characters per part.

References

Source specifications

The published standards this page is grounded in. Opens in a new tab.

BNMaintained by the BroadNet engineering team·Carrier-grade messaging since 2003
Put it on the wire

Build with a real SMPP bind and REST API.

Request test access with real test keys: send to your own verified number first, then move to production across 200+ countries once your sender identity and routes are approved.