CRM webhooks
CRM webhooks send call outcomes from VaniAgent to an HTTPS endpoint you control.
Supported events
Section titled “Supported events”call.completedcall.recording_readycall.failed
Events may originate from campaign, direct/send-call, web test, or inbound calls. Subscribe only to events your consumer handles.
Delivery settings
Section titled “Delivery settings”The endpoint must use HTTPS. Configure a timeout from 5–120 seconds and 0–10 retries. Return a 2xx response promptly; queue slower CRM work after authentication.
Verify the signature
Section titled “Verify the signature”VaniAgent signs the raw request body with HMAC-SHA256 and sends the digest in X-Webhook-Signature.
import hashlib, hmac
def valid_signature(raw_body: bytes, received: str, secret: str) -> bool: expected = hmac.new( secret.encode("utf-8"), raw_body, hashlib.sha256, ).hexdigest() return hmac.compare_digest(f"sha256={expected}", received)Do not parse and re-serialize JSON before verification; verify the exact raw bytes received.
Test and operate
Section titled “Test and operate”Use Test delivery, confirm the signature check succeeds, and inspect delivery logs. Logs include event, attempt, HTTP result, and error details. Repeated failures can degrade or disable a webhook; fix the receiver, test successfully, then re-enable it.
Make processing idempotent because retries can deliver the same logical event more than once.
Payload shapes
Section titled “Payload shapes”All payloads contain event, timestamp, and data.
call.completed includes call identity, direction, status, duration, timestamps, provider identifiers, agent, optional campaign, transcript, analysis, and billing. Recordings are included when enabled for the webhook configuration.
{ "event": "call.completed", "timestamp": "2026-07-28T10:30:00Z", "data": { "call": { "id": "call_id", "phone_number": "+919876543210", "call_type": "campaign", "call_direction": "outbound", "status": "completed", "duration_seconds": 84, "provider": "exotel", "provider_call_id": "provider_id" }, "campaign": { "id": "campaign_id", "name": "Lead qualification" }, "agent": { "id": "agent_id" }, "transcript": { "text": "...", "with_timestamps": [] }, "analysis": { "summary": "...", "sentiment": "positive", "structured_data": {} }, "billing": { "cost": "4.20", "rate_per_minute": "3.00", "currency": "INR" } }}call.recording_ready contains call_id, phone number, call type/direction, and provider/S3 recording URLs. call.failed contains call identifiers and an error object.
Additional delivery headers include X-Webhook-Event and the signature header. Consumers should tolerate additional JSON fields.