When a call session ends, Agni dispatches a call.completed webhook event to any URLs configured in your agent’s Webhook Settings. This delivers the full call record including transcripts, AI analysis, and metadata.
Configure webhook URLs in the agent builder’s Webhook Settings panel, or via the Agent API webhook_urls field.

Event Details

FieldValue
Event namecall.completed
MethodPOST
Content-Typeapplication/json
TriggerAutomatically dispatched when a call session ends

Payload Structure

event
string
Event type identifier. Always "call.completed" for this webhook.
org_id
string
UUID of the organization that owns this call.
data
object
Full call session data.

Example Payload

{
  "event": "call.completed",
  "org_id": "1268c1f0-19f3-47db-aefb-c16a7c3ace6e",
  "data": {
    "campaign_id": "019d2a1b-4c5e-7f8a-9b0c-1d2e3f4a5b6c",
    "contact_id": "019d2a1b-5d6f-7a8b-9c0d-2e3f4a5b6c7d",
    "phone": "+14155550100",
    "status": "completed",
    "duration_sec": 125,
    "call_session_id": "019d2b3c-8e9f-7a0b-1c2d-4e5f6a7b8c9d",
    "attempt": 1,
    "summary": "Customer called about their order #4521. Agent confirmed the order shipped yesterday and provided the tracking number. Customer was satisfied.",
    "recording_url": "https://storage.agniai.com/rec/019d2b3c-8e9f.mp3",
    "caller_number": "+18881234567",
    "callee_number": "+14155550100",
    "caller_name": "John Doe",
    "caller_email": "john@example.com",
    "agent_name": "Support Agent",
    "channel": "voice",
    "disconnect_reason": "customer_hangup",
    "cost_total": 0.42,
    "call_latency_ms": 150,
    "started_at": "2026-03-24T18:30:00Z",
    "ended_at": "2026-03-24T18:32:05Z",
    "created_at": "2026-03-24T18:30:00Z",
    "post_call_analysis": {
      "sentiment": "positive",
      "disposition": "issue_resolved",
      "goals_met": true,
      "next_steps": "No follow-up needed. Customer issue fully resolved."
    },
    "transcripts": [
      {
        "id": "t-001",
        "timestamp_ms": 0,
        "role": "agent",
        "message": { "content": "Hello! Thanks for calling Acme Support. How can I help you today?", "format": "text" },
        "created_at": "2026-03-24T18:30:00Z"
      },
      {
        "id": "t-002",
        "timestamp_ms": 3200,
        "role": "user",
        "message": { "content": "Hi, I wanted to check on my order number 4521.", "format": "text" },
        "created_at": "2026-03-24T18:30:03Z"
      },
      {
        "id": "t-003",
        "timestamp_ms": 5800,
        "role": "agent",
        "message": { "content": "Of course! Let me look that up for you. Order 4521 shipped yesterday and the tracking number is TRK-98765. It should arrive by Friday.", "format": "text" },
        "created_at": "2026-03-24T18:30:05Z"
      }
    ]
  }
}

Handling Webhooks

Your endpoint must return a 200 HTTP status code to acknowledge receipt. If Agni doesn’t receive a 200, it will retry the webhook.
Always check that the org_id in the payload matches your organization to prevent processing webhooks from other sources.
Return 200 immediately and process the data in a background job. Don’t make the webhook wait for your database writes or API calls.
Use call_session_id as a unique key to deduplicate webhook deliveries in case of retries.