Customer portal Devzone

Spirius SMS Gateway REST interface (1.2.0)

Download OpenAPI specification:Download

Introduction

Spirius SMS Gateway REST interface is the recommended way to add messaging capabilities to your applications. It is easy to use but still offer the same performance and reliability as its predecessors. The API allows you to send and receive SMS messages as well as tracking delivery of sent messages.

Base URL

The following URLs can be used by to access the REST API

Site URL Description
Karlskrona https://rest1.spirius.com/v1 Application Load Balancer with automatic failover.
Stockholm https://rest2.spirius.com/v1 Application Load Balancer with automatic failover.
Balanced https://rest.spirius.com/v1 DNS Load Balancing between Sites listed above.

Authentication

This API supports two different authentication schemes:

HTTPS encryption is used to protect communications between your application and Spirius SMS Gateway.

In addition to the authentication schemes, Spirius SMS Gateway allows users to lock usage to a single IPv4 address, or to a list of IPv4 addresses. This setting is found in the Account Settings section of the customer portal

Note that HMAC-SHA256 based authentication is the most secure method offered. No password or token is sent over the wire and replay of requests is mitigated thanks to a timestamp being part of the signature.

Basic Authentication

In basic HTTP authentication, a request contains a header field in the form of Authorization: Basic <credentials>, where credentials is the Base64 encoding of username and password joined by a single colon.

For example, given username bob and password secret, the string to Base64 encode is bob:secret and the final result for the header is Authorization: Basic Ym9iOnNlY3JldAo=.

Basic authentication is simple to implement and most HTTP clients have support for this feature. Since Spirius SMS gateway uses HTTPS, the credentials are always encrypted.

HMAC-SHA256

Spirius SMS Gateway supports the use of HMAC (hash-based message authentication code) to verify that a request is coming from an expected source and has not been tampered with. The client generates a unique HMAC representing its request to the server and sends that HMAC to the server, along with a timestamp and all the arguments and values it was going to send anyway. The SMS Gateway API gets the request and re-generates its own unique HMAC based on the submitted values using the same methods the client used. The SMS Gateway API will then compare the two HMACs. If they are equal, then the server trusts the client, and processes the request.

Following code snippet demonstrates how to generate HMAC signatures:

import base64
import json
import hmac
import time
import hashlib

# Settings
encoding = "utf-8"
auth_version = "SpiriusSmsV1"
api_key = "963e3454-1626-11ec-b249-67af30055a2c".encode(encoding)
path = "/sms/mt/send"

# Create message with parameters
data = {
  "message": "Hello world!",
  "to": "+46123456790",
  "from": "SPIRIUS",
}
request_body = json.dumps(data)

# Build HMAC
http_verb = "POST"
unix_timestamp = int(time.time())
body_hash = hashlib.sha1(request_body.encode(encoding))
msg_to_sign = "\n".join([
  auth_version,
  str(unix_timestamp),
  http_verb,
  path,
  body_hash.hexdigest()
]).encode(encoding)

# Create signature
digest = hmac.new(
  key=api_key,
  msg=msg_to_sign,
  digestmod=hashlib.sha256
).digest()

signature = base64.b64encode(digest).decode(encoding)
print(signature)

Complete code examples for sending requests with HMAC signatures are available on GitHub.

Further settings when deploying HMAC-SHA based authentication

Things to consider

  • Disable Basic authentication in the customer portal by checking "Enforce HMAC signature"
  • Make sure your machine uses NTP (or SNTP) to prevent messages to be rejected because of clock drift.

Rate Limit

Clients are setup with a rate limit that defines the maximum number of HTTP requests that can be sent per second. When the rate limit is exceeded requests will be rejected with a HTTP status 429 “Too many requests” response. Once the client drops below the limit, SMS Gateway will again start processing requests.

A single HTTP request listing 50 recipients will count as 1 request for HTTP protocol rate limiting purposes, but the 50 messages will be subject to throttling and only sent out with the maximum speed (in SMS/second) defined by the rate limit of the client.

The same kind of throttling also applies to concatenated messages. A single message with a text long enough to require three concatenated SMS to carry the message contents, will be counted as three SMS the current second.

Conventions

JavaScript Object Notation is used for HTTP bodies in both requests and replies.

Receiver phone numbers (MSISDN) must be specified in international E.164 format with leading + (e.g. +46123456789)

Webhooks

If configured, SMS Gateway will initiate HTTP requests to the client whenever a new MO message or status notification arrives. Webhook URLs are preset in the system when the account is setup and can be changed at any time using the customer portal.

Note that the webhook URL configured in the account settings may be overridden using the dlrCallbackUrl parameter of the Send SMS endpoint.

Webhooks support HTTPS encryption and Basic Authentication. This allows you to password protect the URLs on your web server so that only you and Spirius SMS Gateway can access them. You may provide a username and password using the following URL format.

https://username:password@www.myserver.com/sms/dlr

Webook requests must be responded to using a HTTP status 200 or 202 to acknowledge reception of the call and thereby stop retransmissions. Retransmissions will initially occur once every minute. After 15 minutes the retry frequency will start to drop and after 1 week the attempts will cease.

Mobile Terminated SMS

These endpoints are related to sending SMS and tracking delivery of sent messages.

A single SMS can contain maximum 160 characters, or maximum 70 characters if it contains emojis or any other character that is not part of the GSM-7 character set. When sending longer messages, up to 10 SMS will be concatenated to carry the message content. The maximum limit is imposed by mobile networks. Requests to send larger messages than what can fit within 10 concatenated SMS will be rejected with HTTP status 400.

Note A concatenated SMS can contain less characters than said above (usually 153) because some space is needed for the concatenation header. To find out how many SMS that will be used, the dryRun parameter can be used and then check numberOfSms in the response.

The encoding used in the SMS (i.e. GSM-7 or UCS-2) is automatically chosen by the SMS Gateway depending on the message content.

The number of SMS needed to carry the message payload is returned from the Send SMS endpoint on all HTTP 202 Accepted responses (this is true for dry-runs as well).

SMS status Webhook

MT-SMS status notification webhooks are sent in JSON format using HTTP POST and JSON.

The URL is configured on the Account setting page in the customer portal.

Request Body schema: application/json
result
integer

The result of this transaction.

Available options are:

  • 1 - delivered
  • 2 - failed to deliver
  • 32 - the message is still pending
statusCode
integer

The status code is used to differentiate between different kind of failures. The value is only meaningful when the result code is 2 (result=2).

Available values are:

  • 1 - The message could not be delivered
  • 2 - The message could not be routed
  • 3 - Validity period expired
  • 4 - Unknown transaction id
  • 5 - Internal error
detail
string

A humanly readable description of the result + status code combination for this transaction

transactionId
string

The transaction ID of the message that this status belongs to

timestamp
string

The time when delivery report was received from the mobile network

timezone
string

The timezone information for above timestamp. Expected to be CET or CEST.

Responses

Request samples

Content type
application/json
Example
{
  • "result": 1,
  • "statusCode": 1,
  • "detail": "The message has been successfully delivered",
  • "transactionId": "6b252bed-c967-446b-bfba-e71427c188a9",
  • "timestamp": "2021-09-23 14:51:00",
  • "timezone": "CEST"
}

Send SMS

Send an SMS to one or more recipients.

When an SMS is accepted for delivery, HTTP 202 Accepted will be returned. Other possible status codes are specified below.

To obtain the outcome of a MT message the user has two options, calling Get SMS Status or using the SMS status webhook.

To request a SMS status webhook event to be generated when an MT message has reached its final state, set the (deliveryReport=true) parameter in the request.

Request Body schema: application/json
message
required
string^.*$

The actual message. If message type is binary this parameter should be given in hexadecimal form.

required
string or Array of strings

The E.164 formatted phone number(s) of the receiver(s). Numbers must start with a + character followed by at least 5, and at most 15, digits.

This value can either be a string or an array of strings.

A maximum of 50 recipients in a single request is supported.

from
required
string^.*$

The displayed sender. Can either be an E.164 formatted phone number, or an alphanumeric string of max 11 characters.

If a default value for from is configured in the customer portal, this parameter can be omitted.

fromType
string^international|national|alphanumeric|short$
Default: "international"
Enum: "international" "national" "alphanumeric" "short"

Determines the format of the from parameter.

If the from parameter contains any non-digits (other than the leading +), the fromType is automatically set to alphanumeric if nothing else is provided. An alphanumeric fromType might not be possible to respond to even if the from value looks like a phone number. If the from value contains non-digits it is definitely not possible to use as a respond-to address.

sendAt
string <date-time> ^(\d{4})-([0]\d|1[0-2])-([0-2]\d|3[01]) ([0-1...
Default: null

A date and time, specifying when to first attempt delivery of the SMS. When this parameter is omitted, the first delivery attempt is immediate.

The timestamp must be provided in the format YYYY-MM-DD HH:mm:ss (e.g. 2021-01-01 15:25:01).

The timezone for this parameters is specified in the sendAtTimeZone parameter.

sendAtTimeZone
string
Default: "Europe/Stockholm"

Specified timezone for the sendAt property.

The format should be the long version as specified in tz database (i.e. Europe/Stockholm).

The default value is Europe/Stockholm.

validityPeriod
integer [ 1 .. 20160 ]
Default: 4320

A validity period specified in minutes, specifying when to expire the SMS if it has not yet been delivered. Calculated from the first delivery attempt specified by the sendAt parameter.

Note Some mobile network operators enforce a shorter maximum validity period (e.g. 2880 minutes) that will override this parameter.

The max value is 20160 minutes.

deliveryReport
boolean
Default: false

Determines whether delivery report webhook is requested. The delivery report URL should be set on the account in the account settings section in the customer portal.

dlrCallbackUrl
string <url>
Default: null

A temporary webhook URL to send delivery report to over HTTP POST valid for this message only. This parameter overrides the delivery report URL saved on the account in the account settings section in the customer portal.

The format of the webhook is documented under the Webhook section. If the dlrCallbackUrl is not a valid URL the request will be rejected.

Note If the deliveryReport parameter is not explicitly set, its value will change to true when dlrCallbackUrl is set.

clientReference
string <= 64 characters ^[.*]{0,64}$
Default: null

A reference that can be used to tag each SMS with a reference string of your choice, e.g. a project name. You can then get a monthly report with the number of SMS sent per project.

Max 64 basic latin letters.

type
string^text|flash|binary$
Default: "text"
Enum: "text" "flash" "binary"

Determines the type of the message parameter.

Note Some mobile network operators do only support ascii characters in flash messages.

Binary SMS do not support concatenation and cannot carry more than 140 bytes.

encoding
string^auto|GSM|UCS$
Default: "auto"
Enum: "auto" "GSM" "UCS"

When this parameter is omitted or set to auto, the API will autodetect if the message content can be encoded using GSM-7 or if the message contains characters that require UCS-2 (such as e.g. emojis). The most efficient encoding will be used.

This parameter can be set to GSMor UCS to bypass the auto-detection algorithm and enforce a specific encoding.

Not applicable for message type binary.

dryRun
boolean
Default: false

If true, enables a dry run, which will validate the message, process it and return a result, but no message will actually be sent, and the account will not be charged.

This is handy for verifying integrations towards the API and testing this endpoint without sending anything or having any expenses incurred.

Responses

Request samples

Content type
application/json
{
  • "message": "Hello world!",
  • "to": "+46123456790",
  • "from": "SPIRIUS",
  • "fromType": "alphanumeric",
  • "sendAt": "2021-12-10 12:30:00",
  • "sendAtTimeZone": "Europe/Stockholm",
  • "validityPeriod": 180,
  • "deliveryReport": true,
  • "clientReference": "Christmas sale",
  • "type": "text",
  • "encoding": "UCS",
  • "dryRun": false
}

Response samples

Content type
application/json
{
  • "detail": "Accepted for delivery",
  • "numberOfSms": 1,
  • "transactionId": "28fc2e4a-abc2-4942-9eec-a61f9dcfb54d",
  • "remainingRequestQuota": 25
}

Get SMS status

Get the status of a sent message, identified by transaction ID.

When calling this endpoint, be sure to look at both the HTTP response code and the actual contents of the response to determine the status of the message. Take a look at the response samples for possible combinations.

You need to send SMS status requests to the same site as was used to send the message. If the message was sent from the Stockholm site you need to check SMS status from the Stockholm site. Other sites will respond with HTTP status 404 Not found. The recommended way is to get SMS status using the webhook.

SMS status will not be available forever via this API. Make sure to read it within 30 days from when the SMS was sent.

path Parameters
transactionId
required
string^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-4[0-9A-Fa-f]{3...
Example: 0e5d76c2-ca5a-4019-b5e2-08ab66cc101d

Transaction ID of message to get status for. Case insensitive.

Responses

Response samples

Content type
application/json
Example
{
  • "result": 1,
  • "statusCode": 1,
  • "detail": "The message has been successfully delivered",
  • "transactionId": "6b252bed-c967-446b-bfba-e71427c188a9",
  • "timestamp": "2021-09-23 14:51:00",
  • "timezone": "CEST"
}

Receive SMS

Using SMS Gateway, it is possible to receive MO (Mobile Originated) messages sent to virtual numbers. To obtain MO messages, the user has two options: using a webhook or repeatedly calling List all messages followed by Pop specific message when a new message arrives. Webhook is the recommended way to receive MO messages.

When a message has been delivered to the client, it will be deleted from SMS Gateway.

Mobile Originated SMS Webhook

MO Messages are sent in JSON format using HTTP POST with Content-Type: application/json.

On the Account settings page in the customer portal, make sure to select the Virtual Number Protocol option HTTP REST to get the format described in this documentation. For new accounts this option should already be preset.

On the same page you also configure the Virtual Number URL, i.e. the destination your MO messages will be sent to.

Request Body schema: application/json
detail
string

Message received

from
string

The displayed sender. Can either be an E.164 formatted phone number, or an alphanumeric string.

fromType
string
Enum: "international" "national" "alphanumeric" "short"
message
string

The message content

type
string
Enum: "text" "flash" "binary"

Determines the type of the message parameter.

result
integer
Enum: 1 2 3 4

A code describing the result of this operation.

The meaning of available options are:

  • 1 No error
  • 2 Unknown transaction ID
  • 3 No more messsages are waiting
  • 4 An internal error occurred
timestamp
string <date-time>

A date and time, specifying when the message was received by Spirius.

The timestamp is of format YYYY-MM-DD HH:mm:ss (e.g. 2021-01-01 15:25:01).

The timezone for this parameters is specified with the timezone parameter.

timezone
string

Specified timezone for the timestamp property.

The format is a timezone abbreviation timezone abbrevation (i.e. CEST).

to
string

The recipient of the message

toType
string
Enum: "international" "national" "alphanumeric" "short"
transactionId
string

The transaction ID for this message.

Responses

Request samples

Content type
application/json
{
  • "detail": "Message received",
  • "from": "SPIRIUS",
  • "fromType": "alphanumeric",
  • "message": "Hello world!",
  • "type": "text",
  • "result": 1,
  • "timestamp": "2021-10-09 15:35:21",
  • "timezone": "CEST",
  • "to": "+4671234567",
  • "toType": "international",
  • "transactionId": "28fc2e4a-abc2-4942-9eec-a61f9dcfb54d"
}

List all messages

Get a list of all waiting messages. The list includes transaction IDs that can then be used to pop specific messages using the pop message operation.

Responses

Response samples

Content type
application/json
Example
{
  • "detail": "2 messages",
  • "transactionIds": [
    ]
}

Get specific message

Get a specific mobile originated message, identified by transaction ID.

This endpoint is identical to Pop specific message except that this endpoint does not delete the message.

Note that this endpoint is intended for testing purposes only. In production environments customers are expected to pop messages from the SMS Gateway.

Responses

Response samples

Content type
application/json
{
  • "detail": "Message received",
  • "from": "SPIRIUS",
  • "fromType": "alphanumeric",
  • "message": "Hello world!",
  • "type": "text",
  • "result": 1,
  • "timestamp": "2021-10-09 15:35:21",
  • "timezone": "CEST",
  • "to": "+4671234567",
  • "toType": "international",
  • "transactionId": "28fc2e4a-abc2-4942-9eec-a61f9dcfb54d"
}

Pop specific message

Get and delete a specific mobile originated message, identified by transaction ID.

Note that once this operation is performed, the message is permanently deleted and cannot be retrieved again, so make sure to save it to avoid it being lost. If you want to only get the message without deleting it, use Get specific message.

Responses

Response samples

Content type
application/json
{
  • "detail": "Message received",
  • "from": "SPIRIUS",
  • "fromType": "alphanumeric",
  • "message": "Hello world!",
  • "type": "text",
  • "result": 1,
  • "timestamp": "2021-10-09 15:35:21",
  • "timezone": "CEST",
  • "to": "+4671234567",
  • "toType": "international",
  • "transactionId": "28fc2e4a-abc2-4942-9eec-a61f9dcfb54d"
}

Pop next message

Get and delete the oldest available mobile originated message.

Note that once this operation is performed, the message is permanently deleted and cannot be retrieved again, so make sure to save it to avoid it being lost.

Responses

Response samples

Content type
application/json
{
  • "detail": "Message received",
  • "from": "SPIRIUS",
  • "fromType": "alphanumeric",
  • "message": "Hello world!",
  • "type": "text",
  • "result": 1,
  • "timestamp": "2021-10-09 15:35:21",
  • "timezone": "CEST",
  • "to": "+4671234567",
  • "toType": "international",
  • "transactionId": "28fc2e4a-abc2-4942-9eec-a61f9dcfb54d"
}