Call Recording

About Call Recording

Setting up call recording allows you to have a permanent record of a conversation that took place.

Configuring Call Recording

Call recording can be enabled in a number of ways:

  • At the account level
  • At the user level
  • At the device level
  • Explicitly as a callflow action

Call recording requires you to either:

  • have a web server capable of receiving an HTTP PUT request with the contents of the recording, which you are then free to save in a way that meets your needs
  • configure a storage plan for call recordings

Account, User, or Device

Configuring recording at the account level means all calls, inbound and outbound, to this account will start the call recording system.

Configuring recording at the user level starts recording for any calls to/from a device owned by that user.

Configuring recording at the device level starts recording for any calls to/from the device.

Precedence of settings

Precedence of settings is: Device > User

If a user turns on call recording but a device has explicitly disabled it, the device will not be recorded when the user makes a call with it. If the device’s settings are left undefined, the user’s settings will be applied.

The account’s settings are considered independently of the endpoint’s. So a user who has disabled recording, within an account that has enabled recording, will still have calls recorded according to the account’s settings.

Recording settings matrix

Account Settings

When an onnet device makes an internal call:

SettingSourceDestinationRecording Started
Account -> Inbound -> Onnetonnetonnetyes
Account -> Inbound -> Offnetonnetonnetno
Account -> Outbound -> Onnetonnetonnetyes (if inbound -> onnet isn’t configured)
Account -> Outbound -> Offnetonnetonnetno

When an onnet device makes an external call:

SettingSourceDestinationRecording Started
Account -> Inbound -> Onnetonnetoffnetyes
Account -> Inbound -> Offnetonnetoffnetno
Account -> Outbound -> Onnetonnetoffnetno
Account -> Outbound -> Offnetonnetoffnetyes (if inbound -> onnet isn’t configured)

When an offnet device makes an internal call:

SettingSourceDestinationRecording Started
Account -> Inbound -> Onnetoffnetonnetno
Account -> Inbound -> Offnetoffnetonnetyes
Account -> Outbound -> Onnetoffnetonnetyes (if inbound-offnet isn’t configured)
Account -> Outbound -> Offnetoffnetonnetno
Endpoint Settings

When an onnet device makes an internal call:

SettingSourceDestinationRecording Started
Endpoint -> Inbound -> Onnetonnetonnetyes¹
Endpoint -> Inbound -> Offnetonnetonnetno
Endpoint -> Outbound -> Onnetonnetonnetyes
Endpoint -> Outbound -> Offnetonnetonnetno

¹ When the setting is enabled on the destination endpoint

When an onnet device makes an external call:

SettingSourceDestinationRecording Started
Endpoint -> Inbound -> Onnetonnetoffnetno
Endpoint -> Inbound -> Offnetonnetoffnetno
Endpoint -> Outbound -> Onnetonnetoffnetno
Endpoint -> Outbound -> Offnetonnetoffnetyes

When an offnet endpoint makes a call to an onnet device:

SettingSourceDestinationRecording Started
Endpoint -> Inbound -> Onnetoffnetonnetno
Endpoint -> Inbound -> Offnetoffnetonnetyes
Endpoint -> Outbound -> Onnetoffnetonnetno
Endpoint -> Outbound -> Offnetoffnetonnetno

Enabling recording

To enable call recording, add "call_recording":{...} to the document of choice. For example, if you have a user with user ID of {USER_ID}, you can patch the user’s document using Crossbar:

curl -v -X PATCH \
    -H "X-Auth-Token: {AUTH_TOKEN}" \
    -H "Content-Type: application/json" \
    -d '{"data":{
    "call_recording":{...}
    }}' \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/users/{USER_ID}

Concrete example

Sales wants calls to and from customers to be recorded but not calls within the account. The sales users would have their call_recording settings set as:

{
  "call_recording": {
    "inbound": {
      "offnet": {
        "enabled": true
      }
    },
    "outbound": {
      "offnet": {
        "enabled": true
      }
    }
  }
}

The call recording settings

KeyDescriptionTypeDefaultRequiredSupport Level
enabledis recording enabledboolean()false
formatWhat format to store the recording on disk`string(‘mp3''wav’)`false
record_min_secThe minimum length, in seconds, the recording must be to be considered successful. Otherwise it is deletedinteger()false
record_on_answerRecording should start on answerboolean()false
record_on_bridgeRecording should start on bridgeboolean()false
record_sample_rateWhat sampling rate to use on the recordinginteger()false
time_limitTime limit, in seconds, for the recordinginteger()false
urlThe URL to use when sending the recording for storagestring()false

Callflow action - Record Call

You can enable call recording on a per-callflow basis by using the record_call callflow action. The callflow action can take the following parameters:

KeyDescriptionTypeDefaultRequiredSupport
actionWhether to start or stop the recordingstring('start', 'stop')starttrue
formatWhat format to store the recording on diskstring('mp3', 'wav')false
labelLabel to include in the origin of call recordingstring()false
media_namethe name of mediastringfalse
record_min_secThe minimum length, in seconds, the recording must be to be considered successful. Otherwise it is deletedintegerfalse
record_on_answerWhether to delay the recording until the channel is answeredbooleanfalsefalse
record_on_bridgeWhether to delay the recording until the channel is bridgedbooleanfalsefalse
record_sample_rateWhat sampling rate to use on the recordingintegerfalse
time_limitTime limit, in seconds, for the recordinginteger3600false
urlThe URL to use when sending the recording for storagestringfalse

Callflow action - Record Caller

The record_caller callflow action is meant for recording things like voicemails or IVR prompts. The schema for the callflow action is:

KeyDescriptionTypeDefaultRequiredSupport Level
formatWhat format to store the recording on disk`string(‘mp3''wav’)`false
methodWhat HTTP method to use when sending the recording`string(‘put''post’)`putfalse
time_limitTime limit, in seconds, for the recordinginteger()3600false
urlThe URL to use when sending the recording for storagestring()false

Interpreting call recordings and call direction

Call direction is a field found in CDRs that indicates, from KAZOO’s perspective, from whence the call was started. inbound indicates that the phone/carrier has sent the INVITE to Kazoo (inbound to KAZOO). outbound indicates that KAZOO is sending the INVITE to the phone/carrier (outbound from KAZOO).

inbound: PHONE ==INVITE==> KAZOO
outbound: PHONE <==INVITE== KAZOO

Now a lot of calls will involve two phones:

PHONE_A ==INVITE==> KAZOO ==INVITE==> PHONE_B

The INVITE from PHONE_A is the inbound call leg while the INVITE from KAZOO to PHONE_B is the outbound leg.

However, these directions are often not intuitive to end users. Most folks would say a call coming in from the PSTN is an inbound call while the call they place to the PSTN is an outbound call. UI clients, therefore, can’t rely on just displaying the call_direction field of a call to indicate the direction of the call from the end user’s perspective.

When call recording is configured, the leg being recorded will include the recording information in its CDR. Additionally, if a leg is coming in from or going out to the PSTN, it will include a resource_type field in the CDR’s custom_channel_vars. Fetching all legs involved (using the interaction_id), it should be possible to determine the direction of a call from the end user’s perspective for the simple case:

End User’s DirectionCall Direction (A leg)Resource Type (A leg)Call Direction (B leg)Resource Type (B leg)Description
inboundinbound from PSTNoffnet-originationoutbound to the deviceundefinedA call in from the PSTN to a registered device
outboundinbound from a deviceundefinedoutbound to the PSTNoffnet-terminationA call from a registered device to the PSTN

Those are the simple cases, of course. Where it gets tricky is when a call comes in from the PSTN and is subsequently sent to a call-forwarded device (via PSTN). Both legs will have resource_type set. Or when a device calls another device, no resource_type will exist on either leg. Or when a call is transferred or parked/picked up (sometimes multiple times).

The leg where call recording is started will have media_recording_id set (among others) in the leg’s CDR under the custom_channel_vars object.

Hopefully this section can serve as a jumping off point for UI clients to determine how to communicate to end users the direction of calls so that labeling recordings can be done in a way that makes sense for the end user.