Getting started

Getting Started

API Basics

APIs

Authentication

Blocklists

Call Channels

Call Center

Call Recordings

Devices

Pivot

Quickcall

Webhooks

Business SMS

VirtualText

Automation

Zapier

Use cases

Create Trello Card for Voicemails Received

Send Call Data to Google Sheets

Slack Notifications from Call Events

SMS Airtable Template

Trigger SMS Messages from Your CRM

Zapier Webinar Recording

About Pivot

The Pivot gives developers control over Inbound Call Handling. Pivot send call details via HTTP to the developer's web server. Pivot expects a response with appropriate JSON, and will execute the callflow returned on behalf of the developer.

A Pivot can be used in callflows in anywhere you want the external application to determine call routing and manage the call experience.

A Pivot can build complex call handling using a wide range of callflow elements. Complex call control may requiere muliple pivots.

To configure Pivots you need to have Advance Call Flows feature enabled on your account.

Use Cases

Example Callflow

The most basic callflow for Pivot:

JSON

{
 "flow":{
     "module":"pivot"
     ,"data":{
         "voice_url":"<http://your.pivot.server/path/to/script.php>"
         ,"req_format":"kazoo"
         ,"method":"get"
         ,"debug":false
     }
 }
}

Debugging

You can set the debug flag to "true" to log the requests and responses Pivot receives from your Pivot Callflows.

Summary

Get a list of recent Pivot attempts:

Shell

$ curl -H "X-Auth-Token: {AUTH_TOKEN} \\
     -H "Content-Type: application/json" \\
     '<http://api.virtualpbx.net/v2/accounts/{ACCOUNT_ID}/pivot/debug>'

Response:

JSON

{
   "data":{
      "name":"Missed Call",
      "hook":"notifications",
      "include_subaccounts":false,
      "http_verb":"get",
      "retries":4,
      "uri":"<https://hooks.zapier.com/hooks/catch/591668/xlwslm/>",
      "type":"account",
      "action":"doc_created",
      "custom_data":{
         "type":"missed_call"
      },
      "enabled":true,
      "include_internal_legs":true,
      "id":"51840ffc8bde832a1f5477def32cd665"
   }
}

Specific Call

Get details of a specific Pivot attempt:

Shell

$curl -H "X-Auth-Token: {AUTH_TOKEN} \\
    -H "Content-Type: application/json" \\
    '<http://api.virtualpbx.net/v2/accounts/{ACCOUNT_ID}/pivot/debug/{CALL_ID}>'

Response:

JSON

{
    "auth_token": "{AUTH_TOKEN}",
        "data": [
        {
            "call_id": "{CALL_ID}",
            "id": "{DEBUG_ID}",
            "method": "get",
            "req_body": "",
            "req_headers": {},
            "uri": "<http://your.pivot.server/script.php?Caller-ID-Number=XXXXXXXXXX&Caller-ID-Name=JoeFromIT&Direction=inbound&ApiVersion=2013-05-01&ToRealm=your.pivot.server&To=3004&FromRealm=your.pivot.server&From=user_sov2kt&Account-ID={ACCOUNT_ID}&Call-ID={CALL_ID}>"
        },
        {
            "call_id": "{CALL_ID}",
            "id": "{DEBUG_ID}",
            "resp_body": "\\n    {\\"module\\":\\"say\\"\\n     ,\\"data\\":{\\"text\\":\\"Please leave your message after the beep\\"}\\n     ,\\"children\\":{\\n         \\"_\\":{\\n           \\"module\\":\\"record_caller\\"\\n           ,\\"data\\":{\\n               \\"format\\":\\"mp3\\"\\n               ,\\"url\\":\\"<http://your.pivot.server/recordings\\>"\\n               ,\\"time_limit\\":360\\n           }\\n         }\\n        }\\n    }\\n"
        },
        {
        "call_id": "{CALL_ID}",
        "id": "{DEBUG_ID}",
        "resp_headers": {
            "content-length": "342",
            "content-type": "application/json",
            "date": "wed, 01 oct 2014 23:30:24 gmt",
            "server": "apache/2.4.7 (ubuntu)",
            "x-powered-by": "php/5.5.9-1ubuntu4.4"
        },
        "resp_status_code": "200"
    }
    ],
    "request_id": "{REQUEST_ID}",
    "revision": "{REVISION}",
    "status": "success"
    }

Remember to URL-encode the {CALL_ID} before sending the request.

Failback

You can add a children to your pivot callflow in case your server is unreachable or send back an error.

JSON

"flow": {
    "data": {
        "method": "GET",
        "req_timeout": "5",
        "req_format": "kazoo",
        "voice_url": "{SERVER_URL}"
    },
    "module": "pivot",
    "children": {
        "_": {
            "module": "play",
            "data": {
                "id": "{MEDIA_ID}"
            },
            "children": {}
        }
    }
}

The Request Payload

You can configure whether you receive the data as a query string in a GET or as a URL-encoded body in a POST.

Payload

Some of the fields may not be included in every request.

Field Description
Call-ID The unique call identifier
Account-ID The account id receiving the call
From The SIP From username
From-Realm The SIP From realm
To The SIP To username
To-Realm The SIP To realm
Request The SIP Request username
Request-Realm The SIP Request realm
Call-Status Status of the call
Api-Version The version of the API
Direction The direction of the call, relative to VirtualPBX
Caller-ID-Name Caller ID Name
Caller-ID-Number Caller ID Number
User-ID The VirtualPBX User identifier(s) of the caller
Language The caller's language preference
Recording-Url Where the recording will be stored
Recording-Duration How long the recording is
Recording-ID The recording id
Digits Any DTMF (or collection of DTMFs) pressed

JSON Overview

Sometimes VirtualPBX's callflow builder doesn't match your needs, integrate with your applications, or provide the experience for your caller that you desire. Fortunately, the building blocks are available for you to play with as you see fit!

By routing a call to a Pivot callflow action, Vi will make an HTTP request to your web server asking for the callflow to process for that specific call (versus the one-size-fits-all approach in the normal callflow builder).

This could be best illustrated with an example, no?

Building Time-based routing

We want to add time-based rules when deciding how to route our office's main number (this exists with the temporal_route callflow action already, but we're trying to make a point!). Following a "typical" office's hours, we are open 9am-5pm (9:00 to 17:00). During that time, we'd like to ring the front desk's phone. Outside of those hours, we'd like calls to go directly to the company's voicemail box.

Example of Building on Pivot

Based on the above goals, we need to build:

Once you've made those, note the IDs for the device and voicemail box (using the developer tool is a good way to find those).

The main number callflow should be:

Plain Text

[NUMBER] -> Pivot
            Url: <http://your.webserver.com/path/to/main_number_tod.php>

Now, whenever this number is called, VirtualPBX will query your URL for callflow to execute.

Build main_number_tod.php

The first thing needed is to set the content-type to application/json.

PHP

<?php
    header('content-type:application/json');

Now we need to know what time it is and determine what to do:

PHP

$now = time();
$hour = date("G", $now);
if ( $hour >= 9 && $hour < 17 ) {
  business_hours();
} else {
  after_hours();
}

Now we have two functions to build the JSON for the callflow to execute:

Bring it all together:

PHP

<?php
    header('content-type:application/json');
    $now = time();
    $hour = date("G", $now);
    if ( $hour > 8 && $hour < 17 ) {
      business_hours();
    } else {
      after_hours();
    }
    function business_hours() {
    ?>
      {"module":"device"
       ,"data":{"id":"{FRONT_DESK_DEVICE_ID}"}
       ,"children":{
         "_":{
           "module":"voicemail"
           ,"data":{"id":"{COMPANY_VM_BOX_ID}"}
         }
       }
    <?php
    }
    function after_hours() {
    ?>
      {"module":"voicemail"
       ,"data":{"id":"{COMPANY_VM_BOX_ID}"}
      }
    <?php
    }
?>

TwiML Format

Pivot supports a subset of TwiML to help ease you into Pivot with an existing TwiML-based application.

Core Supported

Default Request Data included

| --- | --- | --- |

Optional/Conditional Request Data