# Handle SMS messages and delivery receipts

The next section outlines how to format and receive messages, as well as how to manage delivery receipts.

## How to format message commands

This section explains the key settings and parameters needed to format message commands correctly when sending SMS messages via the SMPP API.

### Sender ID

A Sender ID identifies the sender of an SMS message and can be either a phone number or an alphanumeric string. To set up your Sender ID, add your phone numbers (those you've brought to Twilio or obtained from Twilio) and any alphanumeric Sender IDs you plan to use into the SMPP Source Address field in the message submission Protocol Data Unit (PDU).

You'll also need to set the correct type (TON) and format (NPI) for your phone numbers. Twilio might overwrite those values during the routing process for the message to be delivered correctly.

### Supported TON and NPI settings

The Type of Number (TON) setting specifies the address type, such as international, national, or network-specific, for both the source and destination numbers. The Number Plan Indicator (NPI) defines the numbering plan used. The NPI, along with the Type of Number (TON), helps in ensuring that messages are correctly routed by indicating how the destination and source numbers should be interpreted and formatted.

**TON settings**

| TON | Description      |
| :-- | :--------------- |
| 0   | Undefined        |
| 1   | International    |
| 2   | National         |
| 5   | Network-Specific |

**NPI settings**

| NPI | Description            |
| :-- | :--------------------- |
| 0   | Undefined              |
| 1   | E.164                  |
| 9   | Private Numbering Plan |

### Valid TON/NPI combinations

Twilio supports multiple TON/NPI combinations for messages being sent from ESME clients.

Most common implementations use `0/0` or `1/1` and provide an international number format that includes the country code.

> \[!NOTE]
>
> A leading "+" isn't required when formatting the `destination_address` or `source_address` fields in `submit_sm` PDUs regardless of TON and NPI combination.

### Validity period

To determine how long an SMS message should remain valid for delivery, you can use the `validity_period` parameter. The SMPP API integration supports this parameter, allowing you to set the validity period in 2 ways:

1. **Relative validity period**: It lets you specify how long the message should remain valid after it has been sent. For instance, you might set the message to be valid for 5 hours from the time of sending. If the message isn't delivered within this period, no further attempts will be made to deliver it.
2. **Absolute validity period**: You define a specific timestamp until which the message remains valid. The message will only be delivered until this exact point in time.

> \[!NOTE]
>
> The validity periods only determine how long a message stays within the Twilio network. The maximum allowed duration is 10 hours, equivalent to 36,000 seconds. If you submit a message with a validity period exceeding 36,000 seconds, it will be adjusted to the 10-hour maximum duration.

### Message encoding

Twilio supports messages encoded in either GSM7 or UCS2 formats. When sending messages, your SMPP client must set the Data Coding Scheme (DCS) parameter to 0 for GSM7 or 8 for UCS2. GSM7, with a DCS value of 0, is Twilio's standard character set for sending SMS messages.

Any messages submitted with a different encoding value will be rejected. Additional details on supported encodings can be found below.

| Data Coding | Description         | Character Set | Single-Segment Max Characters | Multi-Segment Max Characters |
| :---------- | :------------------ | :------------ | :---------------------------- | :--------------------------- |
| 0           | SMSC Default        | GSM-7         | 160                           | 153                          |
| 1           | IA5/ Latin 9/ ASCII | ISO-8859-15   | 160                           | 153                          |
| 3           | Latin 1             | ISO-8859-1    | 140                           | 134                          |
| 8           | UCS2                | ISO-10646     | 70                            | 67                           |

Twilio may group and split messages differently depending on the network they are sent to. The encoding and number of segments of a submitted message might change during delivery, so it may not arrive exactly as originally sent. You are billed according to the number of segments sent downstream to deliver the message.

> \[!NOTE]
>
> In some instances the number of segments billed by Twilio for delivery downstream may differ from the number of segments you sent to Twilio.

### Multipart SMS

When sending a long message via SMPP, it is required to split a message into segments on the client side and send each segment in a separate SMPP request. Each request must include a User Data Header (UDH) within the message text to indicate that it is part of a multipart message. The two key parameters in the PDU body are:

* `esm_class`: it sets the value to 0x40 (this is 64 in decimal) to indicate that there is a UDH.
* `short_message`: it appends the UDH information at the beginning of the `short_message`.

The SMPP API doesn't support segmentation via Segmentation and Reassembly Tag-Length-Value elements (SAR TLV) mechanism or longer messages submitted in the message\_payload. UDH is the only supported multipart message strategy.

> \[!NOTE]
>
> Twilio doesn't recommend sending concatenated messages of longer than 10 segments as it can lead to significantly longer processing times.

### Register delivery receipts

The `registered_delivery` parameter is used to request a delivery receipt from the SMSC and/or acknowledgements from the SME originated.

Currently, Twilio supports only final delivery receipts. The table below lists the only supported values.

| Bits (76543210) | Abbreviation | Description                                                                                  |
| :-------------- | :----------- | :------------------------------------------------------------------------------------------- |
| x x x x x x 0 0 | 0x00         | No delivery receipt from the SMSC is requested (default option).                             |
| x x x x x x 0 1 | 0x01         | SMSC delivery receipt requested where final delivery outcome is delivery success or failure. |
| x x x x x x 1 0 | 0x02         | SMSC delivery receipt requested where the final delivery outcome is delivery failure.        |
| x x x x x x 1 1 | 0x03         | SMSC delivery receipt requested where the final delivery outcome is delivery success.        |

## Receive an inbound message

Twilio supports inbound messages to phone numbers that are assigned to your account. Inbound messages can be configured in the Twilio Console or Twilio API's using the account specific "Inbound routing webhook" that is provided with your SMPP credentials during initial onboarding. Once the "inbound routing webhook" has been configured on your account all messages received at Twilio for that inventory item will be routed to connected SMPP binds that support carriage of inbound messages, an receiver (RX) or transceiver (TRX) bind.

Delivery receipts can be distinguished from MO messages by checking the value of the `esm_class` parameter. If the 3rd bit is off, the request is an inbound message.

To learn more about how to configure your phone numbers, please check out the [initial setup and connection guide](/docs/smpp/initial-setup-and-connection#set-up-your-inventory-and-configure-inbound-messages).

## Handle delivery receipts

Twilio can send delivery receipts from carriers back to the ESME client for messages they have sent. These delivery receipts are forwarded using the SMPP `deliver_sm` command. This is the same SMPP request type used for Mobile Originated (MO) messages.

Delivery receipts can be distinguished from MO messages by checking the value of the `esm_class` parameter. If the 3rd bit is on, the request is a delivery receipt. If MCC (mobile country code) or MNC(mobile network code) information is desired in the delivery receipt, please reach out to your account executive for more information.

Twilio sends delivery receipts for messages when the ESME client sets the `registered_delivery` field in the mobile-terminated (MT) `submit_sm` command. Individual bits must be set in this field as specified in [section 5.2.17 of the SMPP Specification](https://smpp.org/SMPP_v3_4_Issue1_2.pdf).

DLR's will be sent in the following format:

```bash
    id:<message id> sub:001 dlvrd:001 submit date:1702281424 done date:1702281424 stat:DELIVRD err:000 text
```

### Delivery receipt resending

Twilio will attempt to re-send the DLR every 10 minutes for up to 5 days from the time the segment was accepted. Resending won't happen if a non-zero `command_status` was received in a corresponding `deliver_sm_resp`. If Twilio receives a `deliver_sm_resp` with any `command_status`, then the delivery receipt will be considered processed.

### Delivery receipt message statuses

The final status of messages, as provided in a delivery receipt by the SMPP API, follows the standards set by the [SMPP Protocol Specification v.3.4.](https://smpp.org/SMPP_v3_4_Issue1_2.pdf)

Delivery receipts can have the following message statuses:

| Status    | Description                                                         |
| :-------- | :------------------------------------------------------------------ |
| `DELIVRD` | The message has been successfully delivered to the recipient.       |
| `UNDELIV` | The message hasn't been delivered to the recipient.                 |
| `EXPIRED` | The message has expired and wasn't delivered to the recipient.      |
| `DELETED` | The message has been deleted and wasn't delivered to the recipient. |
| `ACCEPTD` | The message has been accepted by the SMSC.                          |
| `UNKNOWN` | The message status is unknown.                                      |
| `REJECTD` | The message has been rejected by the SMSC.                          |

## Troubleshooting submission errors

When you send messages via the Twilio SMPP API, you might encounter errors that show issues in the delivery process. When this happens, the `submit_sm` request may be rejected on submission.

In this case, the `comand_status` field on the `submit_sm_response` will be used to communicate an error message. The SMPP API doesn't send non-SMPP specification errors on `submit_sm` requests.

Please see the list of common error codes below:

| Error code                                                | Value (hex) | Value (decimal) | Error description                                                                                           |
| :-------------------------------------------------------- | :---------- | :-------------- | :---------------------------------------------------------------------------------------------------------- |
| ESME\_RINVBNDSTS                                          | 0x00000004  | 4               | Incorrect BIND status for given command. PDU has been sent in the wrong session state.                      |
| ESME\_RINVSRCADR                                          | 0x0000000A  | 10              | Invalid source address.                                                                                     |
| ESME\_RINVDSTADR                                          | 0x0000000B  | 11              | Invalid destination address.                                                                                |
| ESME\_RINVSRCTON                                          | 0x00000048  | 72              | Invalid source address TON.                                                                                 |
| ESME\_RINVSRCNPI                                          | 0x00000049  | 73              | Invalid source address NPI.                                                                                 |
| ESME\_RINVDSTTON                                          | 0x00000050  | 80              | Invalid destination address TON.                                                                            |
| ESME\_RINVDSTNPI                                          | 0x00000051  | 81              | Invalid destination address NPI.                                                                            |
| INVALID\_DATA\_CODING\_ERROR\_STATUS                      | 0x00000400  | 1024            | Message sent with invalid data coding.                                                                      |
| INVALID\_UDH\_HEADER\_ERROR\_STATUS                       | 0x00000401  | 1025            | Message sent with invalid UDH header.                                                                       |
| INVALID\_BODY\_ERROR\_STATUS                              | 0x00000402  | 1026            | Inability to decode message body based on provided data coding.                                             |
| SHORT\_MESSAGE\_IS\_TOO\_LONG                             | 0x00000403  | 1027            | Combined length of body and UDH is longer than 160 bytes.                                                   |
| INVALID\_ESM\_CLASS\_AND\_UDH\_COMBINATION\_ERROR\_STATUS | 0x00000404  | 1028            | The ESM Class doesn't support UDH or the UDH is missing when the ESM Class indicates that one should exist. |
| MULTIPART\_ACCUMULATION\_TEMPORARY\_ERROR\_STATUS         | 0x00000405  | 1029            | Temporary error while accumulating multipart message.                                                       |
