Receive the AI-generated summary of a completed PSTN or WhatsApp call as soon as it is ready, including a short recap, the key points discussed and the follow-ups mentioned.
A single event covers both calling channels. The channel field tells you whether the call went through your PSTN number or your WhatsApp Business number.
Events Covered
| Event | Description |
|---|---|
CALL_AI_SUMMARY | Fires once the AI summary of a completed PSTN or WhatsApp call has been generated |
Call AI Summary
Event type: CALL_AI_SUMMARY
Fires when the AI summary of a completed call is ready. The summary is generated after the call ends, so this event arrives after CALL_ENDED for the same call.
Trigger Conditions
The event is emitted when:
- A PSTN or WhatsApp call has ended and its AI summary has been generated.
- The summary was generated automatically after the call (call summarisation is enabled for your organization), or a team member generated it from the chat.
- A webhook is subscribed to
CALL_AI_SUMMARYon the channel the call went through, your PSTN number for a PSTN call, or your WhatsApp Business number for a WhatsApp call.
It is not emitted when:
- No summary can be generated for the call — for example the call was missed or rejected, it ended without a recording, or nothing was said.
- The summary for the call was already generated earlier. The event fires only once per call.
- The call is a bot test call and webhooks were not turned on for that test.
- No webhook is subscribed to
CALL_AI_SUMMARYon the call's channel.
Subscriptions are per channel. A webhook subscribed on your PSTN number receives summaries of that number's PSTN calls only, and a webhook subscribed on your WhatsApp Business number receives summaries of that number's WhatsApp calls only. Subscribe on both if you want both.
Payload Structure
| Field | Type | Required | Description |
|---|---|---|---|
event | string | Yes | Always "CALL_AI_SUMMARY" |
channel | string | Yes | The channel the call went through. See values below. |
callId | string | Yes | Unique identifier for the call. Same callId as the call's lifecycle webhooks. |
callDirection | string | Yes | Direction of the call. See values below. |
callStatus | string | Yes | Status of the call when the summary was generated. Normally "END". |
durationInSeconds | number | Yes | Call duration in seconds |
callStartedAt | string | Yes | ISO 8601 timestamp when the call started |
callEndedAt | string | Yes | ISO 8601 timestamp when the call ended |
from | string | Yes | Your PSTN number or WhatsApp Business number. The same for incoming and outgoing calls. |
to | string | Yes | Customer's phone number. The same for incoming and outgoing calls. |
channelNumber | string | Yes | Same value as from, under the name used by the other call webhooks |
customerNumber | string | Yes | Same value as to, under the name used by the other call webhooks |
agentNumber | string | No | Phone number of the team member who handled or started the call. Absent when there is none. |
callType | string | Yes | Who handled the call. See values below. |
triggeredVia | string | Yes | How the call was started. See values below. |
summary | object | Yes | The AI summary of the call. See Summary Object. |
channel Values
| Value | Description |
|---|---|
PSTN | The call went through your PSTN number |
WHATSAPP | The call went through your WhatsApp Business number |
callDirection Values
| Value | Description |
|---|---|
INCOMING | The call was placed by the customer to the business |
OUTGOING | The call was placed by the business to the customer |
callType Values
| Value | Description |
|---|---|
AI_BOT | The call was handled by an AI bot |
AGENT | The call was handled by a team member |
triggeredVia Values
| Value | Description |
|---|---|
INBOUND | The customer called the business |
CAMPAIGN | The call was placed as part of a voice campaign |
API | The call was started through the public API |
UI | The call was started from the DoubleTick app |
Summary Object
| Field | Type | Required | Description |
|---|---|---|---|
recap | string | Yes | Short summary of the call |
keyPoints | array of strings | Yes | Key points discussed in the call |
nextSteps | array of strings | Yes | Follow-ups mentioned in the call |
When a call ends, callStatus is "END" — not "ENDED". Checking for "ENDED" in your code will silently fail.
Sample Payloads
WhatsApp Call Handled by an Agent
{
"event": "CALL_AI_SUMMARY",
"channel": "WHATSAPP",
"callId": "call_01HX9abc123",
"callDirection": "INCOMING",
"callStatus": "END",
"durationInSeconds": 145,
"callStartedAt": "2026-01-15T10:30:00.000Z",
"callEndedAt": "2026-01-15T10:32:25.000Z",
"from": "+919000000000",
"to": "+919876543210",
"channelNumber": "+919000000000",
"customerNumber": "+919876543210",
"agentNumber": "+919111111111",
"callType": "AGENT",
"triggeredVia": "INBOUND",
"summary": {
"recap": "The customer asked about the delivery date of their order and the agent confirmed it ships tomorrow.",
"keyPoints": [
"The order is packed and ready for dispatch",
"Delivery is expected within two days"
],
"nextSteps": [
"Share the tracking link once the order ships"
]
}
}
PSTN Call Handled by an AI Bot
{
"event": "CALL_AI_SUMMARY",
"channel": "PSTN",
"callId": "call_01HX9def456",
"callDirection": "OUTGOING",
"callStatus": "END",
"durationInSeconds": 87,
"callStartedAt": "2026-01-15T11:00:00.000Z",
"callEndedAt": "2026-01-15T11:01:27.000Z",
"from": "+918000000000",
"to": "+919876543210",
"channelNumber": "+918000000000",
"customerNumber": "+919876543210",
"callType": "AI_BOT",
"triggeredVia": "CAMPAIGN",
"summary": {
"recap": "The AI bot reminded the customer about their appointment on Friday and the customer confirmed they will attend.",
"keyPoints": [
"The appointment is on Friday at 11 AM",
"The customer confirmed attendance"
],
"nextSteps": [
"Send a reminder message on Thursday"
]
}
}
PSTN Call Started by an Agent from the App
{
"event": "CALL_AI_SUMMARY",
"channel": "PSTN",
"callId": "call_01HX9ghi789",
"callDirection": "OUTGOING",
"callStatus": "END",
"durationInSeconds": 212,
"callStartedAt": "2026-01-15T12:10:00.000Z",
"callEndedAt": "2026-01-15T12:13:32.000Z",
"from": "+918000000000",
"to": "+919876543210",
"channelNumber": "+918000000000",
"customerNumber": "+919876543210",
"agentNumber": "+919111111111",
"callType": "AGENT",
"triggeredVia": "UI",
"summary": {
"recap": "The agent followed up on the customer's home loan application and requested the pending income documents.",
"keyPoints": [
"The application is pending income proof",
"The customer will upload the documents this week"
],
"nextSteps": [
"Check the uploaded documents and update the application status"
]
}
}
Fetching a Summary on Demand
The same summary can also be fetched at any time with the public API, using the callId from this event:
GET https://public.doubletick.io/v1/call/ai-summary?callId=<callId>
Notes
- The event fires only once per call, after the summary has been saved. Generating the summary again for the same call does not send a second event.
agentNumberis absent, not an empty string and when no team member handled or started the call, for example an AI bot call started through the public API or a campaign.fromandchannelNumberalways hold your number, andtoandcustomerNumberalways hold the customer's number, whatever the call direction.- Delivery is fire-and-forget: a failure to deliver this webhook never affects the summary being saved. Failed deliveries are retried in the same way as the other call webhooks.
Best Practices
- Use
callIdto correlate this event with the call's lifecycle webhooks (CALL_INCOMING_INITIATED/CALL_OUTGOING_INITIATED→CALL_ACCEPTED→CALL_ENDED→CALL_AI_SUMMARY), which all share the samecallId. - Check
channelbefore processing if your webhook is subscribed on both PSTN and WhatsApp numbers. - Treat
agentNumberas optional and always check that it is present before using it. agentNumbercontains the team member's phone number, not a stable identifier. Phone numbers can change when a team member updates their profile. Do not use it for programmatic matching or routing logic and it is intended for display and audit purposes only.

