Access from your server
Create a Live project and a server API key in Console. Select the permissions your server needs:
History is restricted to the key’s project and organization. A key from another
project cannot retrieve a record, even within the same organization. Browser
session tokens and upload capabilities cannot read history. Reads of existing
artifacts do not open inference sessions or consume translation minutes; they
remain available when the key’s speech spending allowance is exhausted.
Opening the WebSocket does not automatically archive or record a call. Obtain
the participants’ agreement and opt in explicitly. For transcript-only storage,
choose
capture_format: "none".
Create the archive
id alongside your product’s conversation ID. The response
includes call_url, upload_url, complete_url, upload_capability,
upload_until and capture limits. Keep the write capability on your server;
it is bound to this one archive and expires after 20 minutes. Creation is not
automatically retried: retain the successful response before proceeding.
The initial hosted archive supports 10 minutes, 2,000 events and 38,400,044
bytes per party file, with a default allowance of 50 archives/project/day.
These are archive limits, separate from live speech concurrency and your
calling platform’s limits. Use your own transcript/audio storage when your
capture exceeds them; this API does not stitch multiple archives into a long
call or establish ten-call recording capacity.
Feed the original and translated ledgers
Your bridge’s durablerecord callback receives source and translated events.
Retain source_context_id, source/target participants and epochs, character
offsets, playback/cancellation events and transfer revisions. Source contexts
associate the two text ledgers; they do not establish word alignment.
Save a transcript checkpoint before uploading audio:
audio_failed: true so the archive remains
incomplete. A saved transcript can be read before audio is ready.
Upload what each party said and was sent
Forparty-v1, upload two stereo PCM16 WAV files at 16 kHz:
Use the post-echo-validation source audio and the transport’s paced output tap.
Audio must never be fed back into recognition for recording. Sent audio is not
proof that a listener heard it; use the event ledger’s playback receipts and
cancellation boundaries when displaying delivery status.
429 using Retry-After.
Then send the complete event ledger to complete_url without audio_pending.
For capture_format: "none", skip the audio uploads and finalize the ledger.
A repeated finalization preserves an already-ready archive.
Use @pyai/sdk 0.9.3 or later for the translation helpers.
The InterpretationRecording helper in @pyai/twilio 0.4.10 or later performs transcript
checkpointing, bounded per-party capture and sequential uploads. Wire
recording.event(event) into the room’s durable event callback,
recording.capture(kind, leg, pcm) into observeAudio, and await
recording.finish() after the room closes. Keep your application’s call
termination and transfer controls in the calling-platform integration.
Retrieve artifacts in your product
Range, Content-Range, content type and 206 responses.
Never put a live API key in an audio element, query string or public download
link. 409 means audio is not ready or was not recorded; 416 means an invalid
byte range. Incomplete/expired uploads remain visible in history instead of
appearing as complete recordings.
These archives contain artifacts submitted by your bridge. They are not an
authoritative carrier record, usage ledger or proof of acoustic echo quality.
Retain the interpretation request/session ID in the events and reconcile billing
through Usage and metering. There is no call-history
webhook in this interface; poll history or notify your product after archive
finalization succeeds.