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:
- 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.
- 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.
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.
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.