Put a supervisor on a live call
Rings a supervisor onto an answered, in-progress call in
listen (hear only), whisper (hear both sides, and be heard
by the agent only) or barge (hear and speak to both sides)
mode. Only an ordinary two-party call can be supervised —
AI-agent calls, conference sessions and callers still waiting in
a queue all return calls.unsupported_call_type. A client or
sip target that is not registered, or a client target that
resolves to a different workspace, returns
calls.supervisor_unreachable.
A muted supervisor is never heard by the agent or caller, even
in whisper or barge — muting the leg (locally, on the
supervisor's own device) always wins over the mode.
One supervisor per call, enforced by a database constraint:
starting a second one returns calls.supervision_in_progress
naming the current supervisor. If a DELETE on this same call
raced the request and won, this returns
calls.supervision_stopped.
Mode changes only ever happen through this API — the PBX
switches the leg via an internal command, so a supervisor's own
handset DTMF does no such thing, and every mode_changed event
this produces carries source: "api".
Billed per minute from the supervisor leg's connect to its end:
KES 0.50/min for a client or sip supervisor, the workspace's
normal outbound rate for a phone supervisor (rated off the
supervised call's own number). A ringing or failed leg is never
billed. Progress and billing both arrive asynchronously as
call.supervision.* webhooks; this call only returns the leg's
initial connecting state.
Who can call this: a signed-in workspace owner or admin, or
a member holding the Supervisor licence — or an API key or OAuth
token with the calls.supervise scope. A device (handset)
credential can never supervise calls.
Authorization
bearerAuth Long-lived ES256 JWT minted from the dashboard (https://app.sautikit.com/developers/api-keys). Signed by the
platform keyring. Carries workspace_id and scopes claims;
revoked via the platform deny-list.
In: header
Path Parameters
The call's Sautikit UUID, or the PBX session id the same call
carries on the wire (HD_…, returned as session_id on
POST /v1/calls and on every webhook). Either form addresses
the same call. A call outside the active workspace returns 404,
never 400 — a malformed id (neither form) is the only case that
returns 400.
Header Parameters
Retrying the same key returns the same supervision instead of starting a second leg.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/calls/string/supervision" \ -H "Content-Type: application/json" \ -d '{ "mode": "listen", "supervisor": { "type": "client" } }'{ "supervision_id": "3f1c2a9e-6b7d-4e2a-9f0b-1c2d3e4f5a6b", "call_id": "9d2b1f53-8c0e-4f1d-9a6b-5d3a8c47e9f0", "session_id": "HD_24d73b4518bc", "supervisor_leg_id": "sv_8f2c1a", "mode": "whisper", "announce": "agent", "supervisor": { "type": "client", "identity": "agent-supervisor-1", "label": "Amina (QA)" }, "notify_agent": true, "state": "connected", "connected_at": "2026-09-29T09:21:18.442Z", "created_at": "2026-09-29T09:21:13.987Z"}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string", "details": [ "string" ], "resolution": "string", "reason": "invalid_characters", "suggested_e164": "+254727524723" }}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string", "details": [ "string" ], "resolution": "string", "reason": "invalid_characters", "suggested_e164": "+254727524723" }}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string", "details": [ "string" ], "resolution": "string", "reason": "invalid_characters", "suggested_e164": "+254727524723" }}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string", "details": [ "string" ], "resolution": "string", "reason": "invalid_characters", "suggested_e164": "+254727524723" }}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string", "details": [ "string" ], "resolution": "string", "reason": "invalid_characters", "suggested_e164": "+254727524723" }}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string", "details": [ "string" ], "resolution": "string", "reason": "invalid_characters", "suggested_e164": "+254727524723" }}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string", "details": [ "string" ], "resolution": "string", "reason": "invalid_characters", "suggested_e164": "+254727524723" }}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string", "details": [ "string" ], "resolution": "string", "reason": "invalid_characters", "suggested_e164": "+254727524723" }}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string", "details": [ "string" ], "resolution": "string", "reason": "invalid_characters", "suggested_e164": "+254727524723" }}Get the call's active supervision GET
`supervision` is `null` when no supervisor is on the call. **Who can call this:** a signed-in workspace owner or admin, or a member holding the Supervisor licence — or an API key or OAuth token with the `calls.read` scope. Seeing who is listening in on a call is itself treated as supervisory access.
Change the supervisor's mode PATCH
Switches the active supervision between `listen`, `whisper` and `barge` in place. Setting the mode it is already in succeeds without contacting the PBX. A supervisor who has muted their own leg stays unheard regardless of mode. **Who can call this:** a signed-in workspace owner or admin, or a member holding the Supervisor licence — or an API key or OAuth token with the `calls.supervise` scope.