Webhooks deliver real-time event notifications to your server whenever something happens in your Zentrix Agent Studio account -- a call starts, a payment succeeds, or a subscription changes status. Instead of polling the API, you register a webhook URL and receive HTTP POST requests with event data as they occur.
Zentrix Agent Studio uses two webhook endpoints internally:
| Endpoint | Events | Source |
|---|---|---|
/api/calls/webhooks | Call lifecycle events | Voice platform (phone and web) |
/api/payments/webhooks | Payment and subscription events | Razorpay |
These events fire during the lifecycle of a voice call (both phone and web widget):
| Event | Trigger | Key Payload Fields |
|---|---|---|
call.started | Call begins (agent picks up) | callId, agentId, callerNumber, platform |
call.ended | Call terminates | callId, duration, transcript, sentiment, summary, disconnectionReason |
call.transferred | Call handed off to another agent or human | callId, fromAgentId, toAgentId, transferReason, conversationContext |
{
"event": "call.ended",
"timestamp": "2026-03-05T14:30:00.000Z",
"data": {
"callId": "call_abc123",
"agentId": "550e8400-e29b-41d4-a716-446655440000",
"instanceId": "660f9500-f30c-52e5-b827-557766551111",
"platform": "phone",
"callerNumber": "+919876543210",
"duration": 245,
"transcript": "Agent: Hello, how can I help you today? ...",
"sentiment": "positive",
"summary": "Customer inquired about product return policy. Provided return window details and initiated return process.",
"disconnectionReason": "agent_ended"
}
}These events fire when subscription or payment status changes:
| Event | Trigger | Key Payload Fields |
|---|---|---|
subscription.activated | New subscription starts (first payment collected) | subscriptionId, planId, customerId |
subscription.charged | Recurring payment succeeds | subscriptionId, paymentId, amount |
subscription.cancelled | Customer or admin cancels | subscriptionId, cancelledAt |
payment.failed | Recurring payment fails | subscriptionId, paymentId, failureReason |
All webhook requests include a signature header for security. Always verify the signature before processing events.
Call webhooks include x-webhook-signature:
import crypto from 'crypto';
function verifyCallWebhook(body, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}Payment webhooks (Razorpay) include x-razorpay-signature:
function verifyPaymentWebhook(body, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return expected === signature;
}Important: Always use the raw request body string for signature verification, not a parsed JSON object. Parsing and re-stringifying can alter field ordering and break the signature.
callId or paymentId as an idempotency key to avoid duplicate processing.timestamp field.A Product by BRTNeura Technology LLP
Last updated: 2026-03-05