Documentation

Introduction

Welcome to the 46elks API!

The base URL for the API is https://api.46elks.com/a1/ and it is based upon common REST principles. Basic HTTP authentication is used for access control and you can find your API credidentials in the dashboard. If you haven’t used Basic Auth before here’s an introduction.

Request data is sent as regular POST-variables (Content-Type: application/x-www-form-urlencoded). Responses from the API is in JSON format. In case of an error, you will receive a 403 Forbidden or 404 Not found reply. Error descriptions are sent as plain text in the HTTP content.

Callbacks like Incoming SMS, MMS, Recordings and Delivery Reports will be retried for up to 24 hours until a HTTP 200 OK response is received. The HTTP responses 201 through 204 are also supported.

SMS messages

Sending SMS

To send a new SMS simply POST to the /SMS resource. The “from” number can either be one of your previously allocated mobile phone numbers or an arbitrary alphanumeric string.

POST https://api.46elks.com/a1/SMS

from +46766861004 or "HelloWorld"
to +46704508449
message Don't forget the doctor at 08:35 tomorrow!

When using an alphanumeric “from” it needs to be between 3-11 characters in length and you are restricted to using only a-z, A-Z, 0-9. No other characters can be used, and the name has to begin with a letter. Upon request, we can also unlock other “from” numbers for your account.

Message texts and costs

SMS messages should always be sent to the API as URL-encoded UTF-8. The maximum text size of a single message is 160 characters. If your message contains characters not available in the GSM 03.38 basic character set it will be encoded as UTF16-BE which as a general rule means up to 70 characters in a single SMS message.

Longer and more expensive SMS messages can be sent. For messages within GSM 03.38 basic, the calculation is N * 153 where N is the number of SMS parts required. For UTF16-BE, the calculation is N * 67 - however, less for code points above 65535.

Splitting and joining multi-part SMS messages are automatically handled by the API. When your message is being split, your account will be charged for each SMS part.

Receiving SMS

Whenever there is an incoming SMS to one of your allocated 46elks numbers we will make a request to your chosen “sms_url” with the following POST-variables:

POST http://myservice.se/callback/newsms.php

from +46704508449
to +46766861004
message I want to buy 2 cartons of milk!

Replying to a received SMS

If you want to reply an incoming SMS, just send your reply as text in the HTTP response when your “sms_url” is being requested and it will be sent back to the originating mobile phone.

Thank you for your order.

If there is no text in the response or if HTTP 204 No Content response is received no message will be sent back to the originating mobile phone.

Flash SMS

Sometimes you want to show a message directly to the mobile phone user. In a more alerted way and without storing it. We call this cellphone feature Flash SMS. You can send these with 46elks by setting the POST variable “flashsms” to “yes” when sending SMS.

Check this tweet to see how a Flash SMS looks like on an iPhone.

Delivery reports

Optional delivery reports allow you to track invidual SMS messages you send, to find out if the have reached the destination. To activate delivery reports simply add your callback URL to the POST variable “whendelivered” when you send an SMS.

Whenever we have new delivery information regarding your SMS, we will make a POST request to your URL with the following:

POST http://myservice.se/callback/dlr.php

id The SMS id returned from POST to /SMS
status Either "sent", "delivered" or "failed"
delivered Time of delivery (only for status=delivered)

Some destinations and mobile networks does not support delivery reports. Thus, the status of SMS messages you send to such destinations will be “sent”. If the operator supports delivey reports, a message status can then change from sent to delivered or from sent to failed.

MMS messages

MMS enabled numbers

Not every number has support for MMS, be sure to look for the “mms” element in the “capabilites” array for your number with GET /a1/Numbers to see if the number you’re trying to use has MMS support enabled.

These numbers currently needs to be ordered manually.

Receiving MMS

When there’s an incoming MMS message to one of your numbers a request will be made to the URL as defined by “mms_url” with the following POST-variables:

POST http://myservice.se/callback/newmms.php

from +46704508449
to +46766861004
message Hello, world. This is an MMS.
image https://api.46elks.com/a1/images/i7fffc26a7d681205d90b278d86e184b0.jpg

The image contains a link the received JPG or PNG image. If there’s multiple images in a single MMS you’ll find them in image, image2, image3, …, imageN.

Outgoing calls

To create an outgoing call, simply POST to the /Calls resource. This will instruct 46elks to automatically call the number you have selected.

When the dialed number answers, the call will continue according to the "voice_start" argument of the POST.

POST https://api.46elks.com/a1/Calls

from One of your 46elks numbers
to The number you want to call, like +46704508449
voice_start URL or JSON of actions to execute
whenhangup URL you want 46elks to POST when call hangup or failed

How can I track unanswered outgoing calls?

Use the "whenhangup" variable if you want to be able to track calls which are never answered, such as busy or failed outgoing calls. This URL will be POST-requested when the call is hangup, either by failure to connect or after a connected call was finished and hangup.

Voice calls

Incoming calls

Incoming calls are controlled by the “voice_start” attribute on your phone number. The URL you put there will be requested every time there is a new incoming call.

If your “voice_start” contains a JSON object, that action will be triggered directly when incoming calls are received, without making any requests to your web server.

Voice actions

A phone call in 46elks is basically a set of actions and results. Each action is a JSON object explaining what you want to do. And by reading the results you control the flow of actions and ultimately reach the end of the call.

Hands on example

{
  "connect":"+46704508449"
}

If you use the above JSON as voice_start for an incoming call, it will connect the call to the swedish cell phone number 070-450 84 49 and upon answer allow the two callers to speak to each other.

Action chaining

To make something happen after an action is finished or when an action has a certain result, there are specific JSON keys you can define. Each action has it’s own possible results, but most actions have the “next” result key, which indicate “continue here regardless of result”.

Values for result keys can either be a new action object, or a URL string telling 46elks where to fetch action(s) from. URLs are retrieved with HTTP POST.

{
  "connect":"+46704508449",
  "busy":{
    "connect":"+46731704032"
  }
}

POST variables

The following variables are always included in the requests to your URLs. For completed actions, the variable “result” is also included.

direction incoming
from E.164 caller ID or empty if hidden
to E.164 of the called 46elks number
callid Unique ID for this call

Action - “connect”

Connect the call to a given number, and in the case of an answer, let the two callers speak to each other. The callerid indicates who is calling. You can set it to one of your 46elks numbers. If you leave it out, it will default to the incoming caller’s number.

connect E.164 destination number
callerid Either one of your 46elks numbers, or the callling number

Possible results:

busy Destination phone number is busy
success Call was answered and the destination phone has ended the call.
failed Destination phone didn't answer or couldn't be reached.
next Continue here regardless. If URL, result will include any of above.

Limitations:
Calls to mobile 46elks numbers can only "connect" to same-country mobile numbers.

Action - "hangup"

End the call. If this is your first action, it is possible to control signalling, otherwise only "reject" is allowed.

hangup "busy" or "reject" or "404"

Action - "play"

Play the given sound, which could be either a URL on your server or a sound resource provided by 46elks. URLs are fetched using HTTP GET and are always cached, so for unique resources be sure to provide unique URLs.

The plattform currently supports WAV, MP3 and OGG Vorbis.

{
  "play": "http://myserver.se/welcome.wav",
  "next": {
    "connect":"+46704508449",
    "busy":{
      "connect":"+46731704032"
    }
  }
}

For a successful “play” action, the result will be “next”. In case the resource or URL fails to load, the action result will be “failed”.

If the caller presses a digit during “play”, the call directly continues at “next”.

Sound resources and DTMF

Some builtin sound resources are provided by 46elks, such as beeps and DTMF tones. These are:

If you need to add some pause between DTMF tones, use p for one or more short 50ms pauses or the capital letter P for longer 500ms pauses.

There are also sound resources specific to a certain call. This is currently limited to recordings (read below), and all those resources are prefixed with “local”, such as “local/recording1”.

Action - “ivr”

The “ivr” action fills the purpose of playing a sound resource, while also retrieving digits punched by the caller. If no digits are retrieved after playback + 10 seconds of wait, the sound resource will be repeated up to 3 times. You can change the repeat count using the “repeat” key, and how many seconds to wait for input can be changed with the “timeout” key.

By default, the action is completed directly when a single digit has been received. If you want to allow input of more digits, use the “digits” key.

The result of this action is the digits retrieved.

{
  "ivr": "http://myserver.se/menu.wav",
  "1": {
    "play": "http://myserver.se/one.wav"
  },
  "2": {
    "play": "http://myserver.se/two.wav"
  }
}

Can I receive the pressed digits?

Yes, instead of coding the options within the JSON you can instruct the 46elks platform to pass the pressed digits to your script, regardless of what the caller press. Simply set the key “next” to your URL.

{
  "ivr": "http://myserver.se/enterpin.wav",
  "digits": 5,
  "next": "http://myserver.se/login.php"
}

You will get the digits pressed in the “result” POST variable.

result 12345

Action - “record”

Record the voice of the caller with this action. Useful for building your own voicemail. By default, recording stops after 3 seconds of silence or when 2 minutes of voice has been recorded.

Control the timelimit by adding an integer to the key “timelimit. Specified in seconds.

The recording can be saved either directly to a URL of your choice, or stored in the platform locally to allow playback before saving the recording. Set “record” to “local/recording1” if you want to allow playback within the same call. All local recordings are discarded when the call ends.

{
  "play": "http://myserver.se/entervoicemail.wav",
  "next": {
    "record": "http://myserver.se/newvoicemail.php"
  }
}

POST http://myserver.se/newvoicemail.php

created When the recording was stored
duration Audio length in seconds
wav URL where you can request the WAV audio
callid Source callid for this recording
direction Direction of the call
from E.164 caller id
to E.164 destination of the call

When does an incoming call end?

Either when your action chain is empty, or when the caller has hangup. Execution of the action chain will not continue in the case of caller hangup, simply because then there is no longer any call to control.

Call recording

With 46elks, you can record the full contents of both incoming and outgoing calls.

Option - “record call”

At any level within your tree of voice actions, you can put the key “record call”. When reaching that depth in your JSON tree, the call will start to be recorded.

{
  "play": "http://myserver.se/connecting.wav",
  "next": {
    "connect": "+46704508449",
    "recordcall": "http://myserver.se/newrecording.php"
  }
}

The value for your “record call” should be a URL, and this URL will be POSTed when the call has ended and the recording is done (much like how action “record” works).

Phone numbers

For anything other than just sending SMS, you need one or more 46elks phone numbers. You can either allocate phone numbers manually within the dashbord or using the API.

Number allocation

To allocate a new 46elks phone number make a POST request to the resource /Numbers. The variable “country” is mandatory, while other variables are optional.

POST https://api.46elks.com/a1/Numbers

country se
sms_url http://myservice.se/callback/newsms.php
mms_url http://myservice.se/callback/newmms.php
voice_start http://myservice.se/callback/newcall.php

The response when allocating a new number looks like below, and is exactly the same as when you query a number previously allocated:

GET https://api.46elks.com/a1/Numbers/n57c8f48af76bf986a14f251b35389e8b

{
  "id": "n57c8f48af76bf986a14f251b35389e8b",
  "active": "yes",
  "country": "se",
  "number": "+46766861001",
  "capabilities": [ "sms", "voice", "mms" ],
  "sms_url": "http://myservice.se/callback/newsms.php",
  "mms_url": "http://myservice.se/callback/newmms.php",
  "voice_start": "http://myservice.se/callback/newcall.php"
}

Modification and deallocation

For incoming SMS messages, the attribute “sms_url” on your numbers is used. And for incoming Voice calls, “voice_start” it what you are looking for. If you ever need to change these, either do it manually in the dashboard or use the API and simply do a POST like this:

POST https://api.46elks.com/a1/Numbers/n57c8f48af76bf986a14f251b35389e8b

sms_url http://myservice.se/callback/newsms2.php
voice_start http://myservice.se/callback/newcall2.php

You can also deallocate one of your numbers by setting “active” to “no”. Beware that there is no way to get your number back once it has been deallocated.

46elks credits will be consumed at time of allocation and each new month until deallocated.

SMS & calls history

You can list the SMS messages you have sent and recevied with a simple GET to /SMS. The same can be done for calls, by accessing the /Calls resource.

SMS history

By default you get the 100 latest items.

GET https://api.46elks.com/a1/SMS

{
  "data": [
    {
      "id": "s17a6dafb12d6b1cabc053d57dac2b9d8",
      "created": "2012-03-14T09:52:07.302000",
      "direction": "outgoing",
      "from": "MyService",
      "to": "+46704508449",
      "message": "Hello hello",
      "status": "delivered",
      "delivered": "2012-03-14T09:52:10Z",
      "cost": 3500
    },
    {
      "id": "s299b2d2a467945f59e1c9ea431eed9d8",
      "created": "2012-03-14T08:44:34.608000",
      "direction": "outgoing-reply",
      "from": "+46766861069",
      "to": "+46704508449",
      "message": "We are open until 19:00 today. Welcome!",
      "status": "delivered",
      "delivered": "2012-03-14T08:44:36Z",
      "cost": 3500
    },
    {
      "id": "s292d2a459e967945fb1c9ea431eed9d8"
      "created": "2012-03-14T08:44:34.135000",
      "direction": "incoming",
      "from": "+46704508449",
      "to": "+46766861069",
      "message": "Hours?",
      "cost": 3500
    }
  ],
  "next": "2012-02-21T14:15:30.427000"
}

The response is in JSON format. The key “data” contains a list of the items you requested. There is also a key named “next”, which can be used to older history. Do this by adding a “start” argument to your GET request, set to the value of your last “next”.

GET https://api.46elks.com/a1/SMS?start=2012-02-21T14:15:30.42700

{
  "data": [
    {
      "id": "s053d57dac2b9d894a6dafb12d6b1ca12",
      "created": "2012-02-21T14:15:30.427000",
      "direction": "outgoing",
      "from": "TestElk",
      "to": "+46704508449",
      "message": "One two three testing",
      "status": "delivered",
      "delivered": "2012-02-21T14:15:34Z",
      "cost": 3500
    }
  ]
}

This way you can fetch your full SMS & Calls history if needed.

Calls history

The Calls history works the same way as the SMS history.

GET https://api.46elks.com/a1/Calls

{
  "data": [
    {
      "direction": "incoming",
      "from": "+46784325653",
      "to": "+46766861388",
      "created": "2016-02-28T23:54:24.469000",
      "actions": [
        {
          "play": "http://www.hack46.com/test.mp3",
          "result": "ok"
        },
        {
          "record": "http://zapier.com/hooks/catch/opi0ea/",
          "result": "ok"
        }
      ],
      "start": "2016-02-28T23:54:24.427000",
      "state": "success",
      "duration": 32,
      "id": "c361e5927d124d7dcf71a142dc0ec6d9b"
    },
    {
      "direction": "outgoing",
      "from": "+46766862344",
      "to": "+46723175800",
      "created": "2015-05-20T11:23:14.486000",
      "actions": [
        {
          "connect": "+46734082791",
          "result": "success"
        }
      ],
      "start": "2015-05-20T11:23:34.156000",
      "state": "success",
      "cost": 15800,
      "duration": 17,
      "legs": [
        {
          "duration": 6,
          "to": "+46734082791",
          "state": "success",
          "from": "+46766862344"
        }
      ],
      "id": "c10d90e4fcd7d976360509fdec5049e81"
    },
    {
      "direction": "outgoing",
      "from": "+46723175800",
      "to": "+46766861524",
      "created": "2015-03-17T12:03:37.745000",
      "actions": [
        {
          "hangup": "busy"
        }
      ],
      "state": "busy",
      "id": "c451f1dd5233fb9af000290e9f24712c0"
    }
  ]
}

Subaccounts

Are many different customers using the services you have built using 46elks? Subaccounts allow you to separate your different customers within the 46elks platform. Subaccounts have their own 46elks numbers and traffic history, isolated from other subaccounts.

As expected, subaccounts use 46elks credits from your main 46elks account.

Adding a subaccount

In order to create a new subaccount, simply make an HTTP POST to the /Subaccounts resource. The only mandatory key when creating a new subaccount is the key “name”.

POST https://api.46elks.com/a1/Subaccounts

name Sample Customer AB

The reply will look like this:

{
  "id": "a123457da5678d894a6dafb1212b1ca12",
  "secret": "A347215F5F799B814462C37694D2383D",
  "name": "Sample Customer AB",
  "balanceused": 0
}

Using a subaccount

The keys “id” and “secret” is the new API username and API password you should use in order to access the 46elks API for this subaccount. Use these API credentials when you want to make API requests for the subaccount.

Subaccounts are isolated from each other, and there is no way for a subaccount to access information about the main account. It is thus possible to safely deploy the subaccount credentials to a customers server or application.

Can I limit how much credit a subaccount can use?

Yes, make an HTTP POST to the specific subaccount’s resource and set “usagelimit” to the requested value. Once this is set and “balanaceused” reach “usagelimit”, credit consumption for this subaccount will be denied

POST https://api.46elks.com/a1/Subaccounts/a123457da5678d894a6dafb1212b1ca12

name New Name AB
usagelimit 200000

As usual, your setting is returned in the reply if set successfully:

{
  "id": "a123457da5678d894a6dafb1212b1ca12",
  "secret": "A347215F5F799B814462C37694D2383D",
  "name": "New Name AB",
  "balanceused": 7000,
  "usagelimit": 200000
}

The value of the number used in usagelimit depends on the currency set in your account. If you're using €, and want to set the total usage limit for this account to 200€, you'd set the usagelimit to 2000000 (200 * 100 * 100)

If you're using for example SEK, and you want to limit the account to 200:-, you'd also set the usagelimit to 2000000 (200 * 100 * 100)