Call Events

Call events provide details on the state of the call for different moments during the lifecycle of the call. These events can be subscribed to for an entire company, office, or a more granular target (such as a call center or user).

Events are sent to a webhook that you (as a company admin or developer) provide. To get started, create a webhook subscription using our API.

Payload

Event payload will be generated by each state transition that occurs during a call, and there can be many calls that are created to service the end-to-end call flow. The Call Flow Structure section of this article can be immensely helpful to understand the event sequence that can be expected in different scenarios.

High Level Payload Structure

Each payload can also contain a large number of fields. At a high level, the information provided within each payload falls into just a handful of categories:

  • Related call IDs
    These are useful for more complex scenarios where the structure of the call graph must be taken into account. For example "Was this call transferred?" "How many transfers did the customer experience?" "Who was the last person who spoke to the customer on this call?" "Who was the first?" etc...

  • Call participant information
    These are useful for application scenarios that need to understand who was on the call, what their names are, what number they were calling from, etc.

  • Customer satisfaction information
    These fields surface information gathered from the post-call CSAT survey (assuming a post-call survey has been configured)

  • Timing information
    These fields are useful for time-tracking applications. For example "How long was the customer waiting on hold?", "How much time are agents spending on each call?" etc...

  • Recordings, transcripts, and screen-captures that relate to the call
    These metadata facets are mostly in the form of URLs, and are often useful to include in the context of call logging to a CRM or ticketing system

Important Terminology

Some of the payload terminology is a bit... counter-intuitive, so it's worth reading this before reading further:

  • call
    A "call" is better thought of as a "call leg". It is just a component of a call flow, and there may be many calls related to a single interaction with a customer.

  • contact
    The "contact" is the external party. If a customer calls one of your users, or if one of your users calls a customer, the customer is the "contact" in both cases.

  • target
    The "target" is the internal party. In the previous example, the user would be the "target" of the call. Targets can also be other types of Dialpad entities such as call routers, call centers, departments, offices, etc

  • call_id
    This is the ID of the call for which the payload was generated. (i.e. The ID of this call). All other call ID fields refer to a different (but related) call.

Payload Fields

Payloads sent to your webhook will be either JWT encoded or JSON encoded (depending on your webhook configuration) and will contain the following fields.

Field

Data Type

Description

Notes

call_id

int

A unique number ID automatically assigned to each call

contact

object

This is the contact involved in the call. It will contain the following pieces of info:

  • Phone: E.164 phone number
  • Type: User/Local/Nylas/Google/Microsoft
  • ID: Unique contact ID
  • Email: Associated email
  • Name: Contact name

The contact corresponds to the external_number, regardless of whether the call is inbound or outbound.

csat_recording_urls

list

A list of CSAT urls related to the call

May appear blank if call is not in the 'csat' state.

csat_score

int**

The CSAT score of the call

May appear blank if call is not in the 'csat' state.

See the CSAT survey help article for additional details.

csat_transcriptions

list**

A list of CSAT texts related to the call

May appear blank if call is not in the 'csat' state.

custom_data

string**

Additional optional metadata provided (by you) via the initiate outbound call API

The value will only be present if the call was initiated via the API, and non-empty metadata was provided in the body of the request.

date_connected

int (unix ms UTC)

Timestamp when Dialpad connected the call

May appear blank if:

  • Dialpad did not detect a date_rang value.
  • Agent did not answer (Call Queues).

date_ended

int (unix ms UTC)

Timestamp when the call was hung up.

date_rang

int (unix ms UTC)

Timestamp when Dialpad first detects an inbound call to a mainline, department, or person.

May appear blank if:

  • The caller hung up before we could detect ringing.
  • The user has IVR settings that put callers directly to VM.
  • The call is an outbound call.

date_started

int (unix ms UTC)

Timestamp when the call began in the Dialpad system before being connected

direction

string(enum)
inbound, outbound

Call direction. Indicates whether a call was made (outbound) or received (inbound).

duration

int

Duration of the call in milliseconds

May be blank if:

  • The call is not yet completed. (Before the ‘hangup’ state)
  • The call was never connected.

entry_point_call_id

int

A reference ID to the "entry point" call related to this call.

This value will be present on operator calls (departments, call queues). It can be used to associate an operator call with its entry point call.

Additional details can be found in the "Call Flow Structure" section at the bottom of this document.

entry_point_target

object

Where a call initially dialed for inbound calls to Dialpad. It will contain the following pieces of info:

  • Phone: E.164 phone number
  • Type: User/Office/Department/Staff/Room/Call Center
  • Id:Unique entry point ID
  • Email: Associated email

Inbound calls only.

This is populated when an inbound call is fanned out to a Dept/Call Queue.

external_number

string (E164 phone)

The phone number of the contact.

For inbound calls, this is the caller’s number. For outbound calls, this is the destination number.

group_id

string ({type}:{scoped_id})

Unique ID of the department, mainline, or call queue associated with the call.

This matches the entry_point_target for a group call.

May appear blank if the call is not a group call.

internal_number

string (E164 phone)

The phone number internal to your organization

For inbound calls, this is the destination number. For outbound calls, this is the caller’s number.

is_transferred

bool

A boolean value indicating whether this call has been transferred.

This value will be present on hangup events, and if True, it indicates that the call flow will continue with a subsequent call that receives the transfer.

master_call_id

int

A reference ID to the "master" call related to this call.

This value will be present on calls resulting from a call transfer. Every subsequent transfer will refer to the same "master" call ID.

Additional details can be found in the "Call Flow Structure" section at the bottom of this document.

operator_call_id

int

A reference ID to the "operator" call related to this call.

This value will be present if a call to a group entity (such as a call center or department) was answered by an operator.

proxy_target

object

Caller ID used by the Dialpad user for outbound calls. It will contain the following pieces of info:

  • Phone: E.164 phone number
  • Type: Office/Department/Staff/Room/Call Center
  • Id: Unique proxy ID
  • Email: Associated email

If a value appears, the call was placed with an outbound ID other than the user's direct line.

recording_url

list

A list of call recording urls.

This field is present in the payload only if the API Key or the OAuth App associated with the event subscription contains the "recordings_export" scope.

screen_recording_urls

list

A list of URLs of all the screen recordings that were captured during the call

state

string (enum)
See below

Different call state enums

See below for details

target

object

This is the ‘target’ that the Dialpad user dials or receives a call from. It will contain the following pieces of info:

  • Phone: E.164 phone number
  • Type: User/Office/Department/Staff/Room/Call Center
  • ID: Unique Target ID
  • Email: Associated email
  • Name: Target name

May appear blank if unanswered.

The target corresponds to the internal_number. It’s the Dialpad user or Department or Call Center, regardless of whether the call is inbound or outbound.

transcription_text

string

Voice-to-text transcription result in plaintext

voicemail_link

string

URL to the voicemail recording

May appear blank if there was no voicemail left.

In the 'voicemail' state, a voicemail link will be provided, but may 404 if the voicemail was cancelled.

In the 'voicemail_uploaded' state, the voicemail link will not 404 unless the call history is eventually deleted.

was_recorded

bool

Boolean indicating whether or not the call was recorded

Call States

State

Description

calling

Outbound call has started.

ringing

Inbound call is ringing.

connected

Both parties in an outbound or inbound call have answered the call and can hear each other.

merged

An additional caller is added to the call.

hold

Call is on hold.

queued

An inbound call center call is waiting in the queue for an operator to answer.

voicemail

Voicemail recording has started.

Note: In this state, voicemail_link will be populated in the payload proactively, but may 404 if a voicemail is not left (i.e. the voicemail is cancelled early).

voicemail_uploaded

Voicemail recording has completed.

Note: In this state, voicemail_link will be populated in the payload and will not 404 except in the long term if the call history is deleted.

eavesdrop

A user started listening in on a voicemail that is being recorded.

monitor

A call center admin is listening to an operator call.

barge

A call center admin barged in to an operator call.

hangup

Call ended.

admin

Voicemail administration menu entered.

parked

Call is parked.

takeover

A call center admin has taken over an operator call. (The operator is disconnected)

transcription

Voicemail has been transcribed.

recording

Call recording has finished processing.

all

Include all call states.

disposition

Includes the disposition from the call

csat

Includes the CSAT score from the call

Sample Payloads

{
  "master_call_id": null,
  "date_ended": 1582853674998,
  "internal_number": "+16010123456",
  "duration": 13303.755000000001,
  "entry_point_target": {},
  "proxy_target": {},
  "call_dispositions": null,
  "entry_point_call_id": null,
  "operator_call_id": null,
  "call_id": 5747322335264768,
  "state": "hangup",
  "date_started": 1582853645285,
  "transcription_text": null,
  "direction": "inbound",
  "date_connected": 1582853661695,
  "voicemail_link": null,
  "is_transferred": false,
  "was_recorded": false,
  "date_rang": 1582853645838,
  "target": {
    "phone": "+16010123456",
    "type": "user",
    "id": 5908860123456789,
    "name": "sample",
    "email": "[email protected]"
  },
  "contact": {
        "phone": "+16043111111",
        "type": "google",
        "id": "http://www.google.com/m8/feeds/contacts/[email protected]/base/21042cfc8b367347",
        "name": "Test for a Long Name",
        "email": ""
    },
  "group_id": null,
  "external_number": "+16043111111"
}
{
  "master_call_id": null,
  "date_ended": null,
  "internal_number": "+16010123456",
  "duration": null,
  "entry_point_target": {},
  "proxy_target": {},
  "call_dispositions": null,
  "entry_point_call_id": null,
  "operator_call_id": null,
  "call_id": 5747322335264768,
  "state": "ringing",
  "date_started": 1582853645285,
  "transcription_text": null,
  "direction": "inbound",
  "date_connected": null,
  "voicemail_link": null,
  "is_transferred": false,
  "was_recorded": false,
  "date_rang": 1582853645838,
  "target": {
    "phone": "+16010123456",
    "type": "user",
    "id": 5908860123456789,
    "name": "sample",
    "email": "[email protected]"
  },
  "contact": {
        "phone": "+16043111111",
        "type": "google",
        "id": "http://www.google.com/m8/feeds/contacts/[email protected]/base/21042cfc8b367347",
        "name": "Test for a Long Name",
        "email": ""
    },
  "group_id": null,
  "external_number": "+16043111111"
}
{
  "master_call_id": null,
  "date_ended": 1582853883616,
  "internal_number": "+16010123456",
  "duration": null,
  "entry_point_target": {},
  "proxy_target": {},
  "call_dispositions": null,
  "entry_point_call_id": null,
  "operator_call_id": null,
  "call_id": 6580619776884736,
  "state": "hangup",
  "date_started": 1582853854278,
  "transcription_text": null,
  "direction": "inbound",
  "date_connected": null,
  "voicemail_link": "https://dialpadbeta.com/v/6580619776884736",
  "is_transferred": false,
  "was_recorded": false,
  "date_rang": 1582853854874,
  "target": {
    "phone": "+16010123456",
    "type": "user",
    "id": 5908860123456789,
    "name": "sample",
    "email": "[email protected]"
  },
  "contact": {
        "phone": "+16043111111",
        "type": "google",
        "id": "http://www.google.com/m8/feeds/contacts/[email protected]/base/21042cfc8b367347",
        "name": "Test for a Long Name",
        "email": ""
    },
  "group_id": null,
  "external_number": "+16043111111"
}
{
  "master_call_id": null,
  "date_ended": null,
  "internal_number": "+16010123456",
  "duration": null,
  "entry_point_target": {},
  "proxy_target": {},
  "call_dispositions": null,
  "entry_point_call_id": null,
  "operator_call_id": null,
  "call_id": 5747322335264768,
  "state": "connected",
  "date_started": 1582853645285,
  "transcription_text": null,
  "direction": "inbound",
  "date_connected": 1582853661695,
  "voicemail_link": null,
  "is_transferred": false,
  "was_recorded": false,
  "date_rang": 1582853645838,
  "target": {
    "phone": "+16010123456",
    "type": "user",
    "id": 5908860123456789,
    "name": "sample",
    "email": "[email protected]"
  },
  "contact": {
    "phone": "+16043111111",
    "type": "google",
    "id": "http://www.google.com/m8/feeds/contacts/[email protected]/base/21042cfc8b367347",
    "name": "Test for a Long Name",
    "email": ""
  },
  "group_id": null,
  "external_number": "+16043111111"
}
{
  "master_call_id": null,
  "date_ended": null,
  "internal_number": "+16010123456",
  "duration": null,
  "entry_point_target": {},
  "proxy_target": {},
  "call_dispositions": null,
  "entry_point_call_id": null,
  "operator_call_id": null,
  "call_id": 6580619776884736,
  "state": "voicemail",
  "date_started": 1582853854278,
  "transcription_text": null,
  "direction": "inbound",
  "date_connected": null,
  "voicemail_link": null,
  "is_transferred": false,
  "was_recorded": false,
  "date_rang": 1582853854874,
  "target": {
    "phone": "+16010123456",
    "type": "user",
    "id": 5908860123456789,
    "name": "sample",
    "email": "[email protected]"
  },
  "contact": {
    "phone": "+16043111111",
    "type": "google",
    "id": "http://www.google.com/m8/feeds/contacts/[email protected]/base/21042cfc8b367347",
    "name": "Test for a Long Name",
    "email": ""
  },
  "group_id": null,
  "external_number": "+16043111111"
}
{
  "master_call_id": null,
  "date_ended": null,
  "internal_number": "+16010123456",
  "duration": null,
  "entry_point_target": {},
  "proxy_target": {},
  "call_dispositions": null,
  "entry_point_call_id": null,
  "operator_call_id": null,
  "call_id": 4978137078431744,
  "state": "calling",
  "date_started": 1582853788099,
  "transcription_text": null,
  "direction": "outbound",
  "date_connected": null,
  "voicemail_link": null,
  "is_transferred": false,
  "was_recorded": false,
  "date_rang": null,
  "target": {
    "phone": "+16010123456",
    "type": "user",
    "id": 5908860123456789,
    "name": "sample",
    "email": "[email protected]"
  },
  "contact": {
        "phone": "+16043111111",
        "type": "google",
        "id": "http://www.google.com/m8/feeds/contacts/[email protected]/base/21042cfc8b367347",
        "name": "Test for a Long Name",
        "email": ""
    },
  "group_id": null,
  "external_number": "+16043111111"
}
{
  "master_call_id": null,
  "date_ended": null,
  "internal_number": "+16010123456",
  "duration": null,
  "entry_point_target": {},
  "proxy_target": {},
  "call_dispositions": null,
  "entry_point_call_id": null,
  "operator_call_id": null,
  "call_id": 4978137078431744,
  "state": "connected",
  "date_started": 1582853788099,
  "transcription_text": null,
  "direction": "outbound",
  "date_connected": 1582853801664,
  "voicemail_link": null,
  "is_transferred": false,
  "was_recorded": false,
  "date_rang": null,
  "target": {
    "phone": "+16010123456",
    "type": "user",
    "id": 5908860123456789,
    "name": "sample",
    "email": "[email protected]"
  },
  "contact": {
        "phone": "+16043111111",
        "type": "google",
        "id": "http://www.google.com/m8/feeds/contacts/[email protected]/base/21042cfc8b367347",
        "name": "Test for a Long Name",
        "email": ""
    },
  "group_id": null,
  "external_number": "+16043111111"
}
{
  "master_call_id": null,
  "date_ended": 1582853818129,
  "internal_number": "+16010123456",
  "duration": 16464.904000000002,
  "entry_point_target": {},
  "proxy_target": {},
  "call_dispositions": null,
  "entry_point_call_id": null,
  "operator_call_id": null,
  "call_id": 4978137078431744,
  "state": "hangup",
  "date_started": 1582853788099,
  "transcription_text": null,
  "direction": "outbound",
  "date_connected": 1582853801664,
  "voicemail_link": null,
  "is_transferred": false,
  "was_recorded": false,
  "date_rang": null,
  "target": {
    "phone": "+16010123456",
    "type": "user",
    "id": 5908860123456789,
    "name": "sample",
    "email": "[email protected]"
  },
  "contact": {
        "phone": "+16043111111",
        "type": "google",
        "id": "http://www.google.com/m8/feeds/contacts/[email protected]/base/21042cfc8b367347",
        "name": "Test for a Long Name",
        "email": ""
    },
  "group_id": null,
  "external_number": "+16043111111"
}
{
  "master_call_id": null,
  "date_ended": 1582853883616,
  "internal_number": "+16010123456",
  "duration": null,
  "entry_point_target": {},
  "proxy_target": {},
  "call_dispositions": null,
  "entry_point_call_id": null,
  "operator_call_id": null,
  "call_id": 6580619776884736,
  "state": "transcription",
  "date_started": 1582853854278,
  "transcription_text": "",
  "direction": "inbound",
  "date_connected": null,
  "voicemail_link": "https://dialpadbeta.com/v/6580619776884736",
  "is_transferred": false,
  "was_recorded": false,
  "date_rang": 1582853854874,
  "target": {
    "phone": "+16010123456",
    "type": "user",
    "id": 5908860123456789,
    "name": "sample",
    "email": "[email protected]"
  },
  "contact": {
        "phone": "+16043111111",
        "type": "google",
        "id": "http://www.google.com/m8/feeds/contacts/[email protected]/base/21042cfc8b367347",
        "name": "Test for a Long Name",
        "email": ""
    },
  "group_id": null,
  "external_number": "+16043111111"
}
{
  "master_call_id": null,
  "date_ended": 1620694975723,
  "internal_number": "+16010123456",
  "duration": 23263.819000000003,
  "entry_point_target": {},
  "proxy_target": {},
  "call_dispositions": null,
  "entry_point_call_id": null,
  "operator_call_id": null,
  "call_id": 4978137078431744,
  "state": "recording",
  "date_started": 1620694942713,
  "transcription_text": null,
  "direction": "outbound",
  "date_connected": 1620694952459,
  "voicemail_link": null,
  "is_transferred": false,
  "was_recorded": true,
  "recording_url": [
    "https://dialpad.com/r/6086754856781234",
    "https://dialpad.com/r/6086754856787890"
  ],
  "date_rang": null,
  "target": {
    "phone": "+16010123456",
    "type": "user",
    "id": 5908860123456789,
    "name": "sample",
    "email": "[email protected]"
  },
  "contact": {
    "phone": "+16043111111",
    "type": "google",
    "id": "http://www.google.com/m8/feeds/contacts/[email protected]/base/21042cfc8b367347",
     "name": "Test for a Long Name",
     "email": ""
  },
  "group_id": null,
  "external_number": "+16043111111"
}

Call Flow Structure

To gain a good foundation for understanding the events your subscription is receiving, it's extremely helpful to understand the structures representing the underlying call flows.

Let's start with the simplest case:

Direct Calls

When a customer dials a Dialpad number belonging to a single Dialpad user, this creates a single call between the contact (The external party) and the Dialpad user.

Assuming the conversation ends, and the call is hung up, this will generate 4 call events, all related to that single call:

  • preanswer
  • ringing
  • connected
  • hangup

Nothing too surprising so far, so let's look at a slightly more complex case.

Operator Calls

In many cases, rather than calling a user directly, customer will dial a number associated with a group of users within the company (such as a department or call center). In this situation, two calls are created:

  • The "entry point call"
    • representing the audio channel between the contact and the call center
  • The "operator call"
    • representing the audio channel between the call center and the operator who is servicing the call

Each call has an ID that references its counterpart. Hence, the entry point call will have an operator_call_id, and the operator call will have an entry_point_call_id. Although this case isn't enormously complex, it's a good point to introduce the concept of the "call graph". If we imagine each call as a node in a graph, and each reference ID to be a directed edge between nodes, then this scenario can be represented as a two-node graph with two edges.

This "call graph" compact way to visualize the relationship between the calls to understand how to process and interpret the call events being sent to your webhook.

In this scenario, your webook would receive a series of events from two different calls, but the operator_call_id and entry_point_call_id provide enough context to interpret this situation as being two calls within a single flow.

In particular (assuming the call ends at this point), this flow would generate 8 events:

  • entry_point_call: preanswer
  • entry_point_call: ringing
    • The contact hears that their call is ringing as the call center attempts to find an operator to take the call
  • operator_call: preanswer
  • operator_call: ringing
    • An operator receives a ringing inbound call
  • operator_call: connected
    • The operator has answered the call
  • entry_point_call: connected
    • The contact has been connected to the answered call
  • operator_call: hangup
  • entry_point_call: hangup
    • The call has concluded
    • (These two events happen almost simultaneously when one party ends the call)

Now, let's extend this example to illustrate another way that the call graph can become more complex. Rather than hanging up the call, let's imagine that the operator realizes that the contact has called the wrong number, and that they should be speaking with someone in a different call center within the company.

In this case, the operator would transfer the call to the correct call center.

Transferred Calls

When a call transfer occurs, the original call (or calls) are hung up, and a new call (or calls) are created continue servicing the call flow. In this example, since the transfer-recipient of the call is a call center, the call that will accept the transfer is another entry point call, and a new operator call will be created to service the call.

The relationship between those two new calls is identical to the "Operator Call" scenario that we examined in the previous section, but there is a novel element in this new call graph. The master_call_id is a new type of reference that associates the call that received a transfer with the call that was originally connected with the contact.

Assuming the call flow concludes after the contact speaks with the new operator, this situation would generate 16 call events:

  • entry_point_call: preanswer
  • entry_point_call: ringing
  • operator_call: preanswer
  • operator_call: ringing
  • operator_call: connected
  • entry_point_call: connected
  • operator_call: hangup
  • entry_point_call: hangup
    • This event will also contain the is_transfer flag to communicate the fact that the call flow has not concluded yet.
  • new_entry_point_call: preanswer
    • All events related to this new entry point call will contain a master_call_id that refers to the original entry point call.
  • new_entry_point_call: ringing
  • new_operator_call: preanswer
  • new_operator_call: ringing
  • new_operator_call: connected
  • new_entry_point_call: connected
  • new_operator_call: hangup
  • new_entry_point_call: hangup

Now, let's extend this example even further.

Let's imagine that the manager of the second call center sees that a call was transferred in, rather than a direct call, and they want to listen in to see whether they need to intervene to sooth a potentially-frustrated caller.

Monitored/Joined Calls

There is now an additional call in the call graph representing the call center manager monitoring the conversation. We'll refer to this call as a "monitor call".

This graph is almost identical, with the exception of the monitor call, which has a reference to the entry point call being monitored.

It's worth noting that although there are now two active calls associated with the entry point call, only one of them is referenced by the entry point call. This is a key piece of information that distinguishes between the "true" operator call and the monitor call, which may be conflated by the webhook unless this distinction is explicitly taken into account.

Additional Noteworthy Details

  • In call graphs containing multiple transfers, the master_call_id always refers back to the very first call
    • If the initial scenario was an operator call, then specifically the master_call_id will refer to the entry point call.