Get the call's active supervision
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.
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.
Response Body
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/v1/calls/string/supervision"{ "supervision": { "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" }}Terminate an active call POST
Requests termination of an in-progress call via the PBX. The browser SDK dials directly over WebRTC; this server-side endpoint is the control-plane hangup used to force-end a live call. Workspace isolation: `call_id` must belong to the active workspace, otherwise this endpoint returns 404 (cross-tenant existence is not leaked). Idempotent: if the PBX reports the call already ended, the request still succeeds. Addressable by either the Sautikit call row UUID (the `call_id` from `POST /v1/calls` / the `id` from `GET /v1/calls`) or the PBX session id (`HD_…`) the same call carries on the wire — the server resolves the stored PBX session itself either way.
Put a supervisor on a live call POST
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.