Submit voice actions for a control event (MCP live call control)
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.
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.
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
curl -X POST "https://example.com/v1/calls/string/control/respond" \ -H "Content-Type: application/json" \ -d '{ "event_id": "string", "actions": [ {} ] }'{ "accepted": true, "seq": 0}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string", "details": [ "string" ] }}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string", "details": [ "string" ] }}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string", "details": [ "string" ] }}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string", "details": [ "string" ] }}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string", "details": [ "string" ] }}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string", "details": [ "string" ] }}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string", "details": [ "string" ] }}{ "error": { "code": "validation.bad_request", "message": "string", "request_id": "string", "details": [ "string" ] }}Long-poll for live call-control events (MCP live call control) GET
Long-poll mailbox read for a call placed with `control: "mcp"` on `POST /v1/calls`. Returns as soon as at least one event with `seq > after_seq` exists, or after `timeout_seconds` with an empty `events` array and `timed_out: true`. Only calls under `control_mode = "mcp"` are readable here — any other call 404s exactly like a missing call (`calls.control_not_enabled` vs `calls.not_found`; both 404).
Fetch the recording resource for a call (redirect, JSON, or status) GET
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.