View Categories

Call Control API

8 min read

TENIOS allows to delegate the call control (partially) to a customer’s own server. This functionality is enabled by inserting an Call Control API block into a routing configuration.

In order to be able to use the Call Control API, you need an HTTPS-capable web server (e.g. Apache httpd or nginx) that is already used for processing HTTPS traffic (SSL / TLS). More Information can be found here on Github.

Request parameters (from TENIOS to your server):

requestType The type of API request. This is always EXTERNAL_CALL_CONTROL for Call Control API requests
customerNumber Your customer number (the same value you see in parentheses in the top right corner of the TENIOS customer portal) Please verify with every request.
accessKey The accessKey you chose in the initial setup of the Call Control API block (via TENIOS customer portal) Please verify with every request.
variables A key/value map with the keys you chose in the initial setup of the Call Control API block (via TENIOS customer portal) Can be used for anything, be it logging, or deciding the next steps.
loopCount Starting from 0, counts the number of requests that have been made within this instance of the API Routing Control block In many simple applications, you will only want to send blocks, if loopCount is 0. Advanced applications may want to continue sending blocks in multiple iterations.
requestStatus Possible Types are:

  • REQUESTING_BLOCKS: means that you are allowed (and expected) to send 0 or more blocks in your response.
  • VALIDATION_ERRORS: means, that you should look into blocksProcessingResult in validationErrors
    • you are not allowed to send any more blocks in your response (actually, your response will then be completely ignored. You should send a status code of 200, with any content). See the “Basic example” and “Basic example with error case” above.
blocksProcessingResult (only for loopCount > 0) Contains the field validationErrors, which in turn contains a list of validation error messages. In the future, blocksProcessingResult will probably contain more information.

Response parameters (from your server to TENIOS):

blocks An array of blocks. If this array is empty, the dialplan server will finish the Call Control API block, and continue the normal processing of the call.
Each block must have the following format:
blockType Mandatory Type of block. Possible types are:

  • BRIDGE: is for call forwarding (PARALLEL or SEQUENTIAL)
  • ANNOUNCEMENT: is for announcement playback (standard announcements, or announcements uploaded by you on the TENIOS customer portal)
  • SAY: is for speaking texts (Text to Speech)
  • ROUTINGPLAN: can be used to refer to a specific Named Routingplan (Named Routingplans can be set up via the TENIOS customer portal)
  • COLLECT_DIGITS: can be used to collect (multiple) digits via DTMF into a named variable. Note: You can then see the value of that variable in the subsequent Call Control API requests for the same call.
  • COLLECT_SPEECH: can be used to recognize voice input.
  • HANGUP: is for hangup a call with a specified hangup cause.
  • CALL_SETTINGS: sets the callerid, that is displayed when calling.
blockTimeout Timeout in seconds for the entire block. Some blocks require this attribute, others do not allow it:

  • BRIDGE blocks in PARALLEL mode require this attribute
  • BRIDGE blocks in SEQUENTIAL mode do NOT allow this attribute
  • ANNOUNCEMENT block does NOT allow this attribute
  • HANGUP block does NOT allow this attribute
Further information on the block-specific attributes and examples can be found in API-Spec.

Process flow:

The content-type for all HTTP(s) requests and responses in this API is application/json.

When a call enters the Call Control API block, a POST request is sent from TENIOS to your server.

TENIOS POST-Request 0:

{ 
    "requestType" : "EXTERNAL_CALL_CONTROL", 
    "customerNumber" : 200000, 
    "accessKey" : "XXXXX-XXXX-XXXXXX", 
    "variables" : { 
                    "call_uuid" : "1ecd8430-a926-11e3-a701-f9e70cd7ff59", 
                    "destination_number" : "+49800123456789", 
                    "caller_id_number" : "+4989444444444" 
                  }, 
    "loopCount" : 0, 
    "requestStatus" : "REQUESTING_BLOCKS",  
    "blocksProcessingResult" : null 
}
  • loopCount: 0 means that this is the initial request for this Call Control API block (there will be more requests, see later)
  • requestStatus: “REQUESTING_BLOCKS” means that you are allowed to send routing blocks in your response
  • A blocksProcessingResult of null can be ignored for the initial request.

Sample response from your server to TENIOS:

You can respond to this HTTPS request as follows

Customer server response 0:

with one Block

{
  "blocks" : [ {
    "blockType" : "ANNOUNCEMENT",
    "announcementName" : "Voicemail_Ansage",
    "standardAnnouncement" : true
  } ]
}

  • you could also send multiple blocks by comma-separating them within the blocks array
  • the announcement block (blockType: “ANNOUNCEMENT”) uses a standard announcement (i.e. one that’s provided by TENIOS, NOT uploaded by yourself)
  • the announcement is identified by its name “Voicemail_Ansage” (More Information can be found in API-Spec.)

Customer server response 0:

with more than one Block

{ 
   "blocks" :
   [ 
       { "blockType" : "ANNOUNCEMENT", 
         "announcementName" : "Voicemail_Ansage", 
         "standardAnnouncement" : true
       }, 
       { "blockType" : "SAY", 
          "text" : "Hello, how are you doing?", 
          "voiceName" : "de.female.3", 
          "useSsml" : false
       }, 
       {  
         "blockType" : "BRIDGE",
         "destinations" : [ { "destination" : "1001",
                              "destinationType" : "SIP_USER",
                              "timeout" : 25 }, 
                            { "destination" : "+4978787878",
                              "destinationType" : "EXTERNALNUMBER",
                              "timeout" : 30 }
                           ],
        "bridgeMode" : "SEQUENTIAL"
       }
   ] 
}

 

Upon receiving your response, our dialplan server will (try to) execute your blocks. Let’s assume in this case, that everything went well, and the announcement finished playing. Then after that, you will receive another request like:

TENIOS POST-Request 1:

{
  "requestType" : "EXTERNAL_CALL_CONTROL",
  "customerNumber" : 200000,
  "accessKey" : "XXXXX-XXXX-XXXXXX",
  "variables" : {
    "call_uuid" : "1ecd8430-a926-11e3-a701-f9e70cd7ff59",
    "destination_number" : "+49800123456789",
    "caller_id_number" : "+4989444444444"
  },
  "loopCount" : 1,
  "requestStatus" : "REQUESTING_BLOCKS",
  "blocksProcessingResult" : {
    "validationErrors" : [ ]
  }
}
  • loopCount has increased to 1 meaning this is the second request (we started to count at 0)
  • requestStatus is again “REQUESTING_BLOCKS”, which means that you are allowed again to send routing blocks in your response (if you want)
  • blocksProcessingResult contains an empty array of validationErrorswhich is good: It means that your previous response didn’t result in any validation errors.

In the future, there will probably be more interesting information available in the blocksProcessingResult. If you’re missing anything here, please contact customer support!
If the call is accepted, you will not receive any further TENIOS requests. You can configure additional call information in real time in the “Advanced Settings” for call number routing. You can also find details in API Call-Posts.
Now let’s say, that you don’t want to send any more blocks, in which case you should send the following simple response:

Customer-Response 1:

no further Blocks
{
   "blocks": []
}
After that, our dialplan server will continue with the normal processing of the call (so if you have configured more blocks in the TENIOS customer portal, which come after the Call Control API block, they will be executed now).

Examples of invalid requests:

In case the blocks you sent e.g. in Response 0 contain an error:

Kundenserver-Response 0:

(with error)

{ 
   "blocks" : [ 
               { "blockType" : "ANNOUNCEMENT", 
                 "standardAnnouncement" : true 
                } 
              ]
 }

In this case the announcementName attribute is missing. As soon as one of the blocks you sent contains validation errors, the Call Control API block will be terminated, however, you will receive another request that will inform you about the error:

TENIOS POST-Request 1:

Information about the error

{  
     "requestType" : "EXTERNAL_CALL_CONTROL", 
     "customerNumber" : 200000, 
     "accessKey" : "XXXXX-XXXX-XXXXXX",
     "variables" : { "call_uuid" : "1ecd8430-a926-11e3-a701-f9e70cd7ff59", 
                     "destination_number" : "+49800123456789", 
                     "caller_id_number" : "+4989444444444" }, 
     "loopCount" : 1,
     "requestStatus" : "VALIDATION_ERRORS", 
     "blocksProcessingResult" : { 
                                  "validationErrors" : [ "Validation error: blocks[0].announcementName may not be null" ]
                                 }
 }
  • the requestStatus is not “REQUESTING_BLOCKS” anymore – which means you cannot send any more blocks (they would be ignored if you do). Instead, it now has the value “VALIDATION_ERRORS”, which means you should look into blocksProcessingResult
  • blocksProcessingResult validation errors contains error messages, which should help a bit to pinpoint the error (Please note that for some errors on a lower JSON level, you will only receive the line and column number)
More Information about block-specific attributes and Examples can be found in API-Spec.
Call control functions can optionally be integrated via macecall function. Details can be found in API Make call.

General notes

When you receive a request, you have a time frame of (currently) 30 seconds to respond. Please note, that between the time the dialplan server enters the block until a response is received, the call does nothing – so it’s in your best interest to respond as quickly as possible. For the same reason, if you need to submit multiple blocks, it’s most efficient to submit them as multiple blocks within a single response (as opposed to just responding with one block, then waiting for our next request, then sending the next block, …). However, this is clearly not always possible. If you send a response with a HTTPS code not equal to 200, the Call Control API block will be terminated.But please always prefer to respond with HTTPS code 200, and the content {“blocks”:[]} , if you just want to terminate the Call Control API block without indicating an error!

You might also be interested in this article …

TOP