Fetch the recording resource for a call (redirect or status)
Returns the recording asset for the given call in one of three ways depending on the recording's lifecycle state:
-
302 — recording is ready;
Locationheader carries a 15-minute presigned Sautikit CDN URL. The response body is empty. The client can passLocationdirectly to<audio src=...>— audio bytes do NOT flow through the API process. The Sautikit URL is the only URL ever surfaced; the raw PBX URL is never exposed. -
202 — recording capture is still in progress (
status: pending). The client should waitretry_after_secondsbefore re-polling (also reflected in theRetry-Afterresponse header). Error code:recording_not_ready. -
410 — the asset has been pruned per the workspace's storage-tier retention policy and is permanently unavailable. Error code:
recording_unavailable. -
404 — the call does not exist, belongs to a different workspace, or was never configured for recording. Cross-tenant existence is not leaked. Error code:
recording_not_found.
Workspace isolation: call_id must belong to the active workspace;
otherwise the endpoint returns 404.
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
UUID of the Sautikit call row.
uuidResponse Body
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/v1/calls/497f6eca-6276-4993-bfeb-53cbbbba6f08/recording"{ "status": "pending", "retry_after_seconds": 10}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string" }}{ "error": { "code": "recording_not_found", "message": "call recording not found", "request_id": "req-a1b2c3d4" }}{ "code": "recording_unavailable", "reason": "recording pruned after 30-day retention window"}Submit voice actions for a control event (MCP live call control) POST
Answers a `response_required` event from `GET /v1/calls/{call_id}/control/events` with a voice-actions batch (same schema as `validate_voice_actions`). Each event can be answered exactly once.
Mint a short-lived WebRTC PBX token for the browser softphone POST
Requests a workspace-scoped WebRTC bearer token from the PBX. The token is returned as-is from the PBX; the caller passes it to the in-browser softphone SDK to register. Short-lived (typically 60–300 s); renew before expiry. Optional body fields (`client_name`, `role`) are forwarded to the PBX and reflected in token claims; both may be omitted. Every body field is optional, but the request body itself must be valid JSON — send at least `{}` (an empty body is rejected 400 `validation.bad_request`). To bind the token to one of your DIDs (so the WebRTC session routes through that number), pass **either** `tenant_number_id` (the internal number id) **or** `phone_number` (the DID in E.164). The backend resolves the number's PBX sip-profile and embeds it as the token's `sip.id` claim. Omit both to mint a non-DID-bound token, in which case the PBX assigns `sip.id` `"default"`. When both are supplied, `tenant_number_id` wins.