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.
- This event will also contain the
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.
- All events related to this new entry point call will contain a
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.
- If the initial scenario was an operator call, then specifically the
Updated about 3 years ago