Webhooks
Voxxi can send event notifications to your endpoint when call processing completes or fails.
Overview
Configure webhook endpoints in Voxxi Integrations. Each endpoint subscribes to one or more events.
Event types
- Name
call.analysis_complete- Description
Fired when call analysis finishes successfully.
- Name
call.analysis_failed- Description
Fired when analysis fails.
- Name
call.ingestion_failed- Description
Fired when recording ingestion fails.
Headers
Webhook deliveries are POST requests with JSON body and these headers:
- Name
X-Voxxi-Event- Type
- string
- Description
Event name, for example
call.analysis_complete.
- Name
X-Voxxi-Timestamp- Type
- string
- Description
Unix timestamp (seconds) used in signature generation.
- Name
X-Voxxi-Signature- Type
- string
- Description
Signature in the format
v1=<hex_hmac_sha256>.
- Name
X-Voxxi-Delivery-Id- Type
- string
- Description
Unique id for this delivery attempt.
Payload envelope
{
"id": "delivery_uuid",
"type": "call.analysis_complete",
"createdAt": "2026-01-01T00:00:00.000Z",
"data": {
"callId": "call_uuid",
"organizationId": "org_uuid"
}
}
data fields vary by event type. call.analysis_complete includes analysis results, transcript/extractions, tags, and metadata.
Event payload schemas
All webhook deliveries use the same top-level envelope:
- Name
id- Type
- string
- Description
Unique delivery id (
UUID).
- Name
type- Type
- string
- Description
Webhook event type.
- Name
createdAt- Type
- string
- Description
ISO-8601 timestamp for delivery creation.
- Name
data- Type
- object
- Description
Event-specific payload. See schemas below.
call.analysis_complete
- Name
data.callId- Type
- string
- Description
Call id.
- Name
data.organizationId- Type
- string
- Description
Organization id.
- Name
data.memberId- Type
- string | null
- Description
Agent/member id.
- Name
data.memberName- Type
- string | null
- Description
Agent/member display name.
- Name
data.categoryId- Type
- string | null
- Description
Category id used for analysis.
- Name
data.duration- Type
- number
- Description
Call duration in seconds.
- Name
data.date- Type
- string
- Description
Call date (YYYY-MM-DD).
- Name
data.audioUrl- Type
- string | null
- Description
Recording URL.
- Name
data.udfs- Type
- object | null
- Description
User-defined fields attached to the call.
- Name
data.score- Type
- number
- Description
Overall analysis score.
- Name
data.outcomeLabel- Type
- string | null
- Description
Outcome label.
- Name
data.outcomeRationale- Type
- string | null
- Description
Explanation for outcome.
- Name
data.callObservations- Type
- string | null
- Description
Observations summary.
- Name
data.areasForImprovement- Type
- string | null
- Description
Improvement summary.
- Name
data.summary- Type
- string | null
- Description
Short call summary.
- Name
data.transcript- Type
- array | null
- Description
Array of transcript segments:
{ start, end, speaker, content }.
- Name
data.extractions- Type
- array | null
- Description
Extraction objects:
{ id, fieldName, displayName, value, fieldType, description, required, enumValues }.
- Name
data.analytics- Type
- array
- Description
Section-level scoring:
{ sectionId, sectionName, score, totalScore, criterias[] }.
- Name
data.uploadedBy- Type
- string | null
- Description
Uploader user id.
- Name
data.uploadedByName- Type
- string | null
- Description
Uploader name.
- Name
data.uploadedByEmail- Type
- string | null
- Description
Uploader email.
- Name
data.tags- Type
- array
- Description
Call tags:
{ id, slug, displayName, description }.
- Name
data.completedAt- Type
- string
- Description
ISO-8601 timestamp when analysis completed.
- Name
data.createdAt- Type
- string
- Description
ISO-8601 timestamp when call was created.
call.analysis_complete example
{
"id": "4e7f0708-5418-48c8-bf68-06cfef58da9d",
"type": "call.analysis_complete",
"createdAt": "2026-04-09T07:30:00.000Z",
"data": {
"callId": "bff2f584-8bba-4fce-bc99-c5adf72f04a2",
"organizationId": "25f7f786-f334-4f0c-9f0d-09d9aef6f37a",
"memberId": "ee96ce4e-8f8a-4e87-8a7f-93ea7c2260e1",
"memberName": "Ari Sharma",
"categoryId": "e9862d12-d729-47ef-8173-99e4e2804c0f",
"duration": 642,
"date": "2026-04-09",
"audioUrl": "https://cdn.example.com/calls/call-123.mp3",
"udfs": {
"leadId": "lead_123",
"source": "website"
},
"score": 86,
"outcomeLabel": "Qualified",
"outcomeRationale": "Clear need, budget, and timeline captured.",
"callObservations": "Strong discovery and objection handling.",
"areasForImprovement": "Tighter next-step confirmation.",
"summary": "Prospect agreed to product demo next week.",
"transcript": [
{
"start": 0.12,
"end": 4.33,
"speaker": "agent",
"content": "Thanks for taking the call today."
}
],
"extractions": [
{
"id": "ext_1",
"fieldName": "budget",
"displayName": "Budget",
"value": "$12,000",
"fieldType": "string",
"description": "Customer-stated budget",
"required": false,
"enumValues": null
}
],
"analytics": [
{
"sectionId": "discovery",
"sectionName": "Discovery",
"score": 8,
"totalScore": 10,
"criterias": [
{
"criteriaId": "asked_pain_points",
"question": "Did the agent uncover pain points?",
"result": true,
"rationale": "Customer pain points were clarified."
}
]
}
],
"uploadedBy": "e535a336-2cb5-49a6-9292-d3670a52edba",
"uploadedByName": "Priya Nair",
"uploadedByEmail": "priya@example.com",
"tags": [
{
"id": "76f8b94e-c18e-4ce4-b4c2-b78bc4cae4e6",
"slug": "enterprise",
"displayName": "Enterprise",
"description": "Enterprise opportunity"
}
],
"completedAt": "2026-04-09T07:29:52.000Z",
"createdAt": "2026-04-09T07:10:41.000Z"
}
}
call.analysis_failed
- Name
data.callId- Type
- string
- Description
Call id.
- Name
data.organizationId- Type
- string
- Description
Organization id.
- Name
data.message- Type
- string
- Description
Failure reason summary.
- Name
data.failedAt- Type
- string
- Description
ISO-8601 failure timestamp.
call.analysis_failed example
{
"id": "dff42aec-c880-472f-9df1-d16bdc77661e",
"type": "call.analysis_failed",
"createdAt": "2026-04-09T07:31:00.000Z",
"data": {
"callId": "bff2f584-8bba-4fce-bc99-c5adf72f04a2",
"organizationId": "25f7f786-f334-4f0c-9f0d-09d9aef6f37a",
"message": "Call analysis failed",
"failedAt": "2026-04-09T07:30:58.000Z"
}
}
call.ingestion_failed
- Name
data.callId- Type
- string
- Description
Call id.
- Name
data.organizationId- Type
- string
- Description
Organization id.
- Name
data.recordingUrl- Type
- string
- Description
Recording URL that failed ingestion.
- Name
data.errorMessage- Type
- string
- Description
Ingestion error details.
- Name
data.failedAt- Type
- string
- Description
ISO-8601 failure timestamp.
call.ingestion_failed example
{
"id": "f554c715-cfd8-46fe-a3ca-4381e0263e91",
"type": "call.ingestion_failed",
"createdAt": "2026-04-09T07:32:00.000Z",
"data": {
"callId": "bff2f584-8bba-4fce-bc99-c5adf72f04a2",
"organizationId": "25f7f786-f334-4f0c-9f0d-09d9aef6f37a",
"recordingUrl": "https://cdn.example.com/calls/call-123.mp3",
"errorMessage": "Unable to ingest recording",
"failedAt": "2026-04-09T07:31:58.000Z"
}
}
Signature verification
The signature is HMAC-SHA256 over:
<timestamp>.<raw_request_body>
using your webhook signing secret.
Verify X-Voxxi-Signature
import crypto from 'crypto'
function verifyVoxxiSignature({ secret, timestamp, rawBody, signatureHeader }) {
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${rawBody}`)
.digest('hex')
const provided = signatureHeader?.replace(/^v1=/, '')
return Boolean(provided) && crypto.timingSafeEqual(
Buffer.from(expected, 'hex'),
Buffer.from(provided, 'hex')
)
}