List call detail records for the active workspace
Returns the workspace's call detail records, most-recent first.
Cursor pagination via cursor (opaque, returned as
next_cursor when more results exist). Filters: status
(CSV), direction, q (substring on remote_e164 or
session_id), from / to (RFC3339 or unix seconds),
session_id (exact match), limit (1–100, default 25).
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
Query Parameters
Comma-separated subset of statuses. The backend accepts
BOTH the canonical underscored form (no_answer,
in_progress) AND the dash-cased form
(no-answer, in-progress) — dashes are normalized to underscores before matching. Values
are always returned in the underscored form.
Value in
- "ringing"
- "answered"
- "completed"
- "failed"
- "no_answer"
- "no-answer"
- "busy"
- "canceled"
Value in
- "inbound"
- "outbound"
1 <= value <= 100Response Body
application/json
application/json
application/json
curl -X GET "https://example.com/v1/calls"{ "data": [ { "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9", "session_id": "string", "direction": "inbound", "local_e164": "string", "remote_e164": "string", "country": "string", "started_at": "2019-08-24T14:15:22Z", "answered_at": "2019-08-24T14:15:22Z", "ended_at": "2019-08-24T14:15:22Z", "duration_seconds": 0, "status": "ringing", "cost_minor": 0, "cost_currency": "string", "rate_per_minute_minor": 0, "ledger_entry_id": "34c94b99-ae7e-4ed1-928e-78f0df05c275", "pbx_call_id": "string", "failure_code": "string", "metadata": {}, "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z", "events": [ { "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "call_id": "0d0a16ab-a508-4d58-bf24-5dc3cb248f3e", "kind": "string", "payload": {}, "occurred_at": "2019-08-24T14:15:22Z", "created_at": "2019-08-24T14:15:22Z" } ] } ], "next_cursor": "string"}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string" }}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string" }}Revoke a SIP credential DELETE
Deletes the credential row. The associated SIP user-agent can no longer register with this username. Caller must have writer access to the workspace.
Place an outbound call via the PBX POST
Places an outbound call from a workspace number (`from`) to one or more destination numbers (`to`). The call is dialed immediately and the response returns before the remote party answers — poll `GET /v1/calls/{id}` or subscribe to `call.answered` / `call.completed` webhooks for final status. A wallet pre-flight check fires before the PBX is contacted: if the workspace balance is zero the request is rejected 402 (`wallet.insufficient_balance`) without a PBX leg being created. Idempotency & correlation: the `Idempotency-Key` header scopes deduplication — repeated requests with the same key within the active leg's lifetime return the original response. The header value is also forwarded to the PBX as its `clientRequestId`, but the PBX does not reliably echo it back on callbacks — correlate on the `call_id` / `session_id` returned by this endpoint instead (they appear on `call.completed` / `call.failed` webhook payloads as `call_id` / `pbx_call_id`).