Telco

SMS API

SMS API Overview

The SMS API exposes the telco SMS functionality as an API. It allows you to interact with or notify humans or machines using long or short messages via SMS. The current version of the SMS API is focused around the sending of messages and the surrounding functionality of retrieving delivery information and counting text length.

Local and international

You will be able to send SMSs to Belgian destinations, but also to more than 200 worldwide destinations. In Belgium you can of course rely on Proximus as the biggest mobile operator, for international destinations you can count on recognized operators.

Shared or dedicated number

By default, all SMS traffic will be issued from our shared short number 8937. If you wish to have your own dedicated short number, please contact our team.

Inbound SMS support

Next to sending SMS (A2P : application to people), our API makes it also possible to support inbound messaging (P2A : people to application). We offer several possibilities to support inbound scenarios:

  1. Using our shared short number 8937
  • with reserved keywords: you can request to reserve a specific keyword that your users will mention at the start of every SMS they send (for example: "CODE1"). Every single SMS that is sent to the shared API Solutions number 8937 that starts with this keyword will be routed to your account. Keywords can be reserved & released dynamically through our API .
  • without reserved keywords: we are only able to route an incoming SMS sent to our shared number to your account if we understand you are in contact with that party. Without reserved keywords, this means we will route an incoming SMS to your account only when you have first sent a SMS to that person and the person answers in a very short time window on your message.
  1. Using a dedicated short code number: this short code number is dedicated to you and will be shown as originating number for your outbound SMS traffic. Similarly, all messages sent to that dedicated number will solely be routed to your account. If you wish to have your own dedicated short number, please contact our team.

Pay as you grow

Try the API for free and pay as you grow! Check out our different pricing plans and choose one that fits your needs.

SMS API endpoint details

Base url: https://api.enco.io/sms/1.0.0

Header Value Required
Authorization Bearer Yes
Accept application/json Yes
Content-type application/json Yes

! The access_token should be retrieved via the authentication API.

Endpoint overview

/sms/outboundmessages POST
/sms/outboundmessages/{address} POST
/sms/outboundmessages/length POST
/sms/outboundmessages/deliveryinfos/{deliveryinfoId} GET
/sms/inboundmessages/shared GET
/sms/inboundmessages/{address} GET
/sms/dedicatedaddresses GET
/logs GET

Outbound

/sms/outboundmessages POST

Sends an SMS to the specified destination using a shared address such as "8937" as origin. This means that your application needs to send a message to a certain destination before it can get a response from that destination. The routing of the response back to your application is not 100% guaranteed as there may be other applications sending to the same destination. The shared number is free of charge, works "out-of-the-box" and is ideal if inbound SMS is not critical to your application.

Parameter Description Type Required
forceCharacterLimit (query parameter) Force max 1 message or allow message splitting boolean No

Request Payload

{
    "message": {string},
    "destinations": [array of strings],
    "callbackURL": {string}
}

! Destination number must be defined in the correct international format (e.g.: +32490000000). Note that although "Destinations" is an array, it is limited to only one destination. The callbackURL should be a valid http or https URL.

Response Payload

{
  "resourceURL" : {string},
  "deliveryInfo" : [ {
    "address" : {string},
    "deliveryStatus" : {string "DeliveredToTerminal", "DeliveryUncertain", "DeliveryImpossible", "MessageWaiting" or "DeliveredToNetwork"}
  } ]
}

Example Call

curl -i -X POST 'https://api.enco.io/sms/1.0.0/sms/outboundmessages?forceCharacterLimit=false' -H 'Authorization: Bearer 674f4fc8db0000000083e887306cd8' -H 'Content-Type: application/json' -H 'Accept: application/json'  -d '{"message":"Hello World Test Message","destinations":["+32000000000"]}'

HTTP/1.1 201 Created
Server: nginx
Date: Tue, 22 Nov 2016 10:46:07 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST
X-Content-Type-Options: nosniff
Pragma: no-cache
Access-Control-Allow-Headers: authorization,Access-Control-Allow-Origin,Content-Type
X-Frame-Options: DENY
activityID: a90f1010-5e8b-4940-84fa-07a7a87c3d74
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Expires: 0
X-XSS-Protection: 1; mode=block
Location: https://api.enco.io/sms/1.0.0/sms/outboundmessages/deliveryinfos/b6494f29-0000-0000-be67-f6d42d9f787f"
Access-Control-Max-Age: 86400

{
  "resourceURL" : "https://api.enco.io/sms/1.0.0/sms/outboundmessages/deliveryinfos/b6494f29-0000-0000-be67-f6d42d9f787f",
  "deliveryInfo" : [ {
    "address" : "+32000000000",
    "deliveryStatus" : "DeliveredToNetwork"
  } ]
}

! You can put line breaks in your message by using '\n' or '\r'.

Example

curl -i -X GET 'https://api.int.enco.io/sms/1.0.0/sms/outboundmessages?forceCharacterLimit=false' -H 'Authorization: Bearer aaaaaaaaaaaaa'  -H 'Content-Type: application/json' -H 'Accept: application/json'  -d '{"message":"this is a test message\nwith line breaks\rand returns","destinations":["+32aaaaaaaa"]}' 

sms/outboundmessages/{address} POST

Sends an SMS to the specified destination using one of your dedicated addresses as origin. You can get a list of your dedicated addresses with /sms/dedicatedaddresses. To set up a dedicated address, please contact us. As opposed to the shared number, the dedicated address is not free of charge and requires some time to be set up. Once you use a dedicated address, you are 100% guaranteed that inbound SMS will be properly routed back to your application. An other advantage is that your application can receive SMS from a certain destination without the need of your application sending an SMS to that destination first.

Parameter Description Type Required
address The dedicated address to be used as origin string Yes
forceCharacterLimit (query parameter) Force max 1 message or allow message splitting boolean No

Request Payload

{
    "message": {string},
    "destinations": [array of strings],
    "callbackURL": {string}
}

! Destination number must be defined in the correct international format (e.g.: +32490000000). Note that although "Destinations" is an array, it is limited to only one destination. The callbackURL should be a valid http or https URL.

Response Payload

{
  "resourceURL" : {string},
  "deliveryInfo" : [ {
    "address" : {string},
    "deliveryStatus" : {string "DeliveredToTerminal", "DeliveryUncertain", "DeliveryImpossible", "MessageWaiting" or "DeliveredToNetwork"}
  } ]
}

Example Call

curl -i -X POST 'https://api.enco.io/sms/1.0.0/sms/outboundmessages/8888?forceCharacterLimit=false' -H 'Authorization: Bearer 674f4fc8db0000000083e887306cd8' -H 'Content-Type: application/json' -H 'Accept: application/json'  -d '{"message":"Hello World Test Message","destinations":["+32000000000"]}'

HTTP/1.1 201 Created
Server: nginx
Date: Tue, 22 Nov 2016 10:46:07 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST
X-Content-Type-Options: nosniff
Pragma: no-cache
Access-Control-Allow-Headers: authorization,Access-Control-Allow-Origin,Content-Type
X-Frame-Options: DENY
activityID: a90f1010-5e8b-4940-84fa-07a7a87c3d74
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Expires: 0
X-XSS-Protection: 1; mode=block
Location: https://api.enco.io/sms/1.0.0/sms/outboundmessages/deliveryinfos/b6494f29-0000-0000-be67-f6d42d9f787f"
Access-Control-Max-Age: 86400

{
  "resourceURL" : "https://api.enco.io/sms/1.0.0/sms/outboundmessages/deliveryinfos/b6494f29-0000-0000-be67-f6d42d9f787f",
  "deliveryInfo" : [ {
    "address" : "+32000000000",
    "deliveryStatus" : "DeliveredToNetwork"
  } ]
}

/sms/outboundmessages/length POST

Calculates the length of the current text message and specifies how many more characters are allowed in the part before it is split into more parts.

Request Payload

{
    "message": {string}
}

Response Payload

{
  "numberOfChars" : {number},
  "charLimitPerPart" : {number},
  "numberOfParts" : {number},
  "numberOfRemainingCharsInPart" : {number}
}

Example Call

curl -i -X POST 'https://api.enco.io/sms/1.0.0/sms/outboundmessages/length' -H 'Authorization: Bearer 66d126b000000000036897ccabd6' -H 'Content-Type: application/json' -H 'Accept: application/json'  -d '{"message":"Hello world test message"}'

HTTP/1.1 200 OK
Server: nginx
Date: Tue, 22 Nov 2016 10:31:38 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Frame-Options: DENY
activityID: 5908d31b-1598-42b4-b613-67d441564d29
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST
X-Content-Type-Options: nosniff
Expires: 0
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Access-Control-Allow-Headers: authorization,Access-Control-Allow-Origin,Content-Type
Access-Control-Max-Age: 86400

{
  "numberOfChars" : 24,
  "charLimitPerPart" : 160,
  "numberOfParts" : 1,
  "numberOfRemainingCharsInPart" : 136
}

/sms/outboundmessages/deliveryinfos/{deliveryinfoId} GET

Retrieves the delivery info for the specified id.

Parameter Description Type Required
deliveryinfoId The deliveryinfoId linked to the previous outboundmessages POST request String Yes

Response Payload

{
  "resourceURL" : {string},
  "deliveryInfo" : [ {
    "address" : {string},
    "deliveryStatus" : {string "DeliveredToTerminal", "DeliveryUncertain", "DeliveryImpossible", "MessageWaiting" or "DeliveredToNetwork"}
  } ]
}

Example Call

curl -i -X GET 'https://api.enco.io/sms/1.0.0/sms/outboundmessages/deliveryinfos/ff595443-0000-0000-9b83-d9acd74fa67c' -H 'Authorization: Bearer 674f4fc8d00000000003e887306cd8' -H 'Accept: application/json'

HTTP/1.1 200 OK
Server: nginx
Date: Tue, 22 Nov 2016 10:59:02 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Frame-Options: DENY
activityID: a365be3c-3875-419f-8d83-33e5474f13d1
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
X-Content-Type-Options: nosniff
Expires: 0
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Access-Control-Allow-Headers: authorization,Access-Control-Allow-Origin,Content-Type
Access-Control-Max-Age: 86400

{
  "resourceURL" : "https://api.enco.io/sms/1.0.0/sms/outboundmessages/deliveryinfos/ff595443-0000-0000-9b83-d9acd74fa67c",
  "deliveryInfo" : [ {
    "address" : "tel:+32000000000",
    "deliveryStatus" : "DeliveredToTerminal"
  } ]
}

Inbound

/sms/inboundmessages/shared GET

Retrieves the inbound messages on which your application has ownership for the shared address (e.g. "8937"). Your application automatically gets ownership of an inbound message based on the following criteria: your application has sent a message to the sender of that message and there is no other application that has also sent a message to the same destination within a period of 7 days.

Parameter Description Type Required
startdatetime (query param) Only messages higher than the startdatetime will be retrieved datetime Yes
enddatetime (query param) Only messages lower than the enddatetime will be retrieved datetime Yes
new-only (query param) If set to true than only messages will be retrieved that haven't been retrieved before boolean Yes

Response Payload

{
  "numberOfMessages"  :  {integer},
  "messages"  :  [  {
     "senderAddress"  : { string},
       "message"  :  {string},
     "numberOfParts" :  {integer},
     "timeReceived" : {string}
  } ]
}

/sms/inboundmessages/{address} GET

Retrieves all inbound messages sent to the dedicated address specified.

Parameter Description Type Required
address (path param) The dedicated address that received the messages string Yes
startdatetime (query param) Only messages higher than the startdatetime will be retrieved datetime Yes
enddatetime (query param) Only messages lower than the enddatetime will be retrieved datetime Yes
new-only (query param) If set to true than only messages will be retrieved that haven't been retrieved before boolean Yes

Response Payload

{
  "numberOfMessages"  :  {integer},
  "messages"  :  [  {
     "senderAddress"  : { string},
       "message"  :  {string},
     "numberOfParts" :  {integer},
     "timeReceived" : {string}
  } ]
}

Other

/sms/dedicatedaddresses GET

Retrieves all the dedicated addresses that you can use as origin address for sending messages.

Response Payload

{
  "dedicatedAddresses": [array of strings]
}

Example Call

curl -i -X GET 'https://api.int.enco.io/sms/1.0.0/sms/dedicatedaddresses'  -H 'Authorization: Bearer 4f3af6e00000000000000233ca' -H 'Accept: application/json' -H "Content-type: application/json"

HTTP/1.1 200 OK
Server: nginx
Date: Tue, 24 Jan 2017 12:43:49 GMT
Transfer-Encoding: chunked
Connection: keep-alive
X-Frame-Options: DENY
activityID: 468a87a5-a82b-42d4-bf40-2d467ee247b0
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
X-Content-Type-Options: nosniff
Expires: 0
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Access-Control-Allow-Headers: authorization,Access-Control-Allow-Origin,Content-Type
Access-Control-Max-Age: 86400

{
  "dedicatedAddresses" : [ "666", "8888" ]
}

/logs GET

Returns the logging overview of the SMS API

Parameter Description Type Required
type The type of logs to be retrieved. , "sms-outbound": successful API calls , "sms-outbound-error": erroneous API calls string yes
dedicatedaddress dedicated address for which logs should be retrieved. If not provided, logs will be retrieved for shared address string no
year The year to search in integer yes
month The month to search in integer yes
function Function to execute on the logs, "interval": retrieves all results in the specified interval, "groupByDay": retrieves an overview of the month specified string yes
startTime mandatory with "interval" function datetime no
endTime mandatory with "interval" function datetime no
page Used for paging. You can specify "first", "next", "previous" or "last" page. string no
pageref Used for paging. Identifies where to start the next or previous page. string no
limit Limits the amount of results to be returned integer no

Response Payload

[
  {
    "timestamp" : {string ISO8601},
    "destinationAddress" : {string international number format},
    "message" : {string},
    "initialDeliveryInfo" : {string},
    "numberOfChars" : {string},
    "numberOfMessages" : {string},
    "requestId" : {string},
    "httpResponseCode" : {string}
  }, 
  ...
]

Example Call

curl -i -X GET 'https://api.int.enco.io/sms/1.0.0/logs?type=sms-outbound&year=2016&month=12&function=interval&startTime=2016-12-27T23:00:00.000Z&endTime=2016-12-28T23:00:00.000Z&limit=10' -H 'Authorization: Bearer 6586d1234561665dce5888888ea90d' -H 'Accept: application/json'

HTTP/1.1 200 OK
Server: nginx
Date: Wed, 28 Dec 2016 16:19:47 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Frame-Options: DENY
activityID: 618a77e5-37ce-40f0-8afd-e1cce2cccd7f
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
X-Content-Type-Options: nosniff
Expires: 0
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Access-Control-Allow-Headers: authorization,Access-Control-Allow-Origin,Content-Type
Access-Control-Max-Age: 86400

[ {
  "timestamp" : "2016-12-28T16:51:40.727+01:00",
  "destinationAddress" : "+32470000000",
  "message" : "lolololol",
  "initialDeliveryInfo" : "MessageWaiting",
  "numberOfChars" : "9",
  "numberOfMessages" : "1",
  "requestId" : "6a2f5fed-0000-0000-0000-412502c68939",
  "httpResponseCode" : "200"
}, {
  "timestamp" : "2016-12-28T17:13:13.149+01:00",
  "destinationAddress" : "+32470000000",
  "message" : "This is a test message!",
  "initialDeliveryInfo" : "MessageWaiting",
  "numberOfChars" : "23",
  "numberOfMessages" : "1",
  "requestId" : "06e89922-0000-0000-0000-d2e690bd3e9d",
  "httpResponseCode" : "200"
} ]

Handling inbound SMS

With SMS callbacks

The SMS callback allows to define an endpoint address to which we will immediately send all incoming SMS for your account. You can create and manage your SMS callbacks on the following endpoint: /sms/callbacks (more details on the available methods in the API console). The callback object is described as follows:

{
  "id": "string",
  "keyword": "string",
  "number": "string",
  "endpoint": {
    "url": "string",
    "headers": {},
    "method": "POST",
    "authentication": {
      "type": "NONE",
      "username": "string",
      "password": "string",
      "bearerToken": "string"
    }
  },
  "type": "NOTIFICATION",
  "message": "string"
}

By using the “keyword” parameter, you can use a callback only in the case you receive an inbound SMS that contains one of your defined SMS inbound keywords. By using the“number” parameter, you can also use a callback specifically for one of your own origin numbers. Those 2 parameters “keyword” and “number” are both optional. Finally, you can also define which type of notifications you want to use the callback for: “INBOUND” for new inbound SMS messages, “NOTIFICATION” for delivery status, or “ALL”. You can define the endpoint URL, the HTTP method and the authentication method (optional) for which you can use “BASIC”, “BEARER” or “NONE”. The “headers” parameter can be used to specify your own headers starting with “x-“, for example “x-my-header”.

With CloudEngine

The Proximus API Solutions CloudEngine allows to activate scripts based on incoming SMS traffic. When adding a SMS inbound endpoint to a CloudEngine visual flow or script, you can set filters on the endpoint so that only SMSs meeting the filter requirements are passed on to your script. Filters can be defined on:

  • keyword: if you have reserved keywords on our shared number 8937
  • origin number
  • destination number

Once your CloudEngine script receives the incoming SMS, it can leverage all capabilities of CloudEngine for message processing or to forward this message using any of the outgoing endpoints supported by this solution (HTTP, MQTT, FTP, Microsoft Azure, SMTP, …).

Read our documentation to discover more about CloudEngine's capabilities, or take a look at our

API authentication

API Solutions uses OAuth2 to protect API resources. The OAuth2 specification has become the predominant standard for securing RESTful APIs and identity delegation.

In order to gain access to the resources exposed by your API assets, you will need to pass along a valid OAuth2 bearer access token. Here is how you can generate such a token.

Obtaining your OAuth2 Application Keys

Each project you create through the API Solutions Market will result in the creation of a unique pair of OAuth2 application keys. To retrieve your keys, proceed as follows:

  • First, log in and visit your dashboard on the portal. Click the "TOKEN" menu.
  • This will result in your application keys to be shown. These keys can be used to access API resources exposed by any API asset to which you subscribed, within the scope of the selected project.

OAuth 2 Keys

Your application keys are sensitive information; keep them private at all time!

Make sure to store your application keys in a safe way, avoiding them to leak or be stolen by an unintended audience. They are quite sensitive, in that anyone obtaining them will be able to gain access to your assets. In case your application keys would become compromised, contact us through support and we'll revoke them to block access, and provide you with a new pair. This is also the reason why all API traffic should pass through secured HTTP, and why we do not support plain HTTP.

Generating a fresh bearer access token

A bearer access token is a self-contained unique identifier through which you can gain access to API resources. Before elaborating on how you can obtain such type of token, please note that these tokens are valid for a limited time span of 1 hour (or less, if explicitly revoked).

You can obtain a new token by issuing the following request against the server https://api.enco.io :

/token POST

Issue a request to https://api.enco.io/token, adding the following headers and body:

Request

curl -X POST \
  'https://api.enco.io/token?grant_type=client_credentials&scope=openid&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&Accept=application/json' \
  -H 'Content-Type: application/x-www-form-urlencoded' 

Response payload

{ 
  "scope": "openid", 
  "token_type": "Bearer", 
  "expires_in": {number}, 
  "access_token": {string}
}

The field accesstoken in the response contains your token. The field expiresin will show you the remaining validity of your token, in seconds.

Single active access token
Within the context of a single application, you will only have a single active access token at any time. If you would request a new token using the above request message while the previously issued token has not yet expired, you will get back the previous token. To obtain a new one, revoke the old token; then generate a new one.

Code Samples
To help you getting started on implementing this authentication in your code, you can find some samples on our Github.

Revoking an access token

This procedure should be used when your token has been compromised (leaked, stolen, etc.), or if you want to generate another token, but your old token is still valid.

/revoke POST

Issue a request to https://api.enco.io/revoke, adding the following headers and payload:

Header Value Required
Content-type application/x-www-form-urlencoded Yes

Request payload

token=<old-access-token-to-be-revoked>&client_id=<app-consumer-key>&client_secret=<app-consumer-secret>

Creating permanent token

You can create permanent tokens from the "TOKEN" menu of your profile's dashboard. Just click on "Add a new token" to create a new permanent token. Several permanent tokens can be created for the same account.

Permanent token

Your permanent token is sensitive information; keep it private at all time!

Make sure to store your permanent tokens in a safe way, avoiding them to leak or be stolen by an unintended audience. They are quite sensitive, in that anyone obtaining them will be able to gain access to your assets. In case a permanent token would become compromised or not needed anymore, delete this token from your "TOKEN" dashbload by clicking on the red cross next to it.

All set to call your API!

Once a valid access token has been generated, it should be added to request messages. The token should be passed in an HTTP header named Authorization, which should be assigned the value of Bearer, followed by a single space, and immediately followed by the access token. Note the single space between ‘Bearer’ and the token.

curl -i -X GET -H "Accept:application/json" -H "Authorization: Bearer <active-access-token>" https://api.enco.io/lora4maker/0.0.1/device

Terms & Conditions

Proximus SMS API Terms and Conditions document.

Never miss a thing

Stay informed on offers, promotions and platform updates by e-mail. You can unsubscribe at any time.

Proximus logo

All rights reserved. © 2020 Proximus | Cookie policy

This site was created and is managed in accordance with Belgian law.

Proximus API Solutions - powered by ClearMedia NV. Merksemsesteenweg 148, B-2100 Deurne.

BE 0831.425.897