AVR Core provides a flexible webhook system that allows external services to receive real-time notifications about call lifecycle events.
Webhooks can be used for:
This guide explains all supported webhook events, their payloads, and best practices for implementing webhook receivers.
Webhooks are HTTP POST requests sent by AVR Core to a configured endpoint (WEBHOOK_URL) whenever a specific event occurs during a call session.
Each webhook:
uuidSome webhooks are informational, while others (notably call_initiated) can be used to influence call routing behavior.
A typical AVR call lifecycle with webhooks enabled follows this sequence:
call_initiated
Triggered when call metadata is received via HTTP (POST /call)
call_started
Triggered when the AudioSocket connection is established
Runtime events
transcription, interruption, dtmf_digit
call_ended
Triggered when the call session terminates
The call_initiated event is tightly coupled with the HTTP Web Service and is emitted before any audio processing starts.
See also:
👉 AVR Core HTTP Web Service
https://wiki.agentvoiceresponse.com/en/avr-core-http-web-service
The following diagram illustrates how HTTP, AudioSocket, STS, and Webhooks interact during a call lifecycle.
call_initiated
STS_URLcall_started
Runtime events
call_ended
call_initiatedPOST /call received by AVR Corests_url to dynamically override STS routingThis is the only webhook event that supports routing decisions via HTTP response.
{
"uuid": "935652e3-7c59-4edc-b17f-9646a9c2a265",
"type": "call_initiated",
"timestamp": "2026-01-01T12:00:00.000Z",
"payload": {
"from": "2000",
"to": "5001",
"uniqueid": "1770758888.32",
"channel": "PJSIP/2000-00000013"
}
}
call_startedTrigger: AudioSocket connection established
Payload: Empty
Use cases:
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"type": "call_started",
"timestamp": "2024-01-01T12:00:00.000Z",
"payload": {}
}
call_endedTrigger: Call termination
Payload: Empty
Use cases:
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"type": "call_ended",
"timestamp": "2024-01-01T12:05:30.000Z",
"payload": {}
}
interruptionTrigger: User interrupts AI speech
Payload: Empty
Use cases:
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"type": "interruption",
"timestamp": "2024-01-01T12:02:15.000Z",
"payload": {}
}
transcriptionTrigger: Speech transcription event
Payload: Role and text
Use cases:
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"type": "transcription",
"timestamp": "2024-01-01T12:01:45.000Z",
"payload": {
"role": "user | agent",
"text": "Hello, I need help with my account"
}
}
dtmf_digit (Asterisk 22+)Trigger: DTMF key pressed
Payload: Digit value
Use cases:
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"type": "dtmf_digit",
"timestamp": "2024-01-01T12:02:15.000Z",
"payload": {
"digit": "1"
}
}
All webhook events share the same envelope structure:
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"type": "event_type",
"timestamp": "ISO-8601",
"payload": {}
}
WEBHOOK_URL – Webhook receiver endpointWEBHOOK_SECRET – Shared secret for verificationWEBHOOK_TIMEOUT – Request timeout (default: 3000 ms)WEBHOOK_RETRY – Retry attempts (default: 0)WEBHOOK_URL=http://avr-webhook:9000/events
WEBHOOK_SECRET=your-secret-key
WEBHOOK_TIMEOUT=5000
WEBHOOK_RETRY=3
If WEBHOOK_SECRET is configured, AVR Core sends it in the request header:
X-AVR-WEBHOOK-SECRET: your-secret-key
Webhook endpoints should:
The following example shows a minimal Express.js webhook receiver supporting all AVR webhook events.
const express = require("express");
const app = express();
app.use(express.json());
app.post("/events", (req, res) => {
const { uuid, type, payload } = req.body;
switch (type) {
case "call_initiated":
console.log("Call initiated:", payload);
return res.status(200).json({
sts_url: `ws://localhost:6030?uuid=${uuid}`,
});
case "call_started":
console.log("Call started:", uuid);
break;
case "transcription":
console.log(`[${payload.role}] ${payload.text}`);
break;
case "interruption":
console.log("User interrupted the agent");
break;
case "dtmf_digit":
console.log("DTMF digit:", payload.digit);
break;
case "call_ended":
console.log("Call ended:", uuid);
break;
default:
console.log("Unhandled event:", type);
}
res.sendStatus(200);
});
app.listen(9000, () => {
console.log("AVR webhook listener running on port 9000");
});
To help you get started quickly, we provide ready-to-use examples that show how to connect AVR with external systems using webhooks.
These examples demonstrate how to capture events, parse data, and trigger actions in your own applications.
| Event | Phase | Can Affect Routing |
|---|---|---|
call_initiated |
Pre-call | ✅ Yes |
call_started |
Runtime | ❌ No |
transcription |
Runtime | ❌ No |
interruption |
Runtime | ❌ No |
dtmf_digit |
Runtime | ❌ No |
call_ended |
Post-call | ❌ No |
AVR Core implements automatic retry logic for failed webhook requests:
WEBHOOK_TIMEOUT, request is considered failedWEBHOOK_RETRY additional attempts are madeFailed webhook requests are logged with detailed error information:
[WEBHOOK][CALL_STARTED] Retry failed
Webhook Error:
Message: connect ECONNREFUSED avr-webhook:9000
Code: ECONNREFUSED
URL: http://avr-webhook:9000/events
Method: POST
Status:
WEBHOOK_URL is correct and accessibleWEBHOOK_TIMEOUT valueWEBHOOK_SECRET configurationX-AVR-WEBHOOK-SECRET headerWebhooks in AVR allow you to extend the platform beyond call handling, by sending events and call data to your own systems or third-party services.
This makes it possible to enrich analytics, update business tools in real time, and ensure continuous quality improvements.
Here are some common scenarios:
Track key metrics like call duration, frequency, and interaction patterns.
Useful for understanding customer behavior, optimizing agent performance, and measuring AI voicebot efficiency.

Automatically update customer profiles with call transcripts, notes, or outcomes.
This ensures your sales and support teams always have the latest information at hand.

Monitor AI performance, user satisfaction, and conversation quality.
Webhook data can be connected to dashboards or QA tools to spot issues early and continuously improve your conversational flows.
