Supervising Calls

RingCentral Call Monitoring allows a person to receive a real-time audio stream so they can listen in on a call. The primary use case is a supervisor wishing to monitor and provide feedback on an agent's performance.

The Supervision API allows a developer to connect to an active phone call and subsubscribe to an audio stream programatically. Some use cases for this API include:

  • To provide a real-time transcription of a call.
  • To use NLP and AI to assist agents in helping resolve cases faster.

Partners today have used this API to provide RingCentral customers with call assistants that provide their agents with real-time suggestions to help provide customers with rapid and accurate recommendations. This scenario is visualized below. Once the call is established, the Supervision API can be used to connect an app to a call by providing:

  • Call's sessionId
  • Agent's extensionNumber
  • Supervisor's deviceId.

Prerequisites

Before you begin, please verify these prerequesites are met:

  1. Your RingCentral Account has the "Call Monitoring Group" feature enabled as described in this Knowledgebase article.

  2. You have set up a "Call Monitoring Group" with Agents and Supervisors in the Online Account Portal, or via the RingCentral API.

  3. The supervisor has been configured with a SIP device, such as VoIP phone or a SIP server, that is configured to auto-answer/respond to a SIP INVITE request.

No sandbox support

This feature is only available in a production enviornment and not supported in a sandbox enviornment.

Supervise Call API

The Supervise Call API is used to have RingCentral initiate a call out to a registered device such as a VoIP phone or SIP server as follows.

Request

The following is an example request showing the required parameters to add a supervisor to an existing call session.

POST /restapi/v1.0/account/{accountId}/telephony/sessions/{telephonySessionId}/supervise HTTP/1.1
Content-Type: application/json
Content-Length: ACTUAL_CONTENT_LENGTH_HERE
Authorization: <YOUR_ACCESS_TOKEN>

{  
   "mode": "Listen",
   "extensionNumber": "108",
   "deviceId": "60727004"
}
require 'ringcentral'

rc = RingCentral.new(
  'client_id',
  'client_secret',
  'https://platform.ringcentral.com')

rc.authorize username: '+16505550100',
  extension: '',
  password:  'my_password')

res = rc.post '/restapi/v1.0/account/{accountId}/telephony/sessions/{telephonySessionId}/supervise', payload: {  
   "mode": "Listen",
   "extensionNumber": "108",
   "deviceId": "60727004"
}

Parameters

Parameter Location Required? Description
accountId path required This is the unique identifier for the account associated with the request. This can be the actual id or ~ for the current accountId. The default ~ value is acceptable in all uses for this API.
telephonySessionId path required This is the unique identifier for the call, including all parties. See the next section on how to get a list of current telephony sessions.
deviceId body required This is the deviceId of the Supervisor's SIP device. You can get the supervisor's deviceId using the Extension device info API /restapi/v1.0/account/~/extension/~/device
extensionNumber body required The extension number of the agent whose call you want to monitor. Note: In future we shall also support extensionId.
mode body (required) Currently, the only method supported is Listen.

How to find the Session ID and Extension Number

The telephonySessionId and extensionNumber properties can be retrieved from any of the following:

  • Call Session Notification events
  • Account-level Presence API
  • Extension-level Presence API.

The following example shows how to retrieve the telephonySessionId uses the account-level presence API. The agent extension is in the extension.extensionNumber property and the telephonySessionId is in the activeCalls[0].telephonySessionId property.

{
   "uri":"https://platform.ringcentral.com/restapi/v1.0/account/809646016/extension/62226587016/presence",
   "extension":{
      "uri":"https://platform.ringcentral.com/restapi/v1.0/account/809646016/extension/62226587016",
      "id":62226587016,
      "extensionNumber":"108"
   },
   "presenceStatus":"Busy",
   "telephonyStatus":"CallConnected",
   "userStatus":"Available",
   "dndStatus":"TakeAllCalls",
   "meetingStatus":"Disconnected",
   "allowSeeMyPresence":true,
   "ringOnMonitoredCall":false,
   "pickUpCallsOnHold":false,
   "activeCalls":[
      {
         "id":"8bd930cab325416aa054238237eb8832",
         "direction":"Inbound",
         "fromName":"ROY,DIBYENDU",
         "from":"+14083388064",
         "toName":"Dibyendu Roy",
         "to":"+12053788673",
         "telephonyStatus":"CallConnected",
         "sipData":{
            "toTag":"qf-7.p-XGI9-o3D7bA3j7ihdOqfT0Z9D",
            "fromTag":"10.13.22.25-5070-742e2a888ab14be",
            "remoteUri":"do-not-use-me-I-am-useless",
            "localUri":"do-not-use-me-I-am-useless"
         },
         "sessionId":"183851523016",
         "startTime":"2019-03-26T22:16:29.629+0000",
         "partyId":"cs168629785304410134536-2",
         "telephonySessionId":"XXXXXXXXXX"
      }
   ]
}
GET /restapi/v1.0/account/{accountId}/presence/detailedTelephonyState=true&sipData=true

How to find the Device ID

To retrieve the deviceId required by this API, call the extension/device endpoint on the supervisor's extension as follows:

{
   "uri":"https://platform.ringcentral.com/restapi/v1.0/account/809646016/device/60727004",
   "id":"60727004",
   "type":"SoftPhone",
   "sku":"DV-1",
   "name":"Softphone - Digital Line",
   "serial":"LMRC8531",
   "computerName":"LMRC8531",
   "status":"Online",
   "extension":{
      "uri":"https://platform.ringcentral.com/restapi/v1.0/account/809646016/extension/809646016",
      "id":809646016,
      "extensionNumber":"101"
   }
}
GET /restapi/v1.0/account/~/extension/{supervisorExtensionId}/device

Response

The response from the Supervision API will show the supervisor joining the agent extension with a seperate party id, e.g. party-4 in this example. The RingCentral system will then send a SIP INVITE request to the supervisor device which is expected to join the existing customer-agent call session automatically with auto answer. Now the human or app supervisor can stream the audio.

{
    "direction": "Outbound",
    "from": {
        "deviceId": "60727004",
        "extensionId": "809646016",
        "name": "Supervisor ABC",
        "phoneNumber": "101"
    },
    "id": "party-4",
    "muted": false,
    "owner": {
        "accountId": "809646016",
        "extensionId": "809646016"
    },
    "standAlone": false,
    "status": {
        "code": "Answered",
        "reason": "Supervising"
    },
    "to": {
        "extensionId": "62226587016",
        "name": "Dibyendu Roy",
        "phoneNumber": "108"
    }
}

How to verify the Supervisor has joined the session

To verify that the supervisor has joined the call use the account-level Presence API to see that an additional party has been added to the existing session. Then verify that the supervisor's party is in the activeCalls property. For example:

{
   "activeCalls":[
      {
         "id":"aa97ce30b90441158a421ca0e9c0a233",
         "direction":"Outbound",
         "fromName":"Supervisor ABC",
         "from":"101",
         "toName":"Agent",
         "to":"108",
         "telephonyStatus":"CallConnected",
         "sipData":{
            "toTag":"I2rPJdYwDjuEeOFJpT2pDszuCrepqQsL",
            "fromTag":"10.14.23.50-5070-a272ac7ba84b4a7",
            "remoteUri":"do-not-use-me-I-am-useless",
            "localUri":"do-not-use-me-I-am-useless"
         },
         "sessionId":"590506730017",
         "startTime":"2019-03-27T19:14:22.564+0000",
         "partyId":"party-4",
         "telephonySessionId":"XXXXXXXXXX"
      }
   ]
   ...
}
GET /restapi/v1.0/account/{accountId}/presence?detailedTelephonyState=true&sipData=true

FCC Compliance

If you intend to save the audio stream, please make sure you comply with the FCC guidelines by letting the customer know that the calls will be monitored. The following video demonstrates a working example of the Supervision API using the concepts described here.