- Print
- DarkLight
- PDF
Authentication
To obtain an api-key you will initially need to authenticate using a username/password combination.
POST /api/v1/oauth/authorize
Content-Type: application/x-www-form-urlencoded
Accept: application/json
username=demo&password=1234
On successful authentication, the following json will be returned containing a JWT access token which should b stored for future REST calls.
Response 200 OK
{
"access_token" : "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2MTE4Njc5MzksImV4cCI6Mdvas...",
"refresh_token" : "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJmODBjYmYzZS1kMWM5LTQwZWItOGZjYS1hY2I4MDU5ZmYyOTcifQ.eyJleH..."
"refresh_expires_in": 36000
"expires_in" : 3600
}
The JWT will contain important information, for example, the allowed roles for your user:-
...
"realm_access": {
"roles": [
"OrganisationAdmin",
"AdminRecorder",
"VoiceChannel"
]
}
...
Head over to jwt.io to take a peak at the full token details. Also there are plenty of libraries to decode the jwt, here is a few:
Language | Library / CMD |
---|---|
Python | pip install pyjwt |
Node.js | npm install jsonwebtoken |
Java | maven: io.jsonwebtoken / jjwt-root / 0.11.1 |
PHP | composer require firebase/php-jwt |
Refresh Token
The refresh_token expiry is longer than the access_roken expiry. Use will need to use the refresh_token to renew your access_token when it expires.
POST /api/v1/oauth/authorize
Content-Type: application/x-www-form-urlencoded
Accept: application/json
token=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIi...
A successful response will return a new json object as above .
Organisation
Get Organisation Details
GET /api/v1/userAccounts/me
Authorization: Bearer {access_token}
Accept: application/json
Response 200 OK
{
"id" : "3h74872eb0731b38efa4d556",
"name" : "Demo Organisation"
}
Account
List Accounts
GET /api/v1/account
Authorization: Bearer {access_token}
Accept: application/json
Response 200 OK
[
{
"id" : "5554872eb0731b38efa4d444",
"name" : "Darren's Pizzas"
},
{
"id" : "5564872eb0731b38efa4d555",
"name" : "Dean's Taxis"
}
]
Get Account Details
Get Darren's Pizzas account details
GET /api/v1/account/5554872eb0731b38efa4d444
Authorization: Bearer {access_token}
Accept: application/json
Response 200 OK
{
"id" : "5554872eb0731b38efa4d444",
"name" : "Darren's Pizzas"
"mbn" : "441234567890",
"domain" : "darrenspizzas"
}
Get Account Address
Darren's Pizzas Address
GET /api/v1/account/5554872eb0731b38efa4d444/address
Authorization: Bearer {access_token}
Accept: application/json
Response 200 OK
{
"line1" : "Unit 5 The Old Printworks",
"line2" : "20 Wharf Rd",
"level1" : "East Sussex",
"level2" : "Eastbourne",
"postalCode" : "BN213AW",
"country" : "United Kingdom"
}
Update Account Address
Update Darren's Pizzas Address
PUT /api/v1/account/5554872eb0731b38efa4d444/address
Authorization: Bearer {access_token}
Accept: application/json
{
"line1" : "Unit 5 The Old Printworks",
"line2" : "20 Wharf Rd",
"level1" : "East Sussex",
"level2" : "Eastbourne",
"postalCode" : "BN213AW",
"country" : "United Kingdom"
}
Response 204 No Content
Inbound Numbers
Inbound numbers or DDIs connect to voice flows allowing for inbound routing of voice. To allocate a new DDI please see Porting & Allocations
List DDIs
Get Darren's Pizza's inbound ddis
GET /api/v1/account/5554872eb0731b38efa4d444/ddi
Authorization: Bearer {access_token}
Accept: application/json
Response 200 OK
[
{
"id" : "7774872eb9991b38efa4d888",
"name" : "441234567890"
},
{
"id" : "8884872eb9991b38efa4d999",
"name" : "441234567891"
}
]
SIP Trunking
Add authorised IP addresses to whitelist the connection of onsite PBX equipment.
List Trunks
Get Darren's Pizza's sip trunks
GET /api/v1/account/5554872eb0731b38efa4d444/trunk
Authorization: Bearer {access_token}
Accept: application/json
Response 200 OK
[
{
"id": "66aa8915-834a-3004-8363-9c73690d8fe1",
"ip": "1.1.1.1,
"port": 5060,
"vendor": "generic",
"callerFormat": "national",
"calledFormat": "national",
"description": "Primary IP Address",
"zone": "eu-west-1",
"countryCode": "GB"
}
]
Get Trunk
Get Darren's Pizza's sip trunk
GET /api/v1/account/5554872eb0731b38efa4d444/trunk/66aa8915-834a-3004-8363-9c73690d8fe1
Authorization: Bearer {access_token}
Accept: application/json
Response 200 OK
{
"id": "66aa8915-834a-3004-8363-9c73690d8fe1",
"ip": "1.1.1.1,
"port": 5060,
"vendor": "generic",
"callerFormat": "national",
"calledFormat": "national",
"description": "Primary IP Address",
"zone": "eu-west-1",
"countryCode": "GB"
}
Create a Trunk
Create a Darren's Pizza's sip trunk
POST /api/v1/account/5554872eb0731b38efa4d444/trunk
Authorization: Bearer {access_token}
Accept: application/json
Content-Type: application/json
{
"ip": "1.1.1.1,
"port": 5060,
"vendor": "generic",
"callerFormat": "national",
"calledFormat": "national",
"description": "Primary IP Address",
"zone": "eu-west-1",
"countryCode": "GB"
}
Response 201 Created
Update a Trunk
Update Darren's Pizza's sip trunk
PUT /api/v1/account/5554872eb0731b38efa4d444/trunk/66aa8915-834a-3004-8363-9c73690d8fe1
Authorization: Bearer {access_token}
Content-Type: application/json
{
"id": "66aa8915-834a-3004-8363-9c73690d8fe1",
"ip": "1.1.1.1,
"port": 5060,
"vendor": "generic",
"callerFormat": "national",
"calledFormat": "national",
"description": "Primary IP Address",
"zone": "eu-west-1",
"countryCode": "GB"
}
Response 204 No Content
Hooks
Use flow-hooks to allow 3rd parties to control the flow. event-hooks allow you to receive communication events.
List Hooks
Get Darren's Pizza's hooks
GET /api/v1/account/5554872eb0731b38efa4d444/hook
Authorization: Bearer {access_token}
Accept: application/json
Response 200 OK
[
{
"id": "2ad34a16-dc17-42da-b67a-4d68d0046832",
"app": "flow.generic",
"url": "http://test.com/myplugin",
"authType": "DISABLED",
"method": "POST",
"priority": 10
},
{
"id": "3ab34a16-dc17-42da-b67a-4d68d0046822",
"app": "event.generic",
"url": "http://test.com/myevent",
"authType": "DISABLED",
"method": "POST",
"priority": 10
}
]
Get Hook
Get Darren's Pizza's hook
GET /api/v1/account/5554872eb0731b38efa4d444/hook/3ab34a16-dc17-42da-b67a-4d68d0046822
Authorization: Bearer {access_token}
Accept: application/json
Response 200 OK
{
"id": "3ab34a16-dc17-42da-b67a-4d68d0046822",
"app": "event.generic",
"url": "http://test.com/myevent",
"authType": "DISABLED",
"method": "POST",
"priority": 10
}
Create a Hook
Create a Darren's Pizza's hook
POST /api/v1/account/5554872eb0731b38efa4d444/hook
Authorization: Bearer {access_token}
Accept: application/json
Content-Type: application/json
{
"app": "event.generic",
"url": "http://test.com/myevent",
"authType": "DISABLED",
"method": "POST",
"priority": 10
}
Response 201 Created
Update a Hook
Update Darren's Pizza's sip trunk
PUT /api/v1/account/5554872eb0731b38efa4d444/hook/3ab34a16-dc17-42da-b67a-4d68d0046822
Authorization: Bearer {access_token}
Content-Type: application/json
{
"id": "3ab34a16-dc17-42da-b67a-4d68d0046822",
"app": "event.generic",
"url": "http://test.com/myevent",
"authType": "DISABLED",
"method": "POST",
"priority": 10
}
Response 204 No Content
Flow Devices
Devices are the main components of voice flows. Join devices together to create simple to advanced call flows.
List Devices
Get Darren's Pizza's flow devices
In the example below, we can see 2x devices, SIP_GATEWAY & ROUTE_START. This is the basis for a very simple SIP Trunking call flow.
The ROUTE_START device is the entry point for the DDIs to map to the flow and the SIP_GATEWAY device maps the trunks. Pay attention to the connectTo field which maps to the id of a device. This connectTo field may also be populated with an enum, usually HANGUP.
Device Types are defined in more details in the Flow Device Overview
GET /api/v1/account/5554872eb0731b38efa4d444/device
Authorization: Bearer {access_token}
Accept: application/json
Response 200 OK
[
{
"id": "7aa48c2a-aa01-488b-abfb-4eabce3ce9f8",
"type": "SIP_GATEWAY",
"name": "Primary GW",
"extension": "601",
"sipGateway": {
"ringTime": 180,
"maxCallTime": 14400,
"record": false,
"trunks": ["66aa8915-834a-3004-8363-9c73690d8fe1"],
"present": "pass-through",
"countryCode": "GB",
"onComplete": "HANGUP",
"onFail": "HANGUP",
"onNoAnswer": "HANGUP",
"onBusy": "HANGUP"
}
},
{
"id": "4db61df1-f214-4037-9a89-1276bc83a83a",
"type": "ROUTE_START",
"name": "Start of Flow",
"extension": "600",
"startRoute": {
"ddis": ["7774872eb9991b38efa4d888"],
"connectTo": "7aa48c2a-aa01-488b-abfb-4eabce3ce9f8"
}
}
]
Get Device
Get Darren's Pizza's device
GET /api/v1/account/5554872eb0731b38efa4d444/device/4db61df1-f214-4037-9a89-1276bc83a83a
Authorization: Bearer {access_token}
Accept: application/json
Response 200 OK
{
"id": "4db61df1-f214-4037-9a89-1276bc83a83a",
"type": "ROUTE_START",
"name": "Start of Flow",
"extension": "600",
"startRoute": {
"ddis": ["7774872eb9991b38efa4d888"],
"connectTo": "7aa48c2a-aa01-488b-abfb-4eabce3ce9f8"
}
}
Create a Device
Create a Darren's Pizza's flow device
Please checkout Flow Device Overview for more details on the Device model
POST /api/v1/account/5554872eb0731b38efa4d444/device
Authorization: Bearer {access_token}
Accept: application/json
Content-Type: application/json
{
"type": "ROUTE_START",
"name": "Start of Flow",
"extension": "600",
"startRoute": {
"ddis": ["7774872eb9991b38efa4d888"],
"connectTo": "7aa48c2a-aa01-488b-abfb-4eabce3ce9f8"
}
}
Response 201 Created
Update a Device
Update Darren's Pizza's flow device
PUT /api/v1/account/5554872eb0731b38efa4d444/device/66aa8915-834a-3004-8363-9c73690d8fe1
Authorization: Bearer {access_token}
Content-Type: application/json
{
"id": "4db61df1-f214-4037-9a89-1276bc83a83a",
"type": "ROUTE_START",
"name": "Start of Flow",
"extension": "600",
"startRoute": {
"ddis": ["7774872eb9991b38efa4d888"],
"connectTo": "HANGUP"
}
}
Response 204 No Content
Channels
Callable currently supports the voice channel allowing you to create, update and remove live voice calls, we will soon be supporting SMS & Email channels. Stay tuned!
Voice Channel
Create a Voice call
We can generate a new call by adhering the following JSON schema:
{
"callerId" : "",
"tag" : { ... },
"target" : { ... }
"verbs" : [ ... ]
}
Field | Description | Required |
---|---|---|
callerId | The number to present to the initially dialled target, if this is left blank then the main billing number of the account will be used | false |
tag | Contains a field "data" consisting of key / value pairs, these tags span the lifecycle of the call allowing contextual information to be applied | false |
target | A Dial verb, this can be of type Device , SipURI, PhoneNumber or Extension | true |
verbs | On answer of the original Dial, the call will then invoke these verbs. Verbs can be of type Dial, Say, Play, Gather, Reject, Hangup, Redirect | true |
Examples
Create a new outbound call for Darren's Pizzas and tell the customer their pizza is outside
POST /api/v1/account/5554872eb0731b38efa4d444/channels/voice
Authorization: Bearer {access_token}
Accept: application/json
Content-Type: application/json
{
"callerId" : "+441234567890",
"tag" : {
"data" : { "myKey" : "myValue" }
},
"target" : {
"phoneNumber" : { "number" : "+441234567893" }
},
"verbs" : [
{
"say" : {
"text" : [ "Your pizza is outside!" ]
}
},
{
"hangup" : { "reason" : "call-complete" }
}
]
}
Response 201 Created
Create a new outbound call to a registered sip trunk on a particular extension, on connect announce you are connecting them and then dial a phone number
POST /api/v1/account/5554872eb0731b38efa4d444/channels/voice
Authorization: Bearer {access_token}
Accept: application/json
Content-Type: application/json
{
"callerId" : "+441234567890",
"target" : {
"extension" : {
"extension" : "604", "overrideTo" : "201"
}
},
"verbs" : [
{
"say" : {
"text" : [ "Connection you now!" ]
}
},
{
"dial" : {
"callerId" : "+441234567890",
"timeout" : 10,
"timeLimit" : 14400,
"targets" : [
{ "phoneNumber" : { "number" : "+441234567891" } }
]
}
}
]
}
Response 201 Created