# SMPP submit_sm: every mandatory field

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

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

A complete field-by-field reference for submit_sm — service_type, TON/NPI, esm_class, data_coding, registered_delivery, validity_period, short_message and the rest — with the values that actually matter.

## 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)*

| # | Field | Type | Notes |
|---|---|---|---|
| 1 | service_type | C-Octet String (6) | Service category; usually empty |
| 2 | source_addr_ton | Integer (1) | Type of number of the sender |
| 3 | source_addr_npi | Integer (1) | Numbering plan of the sender |
| 4 | source_addr | C-Octet String (21) | Sender address / alphanumeric ID |
| 5 | dest_addr_ton | Integer (1) | Type of number of the recipient |
| 6 | dest_addr_npi | Integer (1) | Numbering plan of the recipient |
| 7 | destination_addr | C-Octet String (21) | Recipient MSISDN |
| 8 | esm_class | Integer (1) | Message mode + type + UDHI flag |
| 9 | protocol_id | Integer (1) | GSM TP-PID; usually 0 |
| 10 | priority_flag | Integer (1) | 0 (normal) – 3 (highest) |
| 11 | schedule_delivery_time | C-Octet String (1\|17) | Empty = immediate |
| 12 | validity_period | C-Octet String (1\|17) | Empty = SMSC default |
| 13 | registered_delivery | Integer (1) | Request delivery receipt |
| 14 | replace_if_present_flag | Integer (1) | 0 = no, 1 = replace |
| 15 | data_coding | Integer (1) | Encoding / DCS |
| 16 | sm_default_msg_id | Integer (1) | Canned message id; usually 0 |
| 17 | sm_length | Integer (1) | Length of short_message (0–254) |
| 18 | short_message | Octet String (0–254) | The message payload |

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

| TON | Meaning | NPI | Meaning |
|---|---|---|---|
| 0 | Unknown | 0 | Unknown |
| 1 | International | 1 | ISDN (E.163/E.164) |
| 2 | National | 3 | Data (X.121) |
| 3 | Network specific | 4 | Telex (F.69) |
| 4 | Subscriber number | 6 | Land Mobile (E.212) |
| 5 | Alphanumeric | 8 | National |
| 6 | Abbreviated | 9 | Private |

## 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)*

| Bits | Field | Value → meaning |
|---|---|---|
| 1–0 | Messaging mode | 0 default · 1 datagram · 2 forward · 3 store & forward |
| 5–2 | Message type | 0 default · 0x04 delivery receipt · 0x08 delivery ack · 0x10 user ack |
| 6 | UDHI | 0x40 = short_message begins with a UDH |
| 7 | Reply path | 0x80 = set GSM reply path |

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

| Value | Encoding |
|---|---|
| 0x00 | SMSC default alphabet (usually GSM 7-bit) |
| 0x03 | Latin-1 (ISO-8859-1) |
| 0x04 | 8-bit binary (octet-unspecified) |
| 0x08 | UCS-2 (UTF-16BE) — Unicode |

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

## Frequently asked questions

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

## Sources

- [SMPP v3.4 specification — §4.4 submit_sm](https://smpp.org/SMPP_v3_4_Issue1_2.pdf)
- [3GPP TS 23.040 — SMS technical realization](https://www.3gpp.org/dynareport/23040.htm)

## Related

- [SMPP deliver_sm & MO messages](https://www.broadnet.me/reference/smpp-deliver-sm)
- [Data coding scheme (DCS)](https://www.broadnet.me/reference/data-coding-scheme-dcs)
- [SMS segmentation & UDH](https://www.broadnet.me/reference/sms-segmentation-concatenation-udh)
- [SMPP PDU decoder (free tool)](https://www.broadnet.me/tools/smpp-pdu-decoder)
- [SMS API product](https://www.broadnet.me/products/sms-api)
