API Reference
Calls

Fetch the recording resource for a call (redirect, JSON, or status)

GET
/v1/calls/{call_id}/recording

Returns the recording asset for the given call in one of four ways depending on the recording's lifecycle state and the requested response mode:

  • 302 (default) — recording is ready; Location header carries a 15-minute presigned Sautikit CDN URL. The response body is empty. The client can pass Location directly 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.

  • 200 — JSON mode: send Accept: application/json or ?format=json and a ready recording is returned as JSON metadata instead of the redirect. url/recording_url carry the same presigned Sautikit URL the 302 would have used (15-minute TTL), alongside size_bytes, duration_seconds, mime/content_type, and expires_at. Prefer this mode from browsers: a cross-origin fetch cannot follow the 302 (the redirect hop fails CORS) — fetch the JSON and hand url to <audio src=...> instead.

  • 202 — recording capture is still in progress (status: pending). The client should wait retry_after_seconds before re-polling (also reflected in the Retry-After response 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.

call_id may be the Sautikit call UUID or the PBX session id (HD_…) the same call carries on the wire — a caller that watched the call happen can fetch its recording without looking the UUID up first.

Authorization

bearerAuth
AuthorizationBearer <token>

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

call_id*string

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.

Query Parameters

format?"json"

Set to json to force JSON mode (equivalent to Accept: application/json) — returns 200 metadata instead of the 302 redirect when the recording is ready.

Value in

  • "json"

Response Body

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/v1/calls/string/recording"
{  "url": "https://storage.sautikit.com/recordings/9d2b1f53/be36758c.wav?X-Amz-Signature=abc123",  "recording_url": "https://storage.sautikit.com/recordings/9d2b1f53/be36758c.wav?X-Amz-Signature=abc123",  "size_bytes": 1048576,  "duration_seconds": 45,  "mime": "audio/wav",  "content_type": "audio/wav",  "expires_at": "2026-07-22T10:31:57Z"}
{  "status": "pending",  "retry_after_seconds": 10}
Empty
{  "error": {    "code": "validation.bad_request",    "message": "string",    "request_id": "string",    "details": [      "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"}