Skip to content

SMS over SMPP 3.4

Connect your platform to the Hablame SMPP 3.4 server to send SMS and receive, for each message, the final status we know for it.

12 min readReviewed on

Goal

Send SMS from your own platform with the standard SMPP 3.4 protocol, and know what happened to each one. It is the right path if you already have an SMPP client or need to send sustained volume.

Over SMPP you send and receive delivery receipts for what you sent. SMS that people send to your short code do not arrive here: they arrive by webhook.

Requirements

  • An SMPP account created by the Hablame team. How to request it.
  • Fixed public IP addresses: only the ones you authorize are enabled for your account.
  • A cost center that usage is attributed to.
  • An SMPP 3.4 client (interface_version 0x34). If you want receipts, a receiver or transceiver connection.

Credentials

Support creates your account and gives you the server, the port, your system_id (up to 15 characters) and your password (up to 8 characters, the most SMPP 3.4 allows). They are not published on this portal.

The same port takes encrypted and unencrypted connections: if your client opens with TLS (version 1.2 or later), the server detects it on its own. We recommend TLS.

The bind’s system_type, addr_ton, addr_npi and address_range are accepted but not validated.

Steps

  1. 01
    Open the connection and bind

    Send the first byte within 5 s; if you use TLS, finish the handshake within 10 s. The bind must arrive within 10 s and, overall, before 30 s have passed since you opened the connection.

  2. 02
    Send with submit_sm

    Over a transmitter or transceiver connection. Set registered_delivery to 0x01 if you want a receipt for each message.

  3. 03
    Store the message_id

    It arrives in the submit_sm_resp. It is the same one the receipt carries, character for character.

  4. 04
    Receive and confirm receipts

    They arrive as deliver_sm over your receiver or transceiver connections of the same account. Answer each one with deliver_sm_resp and status 0 within 60 s.

query_sm, submit_multi, data_sm, replace_sm, cancel_sm are not supported: they get generic_nack with 0x00000003 and the connection stays open.

Keeping the connection alive

  • Hablame sends you an enquire_link every 30 s, with or without traffic. Always answer it: after 2 in a row without an answer, the connection is closed.
  • If your client stops reading for 30 s, the connection is closed.
  • You can send your own enquire_link, but only after binding: before that they get 0x00000004.
  • To close, send unbind and wait for its response.

Limits

Examples

submit_sm fields

source_addr
The sender, up to 20 characters.
destination_addr
The destination number, up to 20 characters. Required: without it, 0x0000000B.
esm_class
0x40 if the text starts with a UDH header.
registered_delivery
0x01: a receipt with the final status, whatever it is. 0x02: a receipt only if the message fails. 0x00: no receipt. There are no intermediate notifications.
data_coding
The text encoding (table below).
short_message
The text, up to 254 octets. For longer text, use message_payload; if both arrive, short_message is used.
schedule_delivery_time
Not applied today: the message goes out right away. Do not use it to schedule sends.
validity_period
Accepted and stored as it arrives.

Encoding

In SMPP, GSM-7 text goes unpacked: one character per octet. If you pack it, it arrives garbled.

  • GSM-7 includes ñ, Ñ, é, É, ü, Ü, ¿, ¡. The accented vowels á, í, ó, ú, Á, Í, Ó, Ú are not included: text with them goes in UCS-2 (0x08).
  • In GSM-7, €, [, ], {, }, ~, \, ^, | take two characters each.
  • In UCS-2, an emoji outside the basic plane takes two characters.

Long messages

There are two ways to send text that does not fit in one part:

  1. Split it yourself, with a concatenation UDH header (IEI 0x00 with an 8-bit reference or 0x08 with a 16-bit reference) and esm_class 0x40, or with the sar_msg_ref_num, sar_total_segments and sar_segment_seqnum TLVs if you do not use UDH. If both arrive, the UDH wins.
  2. Send it whole in the message_payload TLV, without UDH, within the 64 KiB PDU limit.

If you split it, the server joins the parts before sending: it waits up to 60 minutes from the first one and accepts up to 255 parts. Parts are matched by organization, reference, total and destination, so you can send them over different connections of the same organization. Each part gets its own message_id and its own receipt.

An example receipt

short_message of a delivered receipt. Dates are in Colombia time.
id:0192f0c4-7b1e-7a3d-9c55-3e2a1b4c5d6e sub:001 dlvrd:001 submit date:2610241004 done date:2610241004 stat:DELIVRD err:000 Text:Hola Ana, tu pedido 

Expected responses

submit_sm_resp

With status 0 it carries the message_id: a version 7 UUID of 36 characters, one per PDU, including each part of a long message. With any other status, the message was not accepted: see the command_status table.

Delivery receipts

A receipt is the final status we know for your message. It does not guarantee that the person read it.

  • It arrives as a deliver_sm with esm_class 0x04 and the addresses swapped: source_addr is the phone you sent to and destination_addr is your sender.
  • There is one receipt per part. sub and dlvrd are always 001.
  • submit date is when we accepted the message and done date is when the outcome became known, both in Colombia time (UTC−5). Text: carries the first 20 printable ASCII characters of the message, so in UCS-2 it may be almost empty.
  • Read the status from the TLVs rather than the text: the text is informational and the TLVs are the standard form. user_message_reference is not returned.
Receipt text format
id:<message_id> sub:001 dlvrd:001 submit date:YYMMDDhhmm done date:YYMMDDhhmm stat:<status> err:<error> Text:<text>

How receipts reach you

  • Each receiving connection starts with 5 unconfirmed receipts at a time and can go up to 50 if you answer quickly.
  • If you do not answer a deliver_sm within 60 s, or answer with a non-zero status, the receipt is sent again. It may reach you more than once: drop duplicates by receipted_message_id.
  • If you have no receiving connection, receipts wait and keep being retried for up to 72 hours.

Common errors

The most frequent responses and what to do. The full list is in command_status codes.

Security

  • SMPP 3.4 limits the password to 8 characters. That is why your account only accepts connections from the IP addresses you authorized, and a bind from any other gets 0x0000000A.
  • After 5 failed binds in one minute from the same IP and system_id, the rest of that minute is rejected.
  • Use TLS 1.2 or later so your password and messages do not travel in clear text.
  • Keep the password in your secrets manager and never send it by email. If you think it leaked, email developers@hablame.co.

Related endpoints

SMPP does not use the REST API: there are no related endpoints. Inbound SMS arrive by webhook.

Next steps

Need help?

Was this page helpful?

See all support channels

Your cookie preferences

You decide what we measure. You can change your choice at any time. Rejecting takes no feature away from the documentation.

Privacy policy