Skip to content

Recording

Start and stop call recording via the wavstream WebSocket service. Recording configuration (wavstream URL, storage URL) comes from server environment variables, not the API payload.

All recording endpoints require App authentication via X-App-ID and X-API-Key headers. The session must exist and belong to your application.

Start recording the call via the wavstream WebSocket service. An infinite silence stream is started to keep the channel alive during recording. The command.result fires immediately. No user-supplied fields are needed; all recording parameters come from server configuration.

Request body

FieldTypeRequiredDescription
command_uidstringoptionalCaller-supplied idempotency key. Auto-generated UUID if omitted. Max 128 chars, ^[a-zA-Z0-9._-]+$.

No other request body fields are accepted. Recording destination and format are configured server-side.

Rate limitheavy group, 2 s cooldown per session. Shared with record/stop and play_and_get_digits.

POST /api/v1/sessions/{uuid}/commands/record/start
curl -X POST https://gateway.example.com/api/v1/sessions/{uuid}/commands/record/start \
  -H "X-App-ID: YOUR_APP_ID" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Triggered webhooks

  • command.result — immediate; published by the HTTP handler.

Stop recording the call. Stops the audio stream and the silence stream. Publishes both command.result and recording.completed immediately. The recording.completed webhook includes the recording URL, duration, and the original record/start command_uid.

Request body

FieldTypeRequiredDescription
command_uidstringoptionalCaller-supplied idempotency key. Auto-generated UUID if omitted. Max 128 chars, ^[a-zA-Z0-9._-]+$.

Rate limitheavy group, 2 s cooldown per session. Shared with record/start and play_and_get_digits.

POST /api/v1/sessions/{uuid}/commands/record/stop
curl -X POST https://gateway.example.com/api/v1/sessions/{uuid}/commands/record/stop \
  -H "X-App-ID: YOUR_APP_ID" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Triggered webhooks

  • command.result — immediate; fires right after command dispatch.
  • recording.completed — immediate; includes recording_url, duration, and the original record/start command_uid.

When record/stop is called, the recording.completed webhook includes:

FieldTypeDescription
eventstringAlways "recording.completed".
session_uuidstringThe session that was recorded.
recording_urlstringURL to download the recording.
durationnumberRecording duration.
command_uidstringThe command_uid from the original record/start command.

The recording_url emitted by the gateway is not stable indefinitely. Applications that need long-lived audio must download and store the WAV themselves within the retention window.

Validity start. The URL is guaranteed-fetchable from the moment the recording.completed webhook fires. Consumers should not attempt to fetch via the URL before that event; in-progress streaming is exposed via GET /api/v1/sessions/{uuid}/recording/file.wav instead.

Default retention — 24 hours from recording stop. The timer starts when recording stops (the same moment recording.completed is emitted), not from recording start and not from last access. Retention is configurable operator-side via the RECORDING_RETENTION_HOURS environment variable on the wavstream service; the deployed default is 24 hours.

Playback does not extend retention. A GET on the recording URL is read-only. There is no sliding expiry; the 24 hours are counted from stop time regardless of how many times the URL is fetched.

Post-expiry behaviour: 404 Not Found. After the retention window, the URL returns HTTP 404. No Location header, no redirect, no structured error body — the resource is simply gone. Clients must treat a 404 from a previously-valid recording_url as “expired, not available” and not retry.

Operator-managed backends override the default. If the operator points the server-side RECORDING_BASE_URL at an external store (S3, a CDN, or any other backend), retention is governed by that store’s lifecycle policy — not by the 24-hour default. In that configuration the gateway makes no TTL guarantee; consult the operator’s storage policy.

Longer-lived audio is the consumer’s responsibility. To retain audio beyond the gateway’s guarantee, download the WAV inside the retention window and persist it in application-controlled storage. Any URL stored by a consumer and dereferenced later is subject to the rules above; schedulers, retry queues, and archival flows must assume URLs may return 404 after 24 hours.

StatusCondition
400Invalid command_uid format.
401Missing or invalid X-API-Key.
403Session belongs to a different application.
404Session not found.
429Rate limit exceeded (global or per-command cooldown).
503WAVSTREAM_URL not configured on the server (for record/start only).