Start a WebSocket audio relay

View as Markdown
Attach a live, bidirectional audio relay between this session and an external WebSocket backend. Audio streams both ways for the life of the relay. Only one relay may be active per session at a time — starting a second returns `409`. Asynchronous command; outcomes arrive as `websocket.*` webhook events. **Triggered webhooks:** `websocket.connected`, `websocket.disconnected`, `websocket.failed`, `websocket.message_received`, `websocket.audio_playback_completed`

Authentication

AuthorizationBearer
Application auth. Send `Authorization: Bearer <app_uuid>:<api_key>`. See [Authentication](https://voice-platform.docs.buildwithfern.com/api/authentication) for details.

Path parameters

uuidstringRequired

Session UUID (format {5-char-prefix}-{uuid}).

Headers

Idempotency-KeystringOptionalformat: "^[a-zA-Z0-9._-]+$"<=128 characters
Optional client-generated key for a mutating endpoint. It identifies one method, route, query, content type, and exact raw body within the authenticated app. Reusing it for a different request returns 422. While its record exists, a retry replays the original accepted response when available. Keys are valid for 1 hour. Allowed characters: letters, digits, dot, hyphen, underscore; max 128 characters. See the Idempotency guide.

Request

WebSocket audio relay configuration. Shared by the ws/start command and the ws block of POST /v1/sessions.

from_session_audio_rateintegerRequired8000-192000

Sample rate (Hz) of audio captured from the session and sent to the backend. One of 8000, 16000, 24000, or any multiple of 8000 up to 192000.

to_session_audio_rateintegerRequired8000-192000

Sample rate (Hz) of audio the backend pushes back to the session. Same bounds as from_session_audio_rate.

urlstringRequiredformat: "uri"<=4096 characters
WebSocket relay URL. `wss://` is accepted by default. Controlled deployments may opt into plaintext `ws://` by setting `WS_RELAY_ALLOW_INSECURE=true`; without that explicit server-side setting, `ws://` is rejected. The host must resolve to a permitted public address; private, loopback, and link-local targets are rejected (SSRF protection).
operation_uuidstringOptionalformat: "uuid"
Optional caller-supplied per-command correlation id, a bare lowercase RFC-4122 v4 UUID (no prefix). Echoed back as `operation_uuid` in the 202 ack. A later lifecycle webhook carries it only when the gateway can unambiguously associate that event with this command; the field is correlation, not proof of causation. When omitted, the gateway mints one. Not an idempotency key — request deduplication is the `Idempotency-Key` header. Invalid input (not a v4 UUID) is rejected with `400 invalid_request`.
headersmap from strings to stringsOptional

Header name→value map sent on the WebSocket handshake (e.g. auth). Bounded count and total size; values may not contain line breaks.

start_mutedbooleanOptionalDefaults to false

If true, the user’s audio is not sent to the backend until ws/unmute.

Response

Command accepted for async execution
operation_uuidstringformat: "uuid"
statusenum
already_endedtrueOptional

Optional. Set to true on idempotent terminal commands when the session was already in a terminal state at the time the request was received. Absent otherwise.

Errors

400
Bad Request Error
401
Unauthorized Error
404
Not Found Error
409
Conflict Error
413
Content Too Large Error
415
Unsupported Media Type Error
422
Unprocessable Entity Error
429
Too Many Requests Error
500
Internal Server Error
503
Service Unavailable Error