Retrieve Recordings
Once a bot leaves a meeting and processing completes, every artifact is one GET away. All download links are presigned S3 URLs: no extra auth needed, but they expire, so fetch fresh links rather than storing them.
Mixed audio
The link is valid for 1 hour. Mixed audio is always produced, even when per-participant streams are enabled.
Video
The response carries the presigned video_url (valid 1 hour) plus a video_info block with duration, size, resolution, fps, and processing stats, useful for sanity-checking a recording before you pipe it downstream.
Send "video_required": false on create_bot for an audio-only bot. The API defaults this field to true, so an omitted field records video. Audio-only bots skip video capture entirely, which reduces bandwidth and processing time, and it is the right default for transcription-first products. When you do want video, add "recording_config": {"video_layout": "speaker_view"} so the recording follows the active speaker instead of the default grid_view mosaic.
Per-participant streams
With audio_separate_streams / video_separate_streams enabled at create time. Both are opt-in and off unless you set them, and per-participant video in particular multiplies processing and storage by the number of participants:
Full capture details, platform isolation levels, and segment semantics: per-participant audio and video.
Handling 202 (still processing)
Media endpoints return HTTP 202 while the bot is still in the meeting or post-call processing is running, per-participant video responses include a stage field showing where the pipeline is. Poll again after 10–30 seconds, or skip polling entirely by acting on the audio.processed / video.processed webhook events.
Lifetimes cheat sheet
Expired link? Just call the endpoint again. Retention and deletion behavior: Usage & Retention. Want recordings written straight into your own bucket instead? Configure custom object storage in the dashboard.
