> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cartesia.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Call webhooks

> Receive call events at your own endpoint.

A call webhook sends each call's events to an HTTPS endpoint on your server: when the call starts, every turn, when it ends, and a summary afterward. Use it to log calls or trigger follow-up work.

## Add a webhook

> [tab] Playground
>
> 1. Open the agent and go to **Advanced**.
> 2. Under **Context**, click **Add webhook** next to **Post-call webhooks**.
> 3. Enter a **Name**, the **URL**, and an **Authentication Secret** of your choice.
> 4. Click **Add**.
>
> The webhook applies to new calls right away, without **Publish**.
>
> ![Context group on the Advanced page with Post-call webhooks and Time zone settings](https://mintcdn.com/cartesia-2650f86a/rNXFyzq4MzdYRAHq/assets/images/agents/advanced-context.png?fit=max\&auto=format\&n=rNXFyzq4MzdYRAHq\&q=85\&s=d0d8dace5c8e9aa09c7c67bf4e4168b1)
>
> Post-call webhooks on the Advanced page.

> [tab] API
>
> Create the webhook with [`POST /agents/webhooks`](https://docs.cartesia.ai/api-reference/agents/webhooks/create):
>
> ```bash theme={null}
> curl -X POST "https://api.cartesia.ai/agents/webhooks" \
>   -H "X-API-Key: $CARTESIA_API_KEY" \
>   -H "Cartesia-Version: 2026-08-14" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "display_name": "Call events",
>     "url": "https://example.com/cartesia/events",
>     "secret": "YOUR_WEBHOOK_SECRET"
>   }'
> ```
>
> Then attach its `id` to the agent with [`PATCH /v1/agents/{agent_id}`](https://docs.cartesia.ai/api-reference/agents/update):
>
> ```json theme={null}
> { "config": { "event_webhook_id": "agent_webhook_..." } }
> ```
>
> Set `event_webhook_id` to `null` to detach it.

An agent has one webhook, and it receives every event type. Several agents can share a webhook.

## Verify requests

Each request is a `POST` with `Content-Type: application/json` and an `X-Webhook-Secret` header containing the secret you set. Reject requests where the header doesn't match.

## Events

| `type` | Sent when |
| - | - |
| `call_started` | The call connects. |
| `call_turn` | A turn finishes. Each tool call arrives as its own assistant turn with `tool_calls`. |
| `call_completed` | The call ends normally. |
| `call_failed` | The call fails or isn't answered. A failed outbound call may have no `call_started` before it. |
| `post_call_analysis` | A one or two sentence summary is ready, after the call ends. Calls where nobody spoke get no summary. |

Ignore event types you don't handle; Cartesia may add more.

## Payload

Every event shares these fields:

| Field | Description |
| - | - |
| `type` | Event type. |
| `call_id`, `agent_id`, `webhook_id` | IDs for the call, agent, and webhook. |
| `webhook_request_id` | Unique per event and the same across retries. Use it to drop duplicates. |
| `timestamp` | When the event was sent, in RFC 3339. |
| `body` | The transcript on `call_completed` and `call_failed`, the turn on `call_turn`, otherwise `null`. |

The events above also carry one detail object:

* `call` on `call_started`, `call_completed`, and `call_failed`: the full call, the same object [Get Call](https://docs.cartesia.ai/api-reference/agents/calls/get-call.md) returns. `end_reason` is also set on the last two.
* `turn` on `call_turn`: `role`, `text`, `start_timestamp`, `end_timestamp`, `was_interrupted`, and, on turns that invoke tools, `tool_calls` with each call's `name`, `arguments`, and `result`.
* `analysis` on `post_call_analysis`: `summary`.

```json call_turn theme={null}
{
  "type": "call_turn",
  "call_id": "ac_3kF9mN2pQ8rT1vX6",
  "agent_id": "agent_Fo7pKNBUwLZxrTd6jvhpaE",
  "webhook_id": "agent_webhook_...",
  "webhook_request_id": "...",
  "timestamp": "2026-10-30T18:02:11Z",
  "body": {
    "id": 3,
    "role": "user",
    "text": "I want to reschedule.",
    "start_timestamp": 3.5,
    "end_timestamp": 5.8,
    "was_interrupted": false
  },
  "turn": {
    "id": 3,
    "role": "user",
    "text": "I want to reschedule.",
    "start_timestamp": 3.5,
    "end_timestamp": 5.8,
    "was_interrupted": false
  }
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.