End a session
const url = 'https://example.com/v1/sessions/example/end';const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://example.com/v1/sessions/example/end \ --header 'Authorization: Bearer <token>'Terminate a session immediately. Idempotent: calling on an already-terminal session returns 200 with the existing state. The session transitions to canceled if it had not yet started, or ending (then ended once the worker drains) if it was running.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”sess_… prefixed ULID.
sess_… prefixed ULID.
Responses
Section titled “ Responses ”Successful Response
Public session resource — what GET /v1/sessions/{id} returns.
object
Populated when Session.status == failed.
object
Stable lower_snake_case subcode.
Human-readable summary; not stable.
sess_… prefixed ULID.
Output quality tier. Drives the credit billing multiplier.
standard is the default for new sessions. mock is reserved for
internal tests and the bring-up runtime (no real model loaded); it
bills as standard when it appears on a real session.
Public session lifecycle.
Terminal states are ended, failed, canceled. ending is the
graceful-drain state while a worker finishes publishing in-flight frames.
BYO LiveKit transport.
The customer owns the room and mints worker_token; we never touch
their LiveKit API key or secret.
object
How the worker receives audio. See LiveKitAudioSource.
Name of the LiveKit room the worker should join.
If True and no participant joins within 10 s, the worker falls back to a synthetic sine generator. Demo aid only; default off.
Customer’s LiveKit URL, e.g. wss://my-app.livekit.cloud.
Identity the worker presents inside the room.
Short-lived JWT the customer mints authorizing our worker to join the room. Write-only. Never echoed back on read; GET /v1/sessions/{id}.transport.worker_token returns the string "[redacted]".
Reserved — raw WebSocket transport. Not yet available.
Listed in the schema so existing clients keep parsing future responses,
but POST /v1/sessions rejects it today with
invalid_request / code=transport.unsupported.
object
Reserved — Pipecat integration. Not yet available.
Rejected at create-time today; see WebSocketTransportConfig.
object
Live usage counters embedded in the Session resource.
Eventually-consistent — lags the latest worker heartbeat by up to
one interval. Canonical billing data lives in UsageEvent.
object
Example
{ "avatar_id": "av_demo", "created_at": "2026-05-25T19:00:00.123Z", "first_frame_at": "2026-05-25T19:00:02.001Z", "id": "sess_01HXY5K8E7QYG3X8Z6N9R7S0VR", "idle_timeout_seconds": 30, "max_duration_seconds": 600, "metadata": { "customer_session_id": "abc123" }, "object": "session", "quality": "standard", "started_at": "2026-05-25T19:00:01.456Z", "status": "running", "transport": { "audio_source": "data_stream", "room_name": "demo-room", "type": "livekit", "url": "wss://my-app.livekit.cloud" }, "usage": { "billable_seconds": 12, "frames": 300 }}Missing or invalid API key.
Wire format for every non-2xx public API response.
object
Concrete error returned inside ApiErrorEnvelope.error.
object
Stable machine-readable subcode (lower_snake_case). SDKs should switch on this, not message.
Human-readable summary. Not stable; do not parse.
Echo of the X-Request-Id response header for support.
Top-level error categories. Maps roughly to HTTP status.
code (a free-form lower_snake_case string on ApiError) is the
machine-readable subcode SDKs should switch on; type is the broad
category.
Example
{ "error": { "code": "transport.unsupported", "message": "transport.type=pipecat is reserved and not yet available", "param": "transport.type", "request_id": "req_01HXY5K8E7QYG3X8Z6N9R7S0VR", "type": "invalid_request" }}No session with that id.
Wire format for every non-2xx public API response.
object
Concrete error returned inside ApiErrorEnvelope.error.
object
Stable machine-readable subcode (lower_snake_case). SDKs should switch on this, not message.
Human-readable summary. Not stable; do not parse.
Echo of the X-Request-Id response header for support.
Top-level error categories. Maps roughly to HTTP status.
code (a free-form lower_snake_case string on ApiError) is the
machine-readable subcode SDKs should switch on; type is the broad
category.
Example
{ "error": { "code": "transport.unsupported", "message": "transport.type=pipecat is reserved and not yet available", "param": "transport.type", "request_id": "req_01HXY5K8E7QYG3X8Z6N9R7S0VR", "type": "invalid_request" }}Request body or parameters failed validation.
Wire format for every non-2xx public API response.
object
Concrete error returned inside ApiErrorEnvelope.error.
object
Stable machine-readable subcode (lower_snake_case). SDKs should switch on this, not message.
Human-readable summary. Not stable; do not parse.
Echo of the X-Request-Id response header for support.
Top-level error categories. Maps roughly to HTTP status.
code (a free-form lower_snake_case string on ApiError) is the
machine-readable subcode SDKs should switch on; type is the broad
category.
Example
{ "error": { "code": "transport.unsupported", "message": "transport.type=pipecat is reserved and not yet available", "param": "transport.type", "request_id": "req_01HXY5K8E7QYG3X8Z6N9R7S0VR", "type": "invalid_request" }}