Sending over SMPP
Messages go in submit_sm: one PDU per message, or one per part of a long message.
The fields
| Field | What to put in it |
|---|---|
source_addr | The sender name: up to 11 characters if it contains anything besides digits, up to 15 digits otherwise |
destination_addr | The recipient's number in international format, digits only: 447700900123. Other characters are stripped |
data_coding | How to read the bytes of short_message: 0 — GSM 7-bit, 1 — ASCII, 3 — Latin-1, 8 — UCS-2 |
esm_class | 0x40 when the text starts with a UDH (a part of a long message), otherwise 0 |
short_message | The text, up to 255 octets in one PDU |
registered_delivery | Anything: a receipt is sent for every message regardless |
schedule_delivery_time | Send later instead of now. Absolute or relative time, to the minute |
validity_period | How long the message stays worth delivering: from one minute to 72 hours, 72 hours if empty. Absolute or relative time |
TON and NPI of both addresses, service_type, protocol_id, priority_flag,
replace_if_present_flag and sm_default_msg_id are not used: put whatever your library
sends by default. The message_payload field is not read either — the text goes in
short_message only.
The sender name must be allowed for your account. A name reserved by another client, a
blocked or protected name, or — while the account is on moderation — a name not yet verified
with the operators is rejected with a receipt, not in the answer to submit_sm: see the
err:003 code in Delivery receipts.
A flash message — one that opens on the screen at once — is sent with data_coding
0x10 (GSM 7-bit) or 0x18 (UCS-2). It must fit in one part.
The answer
submit_sm_resp returns a message_id — a decimal number, one for every submit_sm, that
is, one per part. Keep it: the delivery receipt carries the same value.
A zero command_status means the message is accepted. Checks that need your balance, the
recipient's operator or the sender name come after that, and a message that fails them gets a
REJECTD receipt instead of an error in the answer. What arrives in the answer itself is
listed in Errors and limits.
Encoding and length
| Encoding | One message | One part of a long message |
|---|---|---|
| GSM 7-bit | 160 characters | 153 characters |
| UCS-2 | 70 characters | 67 characters |
In GSM 7-bit the characters ^ { } \ [ ~ ] | and € take two places each. In UCS-2 an emoji
takes two.
data_coding tells us how to read your bytes; the encoding toward the operator is chosen from
the text itself, so a message in Latin letters you send as UCS-2 goes out as GSM 7-bit. With data_coding 0 the bytes are read as GSM 7-bit characters, one per
octet: plain ASCII @, $ and _ turn into other characters there. For text that comes
from your system as plain ASCII or Latin-1, set 1 or 3.
Before counting, line breaks \r\n become \n, a non-breaking space becomes an ordinary
one, a dash – becomes -, and typographic quotes become ".
Long messages
A text longer than one message is sent in parts, and both ways of marking them are understood:
- UDH in the body of each part, with
esm_class0x40: the concatenation element with an 8-bit (0x00) or a 16-bit (0x08) reference; - SAR fields
sar_msg_ref_num,sar_total_segmentsandsar_segment_seqnum, when there is no UDH.
Parts may arrive in any order. They are joined on our side and split again for the operator; a set that stays incomplete for two days is dropped without a receipt.
You pay for as many parts as you sent or as we counted, whichever is greater — the same rule as everywhere else in the cabinet, so the number in your report matches the number on your invoice.
Scheduled sending and validity
schedule_delivery_time holds the message until the given minute. A value we cannot read is
ignored, and the message goes out at once.
validity_period is passed to the operator, held between one minute and 72 hours. A message
still waiting on our side when its validity runs out — or after 72 hours, if you set none — is
not sent: the money for it is returned, and an EXPIRED receipt comes back.