Introduction
© 2006 - 2024 Lekab Communication Systems AB. Version 5.1.168, 2024-09-02.
This is a Web Service using HTTP POST
requests of two different formats to
send batches of, potentially, many SMS messages: tens or hundreds of thousands.
Where our non-batch web service returns a result only when all messages have been processed and queued for sending, this batch web service makes a quick validation of the input while writing a temporary file and returns a batch id already when the validated batch has been submitted to a background batch processing system. This serves to avoid time-out conditions for large requests; users of Lekab’s older SOAP Batch web service will be familiar with the concepts.
If the batch does not pass validation (e.g. due to the presence of invalid phone numbers, lack of mandatory parameters or invalid credentials), none of the messages in the batch will be sent, and the service returns a relevant HTTP error response code and a json document with an error message.
We offer HTTP GET
and HTTP POST
versions of endpoints for retrieving
batch information and SMS delivery status for messages in a batch. The batch id,
received upon sending, is used here to check the status. Many of the syntax and
authentication details for these endpoints are very similar to the related
Lekab Sms Rest Web Service (cf. that documentation).
Since different REST client software libraries attain varying degrees of
sophistication, the aim has been to make the demands on the sending
HTTP POST
body complexity as low as possible.
Accordingly, multi-part MIME input formats are
not demanded (or supported), because of this uncertainty whether a customer’s
HTTP
client can supply any given version.
Instead the /batchsend
HTTP POST
endpoint has two branches:
/batchsend/json
and /batchsend/list
, where the /json
endpoint takes
a single json document in the HTTP
body and all overall parameters and
all individual recipient data are included as fields in this json object, while
the /list
endpoint accepts the overall parameters as query
parameters in the URL and the individual recipient data in a line based
semicolon separated list (essentially a .csv file with ';' separators) in
the HTTP
body. In the simplest case, this list is a list of recipient phone
numbers, one per line.
UTF-8
encoding is assumed everywhere (the standard for json), and where URL-encoding of input data
is necessary (e.g. for URL query parameters), the underlying encoding is UTF-8
(the standard for
url encoding).
Every endpoint returns a response in the HTTP
response body as a json document.
The formats of the input and output json and list documents and the input url parameters are described below.
Different authentication methods available for requests
Every request to the service must include authentication, i.e.
username and password (or equivalent). For POST
requests (except /batchsend/list
)
these can be given in in the corresponding fields in the JSON
document which is sent
in the (automatically HTTPS = SSL/TLS
encrypted) HTTP
body. For POST /batchsend/list
and all GET
requests, username and password can instead be supplied in the U
and P
URL parameters.
Note that everything in the URL after the host name is also part of the encrypted request,
so URL parameters are equally secure during transfer as parameters in the body or headers.
However, calling web services from a web browser URL line may lead to authentication
credentials being stored in the browser history, which can potentially be unsafe.
We also offer three different alternative ways of supplying these username and
password credentials available in both the GET
and POST
cases:
-
Username and password can be given as standard Basic authentication, in which the header
"Authorization"
should have the value"Basic " + token
, where the token is theBase64
encoding of (aUTF-8
byte array representation of)username:password
. Heretestuser:testpass
will be encoded asdGVzdHVzZXI6dGVzdHBhc3M=
, so the header with key"Authorization"
should have the value"Basic dGVzdHVzZXI6dGVzdHBhc3M="
-
Username and password can be given in the HTTP headers,
X-Lekab-Userid
andX-Lekab-Password
, respectively. The values have to be theBase64
encoding of (aUTF-8
byte array representation of) the username or password to allow non-US-ASCII characters. Here testuser will be encoded asdGVzdHVzZXI=
and testpass asdGVzdHBhc3M=
-
An API key obtained from Lekab can be used as a query parameter
key
, as the value of the headerX-API-Key
or as the JSON fieldapikey
in thePOST
request body (except for/batchsend/list
). The length of the key varies depending on the length of the username (which is contained within the key).TUxVOmRHVnpkSFZ6WlhJOjlKUUczTXU2TVZVU1Exd3Y
is a possible example key for the usernametestuser
. The key is independent of the account password.
Whichever method of authentication is used, parameter values pertaining to other authentication methods should be omitted or set to the empty string "".
Supported character sets in the resulting SMS and pricing issues
The character set used in the input to the API does not affect the resulting SMS. Instead, the characters that are requested to be sent will determine the size and pricing of the message.
Most network operators globally support all printable characters in SMS messages. They also support the sending of longer SMS messages by dividing the content into several SMS message parts (with some exceptions, like South Korea). An SMS message part is limited in size to 140 bytes; longer messages will require more parts. The character set used, not the language, will determine how many parts are needed. The pricing is based on the number of SMS message parts sent. Normally, the recipient’s mobile handset will automatically reassemble the parts of a divided message in the correct order, without any action needed by the recipient.
The GSM standard regulates SMS communication globally. While all characters are supported, some characters used in Western European languages are given special treatment. Two character encodings (character sets) are supported by almost all network operators in the world, and therefore by us: GSM-7 and UCS-2.
By GSM-7 we mean the internationally common GSM-7 alphabet according to GSM 03.38 / 3GPP 23.038 without any national language shift table (only the basic character extension). See for example https://en.wikipedia.org/wiki/GSM_03.38 for details.
The GSM-7 encoding uses 7 bits per character to encode only characters from these Western European languages (including numbers and some punctuation), while the UCS-2 encoding can encode characters from any Unicode alphabet and uses 16 bits per character. If every character in a message can be encoded with GSM-7, the message will employ the more compact GSM-7 encoding. If any character in a message cannot be encoded with GSM-7, UCS-2 will be used for the entire message.
Since the GSM-7 is a 7-bit character set, 160 characters will fit into one 140 bytes SMS part. The UCS-2 is a 16-bit character set and can accommodate only 70 characters in a 140 bytes SMS part. If a GSM-7 encoded message is longer than 160 characters, or a non-GSM-7 encoded message is longer than 70 characters, it will be divided into more than one part. Due to how such parts are constructed, multi-part SMS messages can only fit 153 GSM-7 characters or 67 UCS-2 characters per part. All parts of a message will use the same encoding, so they will all be GSM-7 or all UCS-2.
The inclusion, even accidentally, of a non-GSM-7 encodable character in a message will therefore transform it into a UCS-2 encoded message. This message will have a larger number of shorter parts, and the send-out will be more costly. Therefore, when sending SMS messages in Western European languages, it is often advisable to be on the lookout for any such characters that may be included in the message. For instance, some characters automatically generated in some circumstances by Microsoft Word, like curved citation marks (curved quotes) and unbreakable spaces, are not included in the GSM-7 character set. French vowels with the accent circonflexe also do not fit into GSM-7. Unsurprisingly, Cyrillic, Arabic, Chinese, Thai, Japanese and many other alphabets are not included, and neither are emojis, while ordinary text in English, Swedish, Finnish, German and similar languages will fit into the GSM-7 encoding. The Euro-sign (European Union currency symbol) is included in the GSM-7 basic character extension, which we support.
1. The /batchsend/json
and /batchsend/list
endpoints
Used for sending a batch of SMS
1.1. POST /batchsend/json request example
probably from an application
https://secure.lekab.com/restsms/api/batchsend/json?DB=Y&DNN=Y&DNM=Y
With the contents of the HTTP body:
{"username":"testuser","password":"testpass","from":"LEKAB",
"message":"Hallå där!","batchconversation":"Sendout 123",
"batch":[
{"t":"46701223344"},
{"t":"447711223344","m":"Hello there!"},
{"t":"46702345678"},
{"t":"46703344556"},
{"t":"46704421232"}
]
}
1.2. POST /batchsend/list request example
probably from an application
https://secure.lekab.com/restsms/api/batchsend/list?U=testuser&P=testpass&F=LEKAB&M8=Hall%C3%A5+d%C3%A4r!&BX=Sendout+123&DB=Y&DNN=Y&DNM=Y
With the contents of the HTTP body:
# this is Sendout 123
46701223344
447711223344;Hello there!
46702345678
46703344556
46704421232
1.2.1. Explanation of parameters for /batchsend/json and /batchsend/list
/json json key |
/list query param |
json value (strings quoted) | query param value (strings without quotes) | |
---|---|---|---|---|
username |
U |
string |
string |
username of the LEKAB SMS sending account |
password |
P |
string |
string |
password of the LEKAB SMS sending account |
apikey |
key |
string |
string |
API key of the LEKAB SMS sending account |
from |
F |
string |
string |
sender id of the SMS (ignored for two-way SMS) |
message |
M8 |
string (UTF-8) |
string URL-encoded |
Message to send. May contain template style place holders or other place holders or not |
templateid |
TPID |
string containing integer |
string |
Id of saved template to use as text instead of message parameter. May contain template style place holders or other place holders or not |
batchconversation |
BX |
string |
string URL-encoded |
conversation id identifying the batch (max 100 characters) |
costcenter |
C |
string |
string |
grouping in billing (max 255 characters) |
validminutes |
V |
string containing integer |
string |
validity time of SMS (default is 1440 i.e. 24h) |
defaultcountrycode |
D |
string containing digits |
string containing digits |
replaces leading zero in t numbers from file starting with single zero |
"check mobile number" use as query in url |
CMN |
n/a |
T, TRUE, Y or YES |
Check that numbers are in probable mobile number series according to Google PhoneNumberUtil library, raise an error if not |
"drop blocked" use as query in url |
DB |
n/a |
T, TRUE, Y or YES |
Silently drop numbers blocked for the user (if not set, sending will not go through if blocked number is found) |
"drop non mobile" use as query in url |
DNM |
n/a |
T, TRUE, Y or YES |
Silently drop numbers not in a probable mobile number series according to Google library (if not set, sending will be attempted to non-mobile number, leading to a cost) |
"drop non number" use as query in url |
DNN |
n/a |
T, TRUE, Y or YES |
Silently drop numbers that are obviously not phone numbers (if not set, sending will not go through if e.g. "46MONKEY" is found) |
replacecharacters |
R |
boolean (default false) |
T, TRUE, Y or YES |
replace certain characters not in the GSM-7 standard character set with similar characters in that set (e.g. non-breaking space u00A0 replaced by ordinary space u0020). Only applied if enabled for the account; contact Lekab sales for details. |
holders |
H |
json list of string |
comma separated URL-encoded strings |
place holder strings in the message, that can be replaced for each individual recipient: 1st place holder with 1st substituent etc. |
templateHolders |
TPH |
json list of string |
comma separated URL-encoded strings |
saved template style curly bracket place holder labels in the message, e.g., abc is label for "{Text:abc}" or "{DateTime:abc:Scheduled at:}", that can be replaced: 1st place holder with 1st substituent etc. |
batch |
json list of objects containing t, m, i, s fields (see below) |
individual recipient list for /json endpoint |
||
t |
string |
to number: phone number in international format: plusses, spaces, hyphens, full stops and parentheses will be disregarded |
||
m |
string |
individual message (only to this recipient) |
||
i |
string |
conversation id for this recipient (if omitted, recipient shares the batch conversation id) |
||
s |
json list of string |
text substitutions for the corresponding placeholders in message (see holders parameter) |
||
scheduletime |
AT |
string containing time |
string URL-encoded UTF-8 containing time |
Schedule sendout for sending in the future. ISO 8601 standard format like "2022-02-14T15:00:00Z" or "2022-02-14T15:00Z" or "2022-02-14T17:00:00+02:00 or "2022-02-14T13:00-02:00" |
There is a duplicate check, so that the exact same message will not be sent to the exact same number within a batch. No check on duplicates from other batches is performed.
Note that the four error handling flags CMN
, DB
,DNM
,DNN
have to be on the command line, not inside the json document, for technical reasons having to do with the
possibility of very large sendouts. Mobile number check via the Google PhoneNumberUtil library is offered as an option, since users may want to send to some number series,
especially the extra long numbers sometimes used for Internet-of-Things devices, that are not recognized as possible mobile numbers. Number checks against the user’s blocked
list and against obvious non-numbers (e.g. containing letters) are always active and the choice there is whether to edit the phone number list or to drop the numbers silently.
When scheduling a batch to a future send time, the format of the time string is strictly constrained.
The date must be in the format YYYY-MM-DD
then there has to be a T
capital letter T, then HH:MM:SS
in a 24-hour scheme,
and at last, a time zone marker, which may be either Z
or +01:00
or -01:00
(with any reasonable value instead of 01:00
).
The Z
means the same as +00:00
i.e. UTC/Zulu/GMT time with no time zone difference or summer time and the plus or minus
deviations are deviations from Z. Swedish winter time is +01:00
and Swedish summer time is +02:00
. Scheduling to
a time in the past or the next 3 minutes is not allowed.
1.2.2. HTTP response to /batchsend/json and /batchsend/list
A successful request will return 200 OK and a json document of the following format. Note that the request for sending may be successful even if the send status of some or all SMS sendings are failed.
The subsequent overall fate of the batch can be found with the /batchinfo
endpoints.
A list of message IDs belonging to the batch can be obtained with the /batchmessageid
endpoints. This list can be used when querying for the status of individual messages.
A successfully sent message may sometimes not be delivered due to external factors
(phone turned off, phone subscription expired, no such subscriber).
The later fortune of the messages in the batch can be followed via the /batchmessagestatus
endpoints.
All successful responses will have status Received
The Content-Type
header of the response
is application/json
for all responses.
{
"batchid" : "490922766334210048",
"batchconversation" : "Sendout 123",
"batchstatuscode" : 1,
"batchstatusdescription" : "Received"
}
1.2.3. Explanation of response to /batchsend/json and /batchsend/list
json key | json value (strings quoted) | |
---|---|---|
batchid |
string |
id of this batch, used in the status endpoints to refer to the batch |
batchconversation |
string |
conversation id for the batch supplied when sending to identify the batch |
batchstatuscode |
integer |
the status of the batch (see Batch status table) as an integer |
batchstatusdescription |
string |
description of the status of the batch (see Batch status table) |
1.2.4. Batch status
A batch has been fully validated, processed and queued for sending to the operator when the returned status is 0 (Ok). Single-digit codes are still in progress, while double-digit codes are error conditions.
Status Code | Description |
---|---|
0 |
Ok |
1 |
Received |
2 |
Processing |
3 |
Validating |
7 |
Scheduled |
10 |
Unexpected error |
11 |
Quota exceeded |
12 |
Maximum batch size exceeded |
13 |
Access Denied |
14 |
Validation error |
15 |
Dropped due to send time restrictions |
99 |
Batch Aborted |
1.2.5. Format of the list for /batchsend/list
The supplied list should have lines of the following format:
<phone number>;<message>;<conversation>;<substitution 1>;<substitution 2>; ...
where the phone number is mandatory and all other fields are optional.
The semicolons must be present up until right before the last supplied optional field. Fields that are not supplied will have the value "" (empty string) in substitutions.
-
The phone number should preferably be in international format without any long-distance prefix (like 00). Alternatively, a beginning zero will be replaced by the default country code supplied in the call. Punctuation, namely, hyphen, parentheses, plus sign and full stops, will be removed. So a format like 46701234567 is preferred, but +46(70)123.45.67 will work and 0701-234567 will also work if "46" is the default country code.
-
The message is an individual message to be used for this recipient phone number only. It will run through a URL decoding function, so characters that are replaced upon URL decoding will have to be URL encoded to survive. This is especially important for "+", which will be replaced by space, "%" which has a special meaning in URL encoding and ";" which is the separator between fields on a line in this file. Use %2B for "+", %3B for ";" and %25 for "%". Other UTF-8 characters will survive, but it is perfectly fine to URL encode all non-URL characters, with %C3%96 for "Ö" etc. if that is preferred (e.g. by an automatic function). If no message is supplied, the common message for the batch will be used.
-
The conversation is a reference (max 100 characters) to the individual message, to be used at the sender’s convenience. It will run through a URL decoding function, like the message, so similar precautions are needed for special characters. If no individual conversation id is supplied, the common conversation id for the batch is used for this recipient.
-
The substitutions are texts that will replace the corresponding placeholder strings in the (common) message. They will each run through a URL decoding function, like the message, and similar precautions are needed. Omitted substitution fields have the value "" (the empty string), so the corresponding placeholder will disappear. Excessive substitution fields (more than the number of placeholders) will be ignored.
-
Lines that are empty or only contain spaces are ignored.
-
Lines where the first non-space character is # (hash mark) will be ignored and can be used for comments.
-
We recommend that the last line of the file end with a line break.
-
There are no provisions for using any other order of the fields on the line. The proper order must be arranged by the sending software.
Example file with valid lines:
# This is an example file
46701234567;;conversation001;Karin;Stockholm City
46701223344;;conversation002;Sven;G%C3%B6teborg+C
46701223355;Special message: go back to bed;conversation003
46702112233;;conversation004
46702112266;;conversation005;Björn+Borg;Södertälje Syd
which could e.g. be used with the message:
Hello NAME! Your train leaves in one hour from the station STATION. Love, National Train Service
and the placeholders
H=NAME,STATION
The simplest possible list example (everyone gets the same message) is a list of phone numbers separated by line breaks:
46701234567
46701223344
46701223355
46702112233
46702112266
1.2.6. Example Python 3 code for /batchsend/json
import json
import requests
import base64
sendurl = 'https://secure.lekab.com/restsms/api/batchsend/json'
jsondata = {}
jsondata['from']='Lekab'
jsondata['message']='Spidey Sense Members get 20% off everything in the web shop on Wednesday! Love, Spiderman'
jsondata['batchconversation']='wed_campaign_feb'
b = []
b.append({"t":"46701223344"})
b.append({"t":"447711223344", "m":"You only get 10% off, because you are British!"})
b.append({"t":"46702345678"})
b.append({"t":"46703344556"})
b.append({"t":"46704421232"})
jsondata['batch'] = b
json_data = json.dumps(jsondata)
authstringarray="testuser:testpass".encode('utf-8')
authbase64=base64.b64encode(authstringarray).decode('utf-8')
headers={'Authorization':'Basic '+ authbase64, 'Content-Type':'application/json'}
response = requests.post(sendurl, data=json_data, headers=headers)
sendresp = response.json()
print("Batch " + sendresp["batchid"] + "(" + sendresp["batchconversation"] + ") gets status " + sendresp["batchstatusdescription"])
will output
Batch 490922766334210048(wed_campaign_feb) gets status Received
1.2.7. Example Python 3 code for /batchsend/list
import json
import requests
import base64
import urllib.parse
sendurl = 'https://secure.lekab.com/restsms/api/batchsend/list'
jsondata = {}
jsondata['from']='Lekab'
sendurl += '?F=' + jsondata['from']
jsondata['message']='Spidey Sense Members get 20% off everything in the web shop on Wednesday! Love, Spiderman'
sendurl += '&M8=' + urllib.parse.quote_plus(jsondata['message'])
jsondata['batchconversation']='wed_campaign_feb'
sendurl += '&BX=' + urllib.parse.quote_plus(jsondata['batchconversation'])
authstringarray="testuser:testpass".encode('utf-8')
authbase64=base64.b64encode(authstringarray).decode('utf-8')
headers={'Authorization':'Basic '+ authbase64}
with open('C:/Users/Bob/Documents/WebCampaigns/wednesday_february.csv', 'rb') as f:
response = requests.post(sendurl, data=f, headers=headers)
sendresp = response.json()
print("Batch " + sendresp["batchid"] + "(" + sendresp["batchconversation"] + ") gets status " + sendresp["batchstatusdescription"])
where the file wednesday_february.csv contains (note the URL-encoding of the percent sign in the second message):
# this is wednesday_february
46701223344
447711223344;You only get 10%25 off, because you are British!
46702345678
46703344556
46704421232
will output
Batch 490922766334210048(wed_campaign_feb) gets status Received
1.2.8. Use of saved text templates and substitution of template style place holders
It is sometimes convenient to use a set of standard message templates where only a part of the message text is
unique to the individual message. In such a template, some character sequences function as place holders,
which are to be substituted with the individualized text pieces. In the web portal, such templates can be
edited and stored with an id. The id of the template is shown on the editing page in the newest version of
the web portal, and is used in this API with the templateid
/ TPID
parameter. If a template id is given,
any explicit message given in the message
/ M8
parameters is ignored. Even where no template id is given,
a template text with place holders for substitutions can be equally well be supplied as the message. That is,
use of a saved template and use of place holder substitution are independent features that may be used alone
or together.
In the newest version of the web portal, the feature for editing and saving text templates is improved to allow a use case where logged-in users send single SMS messages by manually adding individual data for slots in the template message into input boxes on the SMS sending web page, allowing a coherent messaging strategy between different recipients.
When editing this type of template in the web portal, convenient buttons add curly bracket style place holders
of the form {Text:customer}
or {Text:ITEMNO}
or {Text:City:Location of the store}
or {DateTime:today}
.
Here customer
, ITEMNO
, City
and today
are labels referring to these place holders.
In this API, there is a short-cut to substitute such template derived place holders in in the same way
as place holders without curly brackets, taking care to keep the upper-case and lower-case of the label
exactly as in the template. Any curly bracket place holders not given a substitution value for a recipient are
replaced with the empty string in the output message.
Note that the web portal template editing page can also add place holders where data pertaining to the logged-in user or the address book contact of the recipient is to be extracted into the message, and these place holder types are not supported in the batch API, which is primarily aimed at use without reference to contacts in any address books stored with us, and without a logged-in manual web portal user.
Thus, place holders can be listed exactly as they occur in the template, using the holders
/ H
parameter.
When "holders":["NAME", "THE CITY"]
or H=NAME,THE+CITY
are specified, the text:
Hello NAME! You can pick up your delivery at our store in THE CITY. Best regards, Our Company
will be replaced for a given recipient, so that NAME
is replaced by the first substituent in the "s"
json list,
or, in the /list
endpoint, with the text after the third semicolon on the input line. Likewise for THE CITY
being
replaced by the second substituent in the "s"
json list, or, in the /list
endpoint, with the text after the fourth
semicolon.
But curly bracket saved template style place holders can also be referred to via their label, using the
templateHolders
/ TPH
parameter.
When "templateHolders":["name", "City"]
or TPH=name,City
are specified, the text:
Hello {Text:name}! You can pick up your delivery at our store in {Text:City}. Best regards, Our Company
will give a similar result as the previous example.
In a case where both plain style holders
/ H
and curly bracket style templateHolders
/ TPH
are used,
the first substituents refer to the holders
, followed by the templateHolders
. This use mode is allowed
but may be confusing. If any labels used inside the curly bracket place holders happen to coincide exactly
with plain style place holders, results are unpredictable. Do not do that! H=name&TPH=name
is a bad idea!
2. The /batchinfo
endpoint
Used to retrieve the current status of a batch that was sent earlier. Outputs the same info that is returned when sending, but with the current status (see Batch Status table).
2.1. GET request example
e.g. from web browser or curl, but in real use-cases probably from an application
curl https://secure.lekab.com/restsms/api/batchinfo?U=testuser&P=testpass&BI=490922766334210048
2.2. POST request example
Probably from an application
https://secure.lekab.com/restsms/api/batchinfo
with the contents of the HTTP body:
{
"username" : "testuser",
"password" : "testpass",
"batchid" : "490922766334210048"
}
2.2.1. Explanation of parameters for /batchinfo
POST json key | GET query param | json value (strings quoted) | query param value (strings without quotes) | |
---|---|---|---|---|
username |
U |
string |
string |
username of the LEKAB SMS sending account |
password |
P |
string |
string |
password of the LEKAB SMS sending account |
apikey |
key |
string |
string |
API key of the LEKAB SMS sending account |
batchid |
BI |
string |
string |
batch id of the batch for which current status is to be retrieved |
2.2.2. HTTP response to /batchinfo
A successful request will return 200 OK and a json document of the
following format. The Content-Type
header of the response
is application/json
for all responses.
{
"batchid" : "490922766334210048",
"batchconversation" : "Sendout 123",
"batchstatuscode" : 0,
"batchstatusdescription" : "Ok"
}
When a status of 0 (Ok) is returned, the batch has been successfully processed and queued for sending to the operator. Depending on the batch size and which operators are involved, the actual SMS sending may take less than a second up to hours, but the status 0 is a final status and will not change further. Other single-digit codes are still in progress, and will have changed upon later checking, while double-digit codes are final error conditions (see Batch status table).
2.2.3. Explanation of response to /batchinfo
json key | json value (strings quoted) | |
---|---|---|
batchid |
string |
id of this batch, used in the status endpoints to refer to the batch |
batchconversation |
string |
conversation id for the batch supplied when sending to identify the batch |
batchstatuscode |
integer |
the status of the batch (see Batch status table) as an integer |
batchstatusdescription |
string |
description of the status of the batch (see Batch status table) |
2.2.4. Batch status
A batch has been fully validated, processed and queued for sending to the operator when the returned status is 0 (Ok). Single-digit codes are still in progress, while double-digit codes are error conditions.
Status Code | Description |
---|---|
0 |
Ok |
1 |
Received |
2 |
Processing |
3 |
Validating |
10 |
Unexpected error |
11 |
Quota exceeded |
12 |
Maximum batch size exceeded |
13 |
Access Denied |
14 |
Validation error |
15 |
Dropped due to send time restrictions |
99 |
Batch Aborted |
2.2.5. Example Python 3 code
import json
import requests
info = {"username" : "testuser", "password": "testpass", "batchid" : "490922766334210048"}
info_json = json.dumps(info)
url = 'https://secure.lekab.com/restsms/api/batchinfo'
response = requests.post(url, data=info_json)
inforesp = response.json()
print("Batch " + inforesp["batchid"] + "(" + inforesp["batchconversation"] + ") gets status " + inforesp["batchstatusdescription"])
will output
Batch 490922766334210048(wed_campaign_feb) gets status Ok
3. The /batchmessageid
endpoint
Used to retrieve a list of all the message ids in a batch that was sent earlier. It is only when /batchinfo returns a 0 (Ok) status, that the full list of ids will be available.
3.1. GET request example
e.g. from web browser or curl
curl https://secure.lekab.com/restsms/api/batchmessageid?U=testuser&P=testpass&BI=490922766334210048
3.2. POST request example
Probably from an application
https://secure.lekab.com/restsms/api/batchmessageid
with the contents of the HTTP body:
{
"username" : "testuser",
"password" : "testpass",
"batchid" : "490922766334210048"
}
3.2.1. Explanation of parameters for /batchmessageid
POST json key | GET query param | json value (strings quoted) | query param value (strings without quotes) | |
---|---|---|---|---|
username |
U |
string |
string |
username of the LEKAB SMS sending account |
password |
P |
string |
string |
password of the LEKAB SMS sending account |
apikey |
key |
string |
string |
API key of the LEKAB SMS sending account |
batchid |
BI |
string |
string |
batch id of the batch for which current status is to be retrieved |
3.2.2. HTTP response to /batchmessageid
A successful request will return 200 OK and a json document of the
following format. The Content-Type
header of the response
is application/json
for all responses.
{
"messageids" : [ "180024553", "180024554", "180024556", "180024558", "180024559" ]
}
When a status of 0 (Ok) is returned when calling /batchinfo
, the batch has been
successfully processed and queued for sending to the operator. At that point forward,
a call to /batchmessageid will return the full list of the messageids.
3.2.3. Explanation of response to /batchmessageid
json key | json value (strings quoted) | |
---|---|---|
messageids |
json list of string |
ids of the messages in the batch |
3.2.4. Example Python 3 code
import json
import requests
ids = {"username" : "testuser", "password": "testpass", "batchid" : "490922766334210048"}
ids_json = json.dumps(ids)
url = 'https://secure.lekab.com/restsms/api/batchmessageid'
response = requests.post(url, data=ids_json)
idsresp = response.json()
for s in idsresp["messageids"]:
print("id=" + s)
will output
id=180024553
id=180024554
id=180024556
id=180024558
id=180024559
4. The /batchmessagestatus
endpoint
Used to retrieve the statuses of the SMS messages in a batch that was sent earlier.
This endpoint is multi-functional, depending on which of the input parameters are supplied. It can either retrieve unread statuses of SMS messages sent in a batch, or retrieve the statuses for a list of given SMS message ids (independent on whether they were read before or not).
-
You can either give a batch id and/or a batch conversation id, which will request a number of statuses (up to the maxnum parameter, which defaults to 1000 and is maximally allowed to be 10000) of statuses from the specified batch(es). This mode of calling has markasread defaulting to true, and the intended way it is supposed to work is that one reads statuses for chunks of the batch until no new statuses appear.
-
Or you can give a list of message ids and/or message conversation ids to get the statuses for all your batch messages with those ids. Here markasread defaults to false, but you can set it to true if you want to mark the message statuses as read.
If you give any message ids and/or conversation ids, the batch id and batch conversation id parameters will be ignored.
4.1. GET request example
e.g. from web browser or curl
curl https://secure.lekab.com/restsms/api/batchmessagestatus?U=testuser&P=testpass&I=180024553,180024554,180024556
4.2. POST request example
Probably from an application
https://secure.lekab.com/restsms/api/batchmessagestatus
with the contents of the HTTP body:
{
"username" : "testuser",
"password" : "testpass",
"messageids" : [ "180024553", "180024554", "180024556" ]
}
4.2.1. Explanation of parameters for /batchmessagestatus
POST json key | GET query param | json value (strings quoted) | query param value (strings without quotes) | |
---|---|---|---|---|
username |
U |
string |
string |
username of the LEKAB SMS sending account |
password |
P |
string |
string |
password of the LEKAB SMS sending account |
apikey |
key |
string |
string |
API key of the LEKAB SMS sending account |
batchid |
BI |
string |
string |
batch id of the batch for which current status is to be retrieved |
batchconversation |
BX |
string |
string |
batch conversation id of the batch for which current status is to be retrieved |
messageids |
I |
json list of string |
comma separated strings |
list of ids of the SMS for which send status is to be retrieved |
messageconversations |
X |
json list of string |
comma separated strings |
list of conversation ids of the SMS for which send status is to be retrieved |
maxnum |
N |
integer (default 1000, max 10000) |
integer |
max number of statuses to retrieve (ignored if ids are listed) |
markasread |
R |
boolean (default true or false) |
F, FALSE, N, NO, T, TRUE, Y or YES |
flag whether the status should be marked as read (defaults to false if message ids or message conversation ids are given, true if no such ids are given) |
4.2.2. HTTP response to /batchmessagestatus
A successful request will return 200 OK and a json document of the
following format. The Content-Type
header of the response
is application/json
for all responses.
{
"statuses" : [ {
"batchid" : "490922766334210048",
"batchconversation" : "Sendout 123",
"to" : "46701223344",
"from" : "LEKAB",
"id" : "180024553",
"status" : "DELIVERED",
"statuscode" : "2",
"conversation" : "Sendout 123",
"time" : "1577031270000"
}, {
"batchid" : "490922766334210048",
"batchconversation" : "Sendout 123",
"to" : "447711223344",
"from" : "LEKAB",
"id" : "180024554",
"status" : "DELIVERED",
"statuscode" : "2",
"conversation" : "Sendout 123",
"time" : "1577031272000"
}, {
"batchid" : "490922766334210048",
"batchconversation" : "Sendout 123",
"to" : "46702345678",
"from" : "LEKAB",
"id" : "180024556",
"status" : "UNDELIVERABLE",
"statuscode" : "6",
"conversation" : "Sendout 123",
"time" : "1577031269000"
} ]
}
In this example, two of the messages were delivered, while one got the status Undeliverable from the operator. Since no individual conversation ids were supplied, all messages are marked with the batch conversation id.
4.2.3. Explanation of response to /batchmessagestatus
POST json key | json value (strings quoted) | |
---|---|---|
statuses |
json list of json documents |
list of send statuses retrieved |
batchid |
string |
id of the batch to which the message belongs |
batchconversation |
string |
conversation id for the batch supplied when sending to identify the batch |
to |
string |
recipient phone number |
from |
string |
sender id (number or alphanumeric) |
id |
string |
id of the SMS |
status |
string |
name of the status state of the message (DELIVERED is good) |
statuscode |
string containing integer 0 to 13 |
integer code of the status state of the message, 2 is good |
conversation |
string |
conversation id given when sending the message |
time |
string containing long integer |
timestamp in milliseconds after the epoch (1970-01-01 00:00:00 Z) |
4.2.4. Message status codes
The following message status codes can be received in the message status.
statuscode | status | Description |
---|---|---|
|
|
Queued for delivery |
|
|
Sent to operator |
|
|
Delivered to the mobile station |
|
|
The message was deleted |
|
|
The message has expired |
|
|
The message was rejected by the operator |
|
|
The message could not be delivered |
|
|
The message was accepted by the operator |
|
|
The subscribers mobile station is switched off |
|
|
The subscriber is not known |
|
|
The destination address is invalid |
|
|
The mobile station can not receive the message |
|
|
The status of the message is unknown |
|
|
Internal error when sending the message |
4.2.5. Non-final statuses
A later status update from the mobile carrier is quite likely to change the value.
QUEUED (0)
, SENT (1)
Note that when the recipient’s phone is turned off, this is where the status is stuck until the phone is turned on or the message expires.
4.2.6. Successful final status
The recipient’s phone has supposedly acknowledged receipt of this message.
DELIVERED (2)
4.2.7. Failing final statuses
The recipient will not get this message.
DELETED (3)
, EXPIRED (4)
, REJECTED (5)
, UNDELIVERABLE (6)
,
ABSENTSUBSCRIBER (8)
, UNKNOWNSUBSCRIBER (9)
, INVALIDDESTINATION (10)
,
SUBSCRIBERERROR (11)
, ERROR (13)
4.2.8. Unclear
Probably failing final statuses (probably the mobile carrier has lost or dumped the message, but it may suddenly turn up).
ACCEPTED (7)
, UNKNOWN (12)
4.2.9. Example Python 3 code
import json
import requests
statuses = {"username" : "testuser", "password": "testpass", "messageids" : ["180024553", "180024554", "180024556"]}
statuses_json = json.dumps(statuses)
url = 'https://secure.lekab.com/restsms/api/batchmessagestatus'
response = requests.post(url, data=statuses_json)
statusresp = response.json()
for s in statusresp["statuses"]:
print("id=" + s["id"] + ", status=" + s["status"])
will output
id=180024553, status=DELIVERED
id=180024554, status=DELIVERED
id=180024556, status=UNDELIVERABLE
5. The /batchstatuscount
endpoint
Used to retrieve counts of the statuses of the SMS messages in a batch that was sent earlier. The message statuses are not marked as read, so the same values will be retrieved every time unless statuses have changed or old messages have been deleted or archived.
You supply a batch id and/or a batch conversation id and will get the number of messages with each status in the specified batch(es). Probably, one or the other is given to refer to the batch, and the resulting list of status counts will have one json document in it. If both id and conversation id are given, and they refer to different batches, the list will have two json documents in it.
We recommend this endpoint only be called once per minute or less often. Polling every second (or even more often) does not add any value. The database call will be relatively heavy for larger batches, and the values change slowly: at first, when all messages have been sent to the operator, many delivery receipts come back from the operator in the first minute, but there is no inherent value in knowing the progress every second. After the first few minutes, new delivery receipts only arrive when a formerly turned off mobile handset is turned on, triggering delivery, and finally after 24 to 72 hours when messages expire for mobile handsets that were never turned on.
5.1. GET request example
e.g. from web browser or curl
curl https://secure.lekab.com/restsms/api/batchstatuscount?U=testuser&P=testpass&BI=490922766334210048
5.2. POST request example
Probably from an application
https://secure.lekab.com/restsms/api/batchstatuscount
with the contents of the HTTP body:
{
"username" : "testuser",
"password" : "testpass",
"batchid" : "490922766334210048"
}
5.2.1. Explanation of parameters for /batchstatuscount
POST json key | GET query param | json value (strings quoted) | query param value (strings without quotes) | |
---|---|---|---|---|
username |
U |
string |
string |
username of the LEKAB SMS sending account |
password |
P |
string |
string |
password of the LEKAB SMS sending account |
apikey |
key |
string |
string |
API key of the LEKAB SMS sending account |
batchid |
BI |
string |
string |
batch id of the batch for which counts of current message statuses are to be retrieved |
batchconversation |
BX |
string |
string |
batch conversation id of the batch for which counts of current message statuses are to be retrieved |
5.2.2. HTTP response to /batchstatuscount
A successful request will return 200 OK and a json document of the
following format. The Content-Type
header of the response
is application/json
for all responses.
{
"statuses" : [ {
"batchid" : "490922766334210048",
"batchconversation" : "Sendout 123",
"counts" : {
"DELIVERED" : 4,
"UNDELIVERABLE" : 1
}
} ]
}
In this example, four of the messages were Delivered to the mobile handset, while one got the status Undeliverable from the operator.
5.2.3. Explanation of response to /batchstatuscount
POST json key | json value (strings quoted) | |
---|---|---|
statuses |
json list of json documents |
list of batch status counts retrieved, one json document per batch |
batchid |
string |
id of the batch to which this status count refers |
batchconversation |
string |
conversation id for the batch supplied when sending to identify this batch |
counts |
map(string → integer) |
name of the status of SMS message (DELIVERED is good) mapped to the number of occurances of that status |
5.2.4. Message statuses
The following message statuses can occur in the count.
The desired, final value is DELIVERED
.
status | Description |
---|---|
|
Queued for delivery |
|
Sent to operator |
|
Delivered to the mobile station |
|
The message was deleted |
|
The message has expired |
|
The message was rejected by the operator |
|
The message could not be delivered |
|
The message was accepted by the operator |
|
The subscribers mobile station is switched off |
|
The subscriber is not known |
|
The destination address is invalid |
|
The mobile station can not receive the message |
|
The status of the message is unknown |
|
Internal error when sending the message |
5.2.5. Non-final statuses
A later status update from the mobile carrier is quite likely to change the value.
QUEUED
, SENT
Note that when the recipient’s phone is turned off, this is where the status is stuck until the phone is turned on or the message expires.
5.2.6. Successful final status
The recipient’s phone has supposedly acknowledged receipt of this message.
DELIVERED
5.2.7. Failing final statuses
The recipient will not get this message.
DELETED
, EXPIRED
, REJECTED
, UNDELIVERABLE
,
ABSENTSUBSCRIBER
, UNKNOWNSUBSCRIBER
, INVALIDDESTINATION
,
SUBSCRIBERERROR
, ERROR
5.2.8. Unclear
Probably failing final statuses (probably the mobile carrier has lost or dumped the message, but it may suddenly turn up).
ACCEPTED
, UNKNOWN
5.2.9. Example Python 3 code
import json
import requests
statuses = {"username" : "testuser", "password": "testpass", "batchid" : "490922766334210048"}
statuses_json = json.dumps(statuses)
url = 'https://secure.lekab.com/restsms/api/batchstatuscount'
response = requests.post(url, data=statuses_json)
statusresp = response.json()
for s in statusresp["statuses"]:
print("id=" + s["batchid"] + ", conv=" + s["batchconversation"])
print("---")
for k in s["counts"].keys():
print(k + " : " + str(s["counts"][k]))
print("---")
will output
id=490922766334210048, conv=Sendout 123
---
DELIVERED : 4
UNDELIVERABLE : 1
---