Tried records every call by default, as two files: a mixed recording of the whole call and a dual-channel recording with the agent on its own channel. The call object returns both as signed, expiring URLs. Files are kept for 30 days unless the workspace opts in to longer retention.
| Field | Contents |
|---|---|
recording_url |
Mixed audio of the call |
recording_multi_channel_url |
Two channels: the agent on one, everyone else on the other |
Use the mixed file for listening and the dual-channel file for analysis or your own transcription, where separating the speakers matters.
How recording works#
Real recordings need LiveKit (for egress) and S3-compatible storage: S3_BUCKET, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, optional S3_REGION (default us-east-1), and S3_ENDPOINT with S3_FORCE_PATH_STYLE=1 for R2 or MinIO.
When a call starts, Tried starts two audio-only LiveKit room composite egresses for the call's room: one mixed, one dual-channel. LiveKit uploads the files straight to your bucket. When an egress finishes, the egress_ended webhook stores the file location on the call.
- File type: Ogg by default. Set
RECORDING_FILE_TYPEtomp3ormp4to change it. - Object key:
<S3_PREFIX>/<workspace_id>/<call_id>/mixed.<ext>and.../dual.<ext>.S3_PREFIXdefaults torecordings. - If LiveKit is configured but S3 is not, recording is skipped and a warning is logged.
Mock mode#
Without LiveKit, Tried writes a short generated WAV pair (mixed and two-channel, 2 to 8 seconds) to RECORDINGS_DIR when the call ends, so the dashboard player works with no keys. These files are served by the API at /recordings/:file with an HMAC-signed, expiring link.
Signed URLs#
Stored locations are never returned directly. Each response turns them into signed links:
- S3: SigV4 presigned URLs.
- Local files: HMAC-signed
/recordings/:file?exp=&sig=links.
The lifetime is, in order: expires_in on the request below, the agent's signed_url_expiration_ms (60000 to 604800000, default 24 hours) when the agent has opt_in_signed_url: true, or RECORDING_URL_TTL_S (default 86400 seconds, 24 hours).
Get a fresh link for an older call with:
curl "https://api.tried.com.au/get-call-recording-url/call_5b3c9e...?expires_in=3600" \
-H "Authorization: Bearer $TRIED_API_KEY"{
"call_id": "call_5b3c9e...",
"recording_url": "https://bucket.s3.amazonaws.com/recordings/...&X-Amz-Signature=...",
"recording_multi_channel_url": "https://bucket.s3.amazonaws.com/recordings/...&X-Amz-Signature=..."
}expires_in is in seconds, clamped to 60 to 604800 (7 days).
Listen in the dashboard#
Open a call in Call History. The recording player in the call drawer has a Mixed and a Stereo (dual channel) choice.
Turn recording off#
| Scope | How |
|---|---|
| Whole deployment | RECORDING_ENABLED=0 on the API |
| One agent | data_storage_setting: "basic_attributes_only" on the agent (recordings, transcripts, variables and analysis text are not stored) |
| One call | metadata.disable_recording: true on the call request |
Privacy settings and recordings#
Agent data_storage_setting |
Effect on recordings |
|---|---|
everything (default) |
Kept as recorded. |
everything_except_pii |
After webhooks and analysis run, a 1 kHz beep is written over words detected as PII, using word timestamps. WAV files are edited in place; Ogg and MP3 are decoded, beeped and re-encoded in the same location. |
basic_attributes_only |
Not recorded. |
How long recordings are kept#
Recordings are kept for 30 days after the call ends, then deleted by the daily privacy job. The call, transcript and analysis stay and the recording URLs become null. Keeping recordings for 90 days, 180 days, 1 year or 2 years is opt-in per workspace (Settings, Security, Recording retention, or recording_retention_days) and adds $0.001 per recorded minute for each extra 30 days. See Recording retention.
data_storage_retention_days (1 to 730) on an agent makes the same job delete older calls together with their recordings.
Limits and gotchas#
- One bucket serves every workspace. Per-region recording storage is not built.
- The Twilio setup guide asks you to leave Twilio's own Call Recording disabled, because Tried already records.
- A recording URL in a webhook payload expires like any other signed URL. Store the call ID and fetch a fresh link when you need the audio later.