Skip to Content

SMS API · version 2

SMS API reference.

Send SMS from your own systems over REST or SMPP: authenticate, send, track delivery and stay within your limits. Version 2 is the current version.

curl -X POST https://api.unecast.com/v2/send \
  -H "Authorization: Bearer $UNECAST_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "sms",
    "from": "YOURBRAND",
    "to": "94771234567",
    "message": "Your OTP is 482913",
    "priority": 3
  }'
REST API
https://api.unecast.com/v2
SMPP API
smpp://smsc.unecast.com:2775
Authentication
Bearer token per app (REST)
Standard rate limit
600 SMS submissions a minute

Quick start

  1. Open an SMS account. Register in the SMS portal with your work email and company details, then confirm your email. SMS has its own account, balance and credentials, separate from the WhatsApp platform.
  2. Get a sender ID and a balance. Request your sender ID in the portal and top up your prepaid balance. We register the sender ID and submit it for approval before your first send.
  3. Create an app. In the portal's Developer area, create an app and choose HTTP (REST API), or SMPP for high-volume systems. Each app has its own credentials.
  4. Send your first SMS. Call POST /v2/send with your token, as in the example above, then read its delivery status.

Authentication

Every REST call sends your app's token in the Authorization header:

Authorization: Bearer YOUR_TOKEN

Keep the token on your server and never put it in a web page or mobile app. A call without a valid token gets an HTTP 401 error (see Errors).

Endpoints

MethodPathWhat it does
POST/v2/sendSend an SMS
GET/v2/status/{message_id}Read the delivery status of one message
GET/v2/account/balanceRead your prepaid balance

All paths are relative to https://api.unecast.com, so the full REST base is https://api.unecast.com/v2. Requests and responses use JSON.

Send an SMS

POST https://api.unecast.com/v2/send with a JSON body:

FieldExampleWhat it is
channel"sms"Always sms for this API.
from"YOURBRAND"Your sender ID. It must be approved and active in your portal.
to"94771234567"The recipient: country code followed by the number, as in the example.
message"Your OTP is 482913"The text of the SMS. See Length and languages.
priority3A number from 0 (lowest) to 3 (highest). See Priority levels.
curl -X POST https://api.unecast.com/v2/send \
  -H "Authorization: Bearer $UNECAST_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "sms",
    "from": "YOURBRAND",
    "to": "94771234567",
    "message": "Your OTP is 482913",
    "priority": 3
  }'

Priority levels

ValueLevelUse it for
3HighestOTPs and alerts: anything the recipient is waiting for.
2HighGeneral messaging.
1LowLow-urgency messages.
0LowestMessages that are not urgent, such as notifications and marketing campaigns.

Keep 3 for truly time-critical messages, and send bulk campaigns at 0. The same levels apply to priority_flag over SMPP.

Keep the message ID from the send response: you need it to read the delivery status.

Length and languages

An SMS carries 160 characters in the standard GSM alphabet, or 70 in Unicode. Longer texts are split into parts and joined again on the phone; each part then carries a little less, because some space holds the joining information.

Text usesOne SMSEach part of a long SMS
Standard GSM alphabet (English letters, digits, common symbols)160 characters153 characters
Unicode (Sinhala, Tamil, emoji and other scripts)70 characters67 characters

One character outside the GSM alphabet switches the whole message to Unicode. The symbols { } [ ] ~ \ ^ | € are in the GSM alphabet but count as two characters each. Your portal's message details show each message's part count and cost.

Delivery status

Read one message's status with GET /v2/status/{message_id}:

curl https://api.unecast.com/v2/status/MESSAGE_ID \
  -H "Authorization: Bearer $UNECAST_TOKEN"
StatusWhat it usually means
pendingAccepted by Unecast and waiting to go out.
sentHanded to the mobile network; the delivery report has not arrived yet.
deliveredThe network reported delivery to the phone.
undeliveredThe network could not deliver it, for example to an unreachable number.
expiredThe network could not deliver it in time, for example because the phone stayed off.
rejectedRefused before delivery.
failedCould not be sent.

The same statuses, with each message's cost, appear in the portal's message log.

Rate limits

The standard limit is 600 SMS submissions a minute, an average of 10 a second. Spread your sends evenly rather than in bursts:

import time

for number in numbers:
    send_sms(number)  # your call to POST /v2/send
    time.sleep(0.1)   # 10 a second, 600 a minute
  • Large lists: use a campaign in the portal, which can also be scheduled.
  • Sustained high volume: connect over SMPP. To raise its throughput, open a support ticket in the portal under Messaging - SMS and choose Increase TPS (SMPP).
  • Need more on REST? Tell us your volume and we will look at your limit.

Sender IDs and countries

A sender ID is the name your customers see instead of a number, such as your brand. Request it in the portal under Sender ID settings. It shows as Pending while we register it and submit it for approval, then Active; a rejected request shows the reason. Only active sender IDs can send.

Sri Lanka is live on all major mobile networks, in any language. Other countries are switched on per account: request them in the portal's Country settings or tell us where you need to send.

SMPP

SMPP suits platforms that send high volumes or already speak SMPP. The Unecast SMSC uses the standard SMPP 3.4 protocol, so any standard SMPP client or library can connect. Log in with the system ID and password of an SMPP app you create in the portal's Developer area.

SettingValue
Addresssmpp://smsc.unecast.com:2775
Host and portsmsc.unecast.com, port 2775
ProtocolSMPP 3.4 (interface_version 0x34)
system_id and passwordThe login of your SMPP app. Each app has its own.
Bindbind_transceiver sends and receives delivery receipts on one connection. A bind_transmitter and bind_receiver pair also works.
Connection limitHow many binds the app can hold open at once, set on the app. The minimum is 1.
Allowed IPsAllow every IP address or host, or only the server IPs and hosts you list on the app.
ThroughputRaised on request: Support → Messaging - SMS → Increase TPS (SMPP).

A session, step by step

PDU                    You   SMSC Notes
bind_transceiver       ---------> system_id, password
bind_transceiver_resp  <--------- command_status 0x00000000
submit_sm              ---------> sender ID, number, text
submit_sm_resp         <--------- message_id
deliver_sm             <--------- delivery receipt
deliver_sm_resp        --------->
enquire_link           ---------> about every 30 s when idle
enquire_link_resp      <---------
unbind                 --------->
unbind_resp            <---------

submit_sm fields

FieldSet it to
source_addrYour active sender ID. For a name such as YOURBRAND, use source_addr_ton 5 (alphanumeric) and source_addr_npi 0. For a number, use TON 1 and NPI 1.
destination_addrCountry code followed by the number, such as 94771234567, with dest_addr_ton 1 (international) and dest_addr_npi 1 (E.164).
data_coding0 for the GSM alphabet, 8 for Unicode (UCS-2): Sinhala, Tamil, emoji and other scripts.
short_messageUp to 140 bytes: 160 GSM characters or 70 Unicode characters.
esm_class0x00 for a single SMS; 0x40 when short_message starts with a concatenation header (one part of a long SMS).
priority_flag0 (lowest) to 3 (highest), the same levels as the REST priority: 3 for OTPs and alerts, 0 for notifications and marketing.
registered_delivery1 to get a delivery receipt.

Long messages: split the text into parts of up to 153 GSM or 67 Unicode characters, start each part with a 6-byte concatenation header (the same reference number in every part, plus the part count and part number), and set esm_class to 0x40. Most SMPP libraries do this for you, as in the example below.

Delivery receipts

With registered_delivery set to 1, the receipt comes back as a deliver_sm with esm_class 0x04. It carries the message ID from your submit_sm_resp in the receipted_message_id field, and the standard receipt text in short_message:

id:MESSAGE_ID sub:001 dlvrd:001 submit date:2611051030 done date:2611051030 stat:DELIVRD err:000 text:Your OTP is 482913
statWhat it usually means
DELIVRDDelivered to the phone.
UNDELIVThe network could not deliver it, for example to an unreachable number.
EXPIREDNot delivered in time, for example because the phone stayed off.
REJECTDRefused before delivery.
ACCEPTD, DELETED, UNKNOWNOther final states defined by SMPP 3.4.

Answer every deliver_sm with a deliver_sm_resp, or the receipt may be sent again.

Keep the connection healthy

  • Keep it alive: send enquire_link about every 30 seconds when the link is idle, and answer the SMSC's enquire_link with enquire_link_resp.
  • Reconnect calmly: if the connection drops, wait a few seconds before you bind again, and wait longer after each failed try.
  • Limit what is in flight: keep only a small window of submit_sm waiting for a response, and stay within your throughput.
  • Slow down when asked: on 0x00000058 (throttled) or 0x00000014 (queue full), pause and retry that message later.
  • Close cleanly: send unbind and wait for unbind_resp before you disconnect.

Example: send over SMPP

# Python 3 with smpplib (pip install smpplib)
import os
import smpplib.client
import smpplib.consts
import smpplib.gsm

client = smpplib.client.Client("smsc.unecast.com", 2775)

# submit_sm_resp carries the message ID; deliver_sm carries the delivery receipt
client.set_message_sent_handler(
    lambda pdu: print("accepted", pdu.message_id))
client.set_message_received_handler(
    lambda pdu: print("receipt", pdu.receipted_message_id, pdu.short_message))

client.connect()
client.bind_transceiver(system_id=os.environ["SMPP_SYSTEM_ID"],
                        password=os.environ["SMPP_PASSWORD"])

# Splits long text, picks GSM (0) or UCS2 (8) and adds the UDH when needed
parts, data_coding, esm_class = smpplib.gsm.make_parts("Your OTP is 482913")
for part in parts:
    client.send_message(
        source_addr_ton=smpplib.consts.SMPP_TON_ALNUM,
        source_addr_npi=smpplib.consts.SMPP_NPI_UNK,
        source_addr="YOURBRAND",
        dest_addr_ton=smpplib.consts.SMPP_TON_INTL,
        dest_addr_npi=smpplib.consts.SMPP_NPI_ISDN,
        destination_addr="94771234567",
        short_message=part,
        data_coding=data_coding,
        esm_class=esm_class,
        priority_flag=3,  # 0 lowest to 3 highest: 3 for OTPs and alerts
        registered_delivery=True,
    )

client.listen()  # answers receipts with deliver_sm_resp and sends enquire_link when idle

Common command_status codes

CodeNameWhat to do
0x00000000ESME_ROKSuccess.
0x00000005ESME_RALYBNDAlready bound: don't bind twice on one connection.
0x0000000DESME_RBINDFAILBind failed: check the connection limit and allowed IPs on your SMPP app.
0x0000000EESME_RINVPASWDWrong password.
0x0000000FESME_RINVSYSIDWrong system ID.
0x0000000AESME_RINVSRCADRSender ID not valid: use an active sender ID and the right TON and NPI.
0x0000000BESME_RINVDSTADRRecipient number not valid: use the country code followed by the number.
0x00000014ESME_RMSGQFULQueue full: pause and retry later.
0x00000045ESME_RSUBMITFAILSubmit failed: check the fields and your balance, then retry.
0x00000058ESME_RTHROTTLEDOver your throughput: slow down and retry later.

Errors

Errors come back as JSON with an HTTP status code, a status of error and a readable message. For example, a call without a valid token returns HTTP 401:

{
  "status": "error",
  "message": "Authentication required. Please provide an Authorization header with your API key.",
  "code": 401
}

Check the HTTP status first, log the message, and do not retry a 401 until the token is fixed.

Routes and pricing

Transactional SMS, such as OTPs, alerts and order updates, goes out on a high-priority route. Promotional SMS goes to your opted-in lists. You pay per message from a prepaid balance, with no setup or monthly fees; read your balance with GET /v2/account/balance.

curl https://api.unecast.com/v2/account/balance \
  -H "Authorization: Bearer $UNECAST_TOKEN"

Rates in rupees and US dollars, and the Premium, HQ and Wholesale routes, are on the SMS gateway page. For large monthly volumes, ask for a quote by route.

SMS API questions

What is the SMS API rate limit?

The standard limit is 600 SMS submissions a minute, an average of 10 a second. For sustained higher volume, use SMPP and ask for a higher throughput through a support ticket, or tell us your volume.

Should I use REST or SMPP?

Use the REST API (https://api.unecast.com/v2) for most applications: it is JSON over HTTPS with a Bearer token. Use SMPP for high-volume platforms or systems that already speak SMPP; each SMPP app has its own login, connection limit and allowed IPs.

What are the SMPP connection details?

Connect to smpp://smsc.unecast.com:2775 (host smsc.unecast.com, port 2775) with standard SMPP 3.4. Bind as a transceiver with the system ID and password of an SMPP app from the SMS portal, set registered_delivery to 1 for delivery receipts, and send enquire_link about every 30 seconds when idle.

Which priority should I use?

Priority is a number from 0 (lowest) to 3 (highest), over REST and SMPP. Use 3 for OTPs and alerts, 2 for general messaging, 1 for low-urgency messages and 0 for notifications and marketing campaigns.

Can I send SMS in Sinhala or Tamil?

Yes. Sinhala and Tamil are sent as Unicode, so one SMS carries 70 characters and each part of a longer message carries 67.

How do I check whether an SMS was delivered?

Keep the message ID from the send response and call GET /v2/status/{message_id}. Statuses include pending, sent, delivered, undelivered, expired, rejected and failed.

Do I need a sender ID before I can send?

Yes. Request it in the SMS portal; it shows as Pending while we register it and submit it for approval, and only active sender IDs can send.

Building on the SMS API?

Our engineers can review your setup, suggest REST or SMPP, and help with sender IDs and volumes. Call +94 77 600 3273 or write to sales@unecast.com.

Talk to us now+94 77 600 3273sales@unecast.comMonday to Friday, 9 AM to 6 PM