---
title: call.supervision.ended
description: >-
  Fires when a supervision ends: the supervisor left or hung up, the call ended
  or was transferred, or nobody answered.
summary: >-
  Emitted once when a supervision ends. Carries the reason and duration_seconds,
  the billable seconds of the supervisor leg.
date: 2026-09-30T00:00:00.000Z
type: webhook-event
---


## Summary

`call.supervision.ended` fires once when a supervision is over. A supervisor who answered always ends with this event. A supervisor who never answered also ends here, with `reason: "no_answer"` and `duration_seconds: 0`. The call itself carries on unless it was the call that ended.

This event is subscribable as a workspace webhook: add `call.supervision.ended` to the `events` of a subscription created with [Create a webhook](/developers/api/createWebhook). Supervision events are subscribed by name; there is no `call.supervision.*` wildcard. Delivery is at least once, so deduplicate on the `X-Sautikit-Event-Id` header.

## Payload

The body is flat. The event kind travels in the `X-Sautikit-Event-Kind` header.

```json
{
  "workspace_id": "01900000-0000-7000-8000-000000000002",
  "call_id": "9d2b1f53-8c0e-4f1d-9a6b-5d3a8c47e9f0",
  "session_id": "HD_24d73b4518bc",
  "supervision_id": "0f6d3c1e-5a8b-4c2d-9e7f-1a2b3c4d5e6f",
  "mode": "listen",
  "supervisor": {
    "type": "client",
    "identity": "mary",
    "label": "Mary Wanjiku"
  },
  "occurred_at": "2026-09-30T09:15:04Z",
  "reason": "supervisor_left",
  "duration_seconds": 95
}
```

Every supervision event carries `workspace_id`, `call_id` (the supervised call's UUID), `session_id` (its `HD_` session id), `supervision_id`, `mode`, `supervisor` (`type`, then `identity` for `client` and `sip` or `number` for `phone`, and `label` when you set one) and `occurred_at`.

## Fields

| Field | Type | Description |
|---|---|---|
| `reason` | string | Why the supervision ended. See below. |
| `duration_seconds` | integer | Seconds from answer to end, rounded up. `0` when the supervisor never answered. |

`reason` is one of:

- **`supervisor_left`**: the supervision was stopped through the API.
- **`supervisor_hangup`**: the supervisor hung up.
- **`call_ended`**: the customer or the agent hung up, so the call ended.
- **`call_transferred`**: the call was transferred or redirected. The supervisor does not follow it.
- **`no_answer`**: the supervisor did not answer within 30 seconds.
- **`insufficient_balance`**: the wallet could not cover the running supervisor leg, so Sautikit removed the supervisor.


## Headers

| Header | Description |
|---|---|
| `X-Sautikit-Event-Id` | UUID of the event. Use it to deduplicate. |
| `X-Sautikit-Event-Kind` | `call.supervision.ended` |
| `X-Sautikit-Delivery-Id` | UUID of this delivery. |
| `X-Sautikit-Attempt` | Attempt number, starting at `1`. |
| `X-Sautikit-Timestamp` | Unix time the delivery was signed. |
| `X-Sautikit-Signature` | `t=<timestamp>,v1=<hex HMAC-SHA256>`. See [Verify webhook signatures](/developers/guides/verify-webhook-signatures). |

## Next steps

- [Supervise live calls](/developers/guides/supervise-live-calls): start, switch and stop supervision.
- [Webhook concepts](/developers/concepts/webhooks): delivery, retries and subscriptions.
