--- title: CRM webhooks description: Receive authenticated VaniAgent call events in your CRM or automation service. --- CRM webhooks send call outcomes from VaniAgent to an HTTPS endpoint you control. ## Supported events - `call.completed` - `call.recording_ready` - `call.failed` Events may originate from campaign, direct/send-call, web test, or inbound calls. Subscribe only to events your consumer handles. ## 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 VaniAgent signs the raw request body with HMAC-SHA256 and sends the digest in `X-Webhook-Signature`. ```python 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 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 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. ```json { "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.