Webhooks
/settings/webhooks · HMAC-SHA256 signingWhen a call or campaign event fires, we POST a signed JSON payload to your endpoint. Configure endpoints under Settings → Webhooks in the dashboard.
Event types
call.queued— call added to dial queuecall.connected— far end picked upcall.completed— call finished, includes duration + dispositioncall.failed— call attempted but didn't connect (busy, no_answer, failed)campaign.startedcampaign.compliance_paused— abandon rate exceeded 3.5%
Request shape
POST /your-endpoint HTTP/1.1
Content-Type: application/json
User-Agent: VICIagent-Webhook/1.0
X-VICIagent-Event: call.completed
X-VICIagent-Delivery: 9f4e2c8a-... (uuid, unique per delivery)
X-VICIagent-Timestamp: 1715616000 (unix seconds)
X-VICIagent-Signature: t=1715616000,v1=4f8a9b...
{
"id": "9f4e2c8a-...",
"type": "call.completed",
"occurredAt": "2026-05-13T10:00:00Z",
"data": {
"callId": "...",
"agentId": "...",
"contactId": "...",
"durationSeconds": 245,
"status": "completed",
"disposition": "normal",
"recordingUrl": null
}
}Verification
Recompute HMAC-SHA256(secret, body) using the endpoint's signing secret (shown ONCE at creation time, never displayed again). Match against the v1= value in X-VICIagent-Signature. Reject if it doesn't match. Reject also if the timestamp is more than 5 minutes off your clock (replay defense).
Node.js example:
import { createHmac } from 'node:crypto';
function verify(req, secret) {
const sig = req.headers['x-viciagent-signature']
.match(/v1=([a-f0-9]+)/)[1];
const expected = createHmac('sha256', secret)
.update(req.rawBody)
.digest('hex');
return sig === expected;
}Retries + auto-disable
Failed deliveries (non-2xx response or timeout) retry with exponential backoff: 5s → 30s → 120s → abandoned. After 10 consecutive failures across deliveries, we auto-disable the endpoint and surface it on the Webhooks page with a reason. Re-enable manually after fixing the receiver.
Idempotency
The same delivery may arrive more than once (we retry on transient errors). Use X-VICIagent-Delivery as the dedupe key on your side — process each delivery ID exactly once.