Welcome to the new Daily Docs. Please let us know what you think.

Recording calls with the Daily API

A notification to start recording a call appears on top of the call participants in Daily Prebuilt

There are multiple ways to record calls of up to three hours with the Daily API. This guide walks through the different options, including why and how to use each recording type:

It also covers how to transcode the .webm files returned by most of the recording types, and recommends best practices for recording calls with Daily.

  • For costs associated with each recording type, please see our pricing page.
  • To learn how to manage your recordings with the Daily /recordings endpoint, head to our reference docs.

Daily recording types

The cloud-beta recording type records a Daily call server-side. By default, "cloud-beta" outputs video at 1920x1080, 20 fps encoded as H.264 at 5 Mbps, and audio encoded as AAC at 96 kbps, in the MP4 container format. The .mp4 files can be retrieved via the Daily REST API, or from the Daily dashboard. Recordings are stored in the Daily cloud until the Daily account holder deletes them.

With cloud-beta recording, it's possible to configure the layout of the recording.

Cloud-beta is the best choice if your users need to record from any browser or device, or if you want control over the look and feel of the recording output. Cloud-beta recordings are also conveniently available for download from the Daily dashboard.

Turn on cloud-beta recording

To allow any participant in a room to start a cloud-beta recording, set the enable_recording property to "cloud-beta" at the room level.

This can be done through an API request:

If instead of the whole room, only select participants should be able to start a recording, set the enable_recording property to "cloud-beta" on those participants’ meeting tokens.

Once cloud-beta recording is enabled, you can call the daily-js methods startRecording(), updateRecording() and stopRecording() in your app to manage the recording process.

Customize cloud-beta recording layouts

You can pass configuration properties to either startRecording() or updateRecording() to control the look and feel of the final output.

The options currently include:

  • height, width: Controls the resolution of the recording.
  • backgroundColor: Specifies the background color of the recording.
  • layout: an object specifying the way participants’ videos are laid out in the recording. A preset key with one of the following values must be provided:
    • "default": This is the default grid layout, which renders participants in a grid, or in a vertical grid to the right, if a screen share is enabled. Optionally, a max_cam_streams integer key can be provided to specify how many cameras to include in the grid. The default value is 9, which is also the maximum number of cameras in a grid. The maximum may be increased at a later date.

Example "default" layout:

Grid of nine participants on a video call

Example screenshare "default" layout:

A screenshare takes up the main video call screen with participant videos to the right vertically

  • "single-participant": Use this layout to limit the audio and video to be streamed to a specific participant. The selected participant’s session ID must be specified via a session_id key.

Example "single-participant" layout:

One participant video screen takes up the entire video call

  • "active-participant": This layout focuses on the current speaker, and places up to 9 other cameras to the right in a vertical grid in the order in which they last spoke.

Example "active-participant" layout:

One participant video screen takes up the majority of space on a call with two others to the right in a small vertical bar

  • "portrait": Allows for mobile-friendly layouts. The video will be forced into portrait mode, where up to 2 participants will be shown. An additional variant key may be specified. Valid values are "vertical" for a vertical grid layout (the default), and "inset" for having one participant's video take up the entire screen and the other inset in a smaller rectangle. Participants' videos are scaled and cropped to fit the entire available space. Participants with the is_owner flag are shown lower in the grid (vertical variant), or full screen (inset variant).

Example "portrait" layout with "vertical" variant:

Two participant screens on a mobile vertical video call

Example "portrait" layout with "inset" variant:

Two participant screens on a mobile vertical video call

Retrieve cloud-beta recordings

You can retrieve all your completed cloud-beta recordings from the Daily dashboard "Recordings" tab.

Download links and share tokens for cloud-beta recordings

Please note that our cloud-beta recording storage is intended for archiving, not for streaming.

For convenience in scripts, or if your use case absolutely requires a long-lived download link, you can also use the recording object's share_token to download the file. Use cases with this requirement are rare, and generally aren't a good fit for the engineering and cost trade-offs we've made with regard to how recordings are encoded and stored. If you have questions about this please contact us.

  1. Send a GET request to /recordings to find the recording id:
  1. Find the share_token in the response object nested under the id.

  2. Once you have the share_token, visit this URL in your browser, filling in the share_token placeholder: https://api.daily.co/v1/recordings/share_token/download

You can also create a time-limited access link for the recording.

Using cloud-beta recording with Daily Prebuilt

For rooms where cloud-beta recording is enabled, end users can start their own recordings using the "Record" button. When a recording is started, a layout is automatically selected for the user based on their current layout:

If "Grid view" is selected, then a preset of "default" is used If "Speaker view" is selected, then a preset of "active-speaker" is used

For programmatic control over recording and additional layout presets, use the startRecording() and updateRecording() methods.

For the best user experience when using a single-participant recording, use a meeting token for the recorded user where the enable_recording property is set to "cloud-beta". This will ensure that only the recorded participant sees the recording UI.

"cloud" recording will soon be deprecated in favor of "cloud-beta".

The cloud recording type records calls client-side, and then uploads the resulting .webm files to Daiy servers.

Turn on cloud recording

To allow any call participant to start a recording, set the enable_recording property to "cloud" at the room level. This can be done either through the Daily API or from the dashboard.

To create a room with "cloud" recording enabled from the dashboard:

  1. Open the "Rooms" tab and click the "Create Room" button.

  2. Select "Cloud recording".

  3. Click "Create room".

Arrow points to Recording option on the Daily dashboard create room page

If only select participants should be able to start a recording, set the enable_recording property to "cloud" on those participants’ meeting tokens.

Once cloud recording is enabled, you can call the daily-js methods startRecording() and stopRecording() in your app to manage the recording process.

Retrieve cloud recordings

You can retrieve all your completed cloud recordings from the Daily dashboard "Recordings" tab.

Download links and share tokens for cloud recordings

Please note that our cloud recording storage is intended for archiving, not for streaming.

For convenience in scripts, or if your use case absolutely requires a long-lived download link, you can also use the recording object's share_token to download the file. Use cases with this requirement are rare, and generally aren't a good fit for the engineering and cost trade-offs we've made with regard to how recordings are encoded and stored. If you have questions about this please contact us.

  1. Send a GET request to /recordings to find the recording id:
  1. Find the share_token in the response object nested under the id.

  2. Once you have the share_token, visit this URL in your browser, filling in the share_token placeholder: https://api.daily.co/v1/recordings/share_token/download

You can also create a time-limited access link for the recording.

Because local recording happens on a participant's own device and relies on local compositing, the final recording quality will be subject to browser and device limitations.

The participant recording the call must also be using Chrome on desktop.

Please refer to our best practices for guidelines on ensuring a smooth user experience.

Local recording saves the finished recording as a .webm file on the participant's computer. The file may need to be transcoded in order to compress the size and to be played back on most devices.

Use this recording type if you would like to access recordings directly on a participant’s computer, instead of via the Daily cloud. Local recording is also HIPAA-friendly.

Turn on local recording

To allow any call participant to start a recording, set the enable_recording property to "local" at the room level. This can be done either through the Daily API or from the dashboard.

To create a room with "local" recording enabled from the dashboard:

  1. Open the "Rooms" tab and click the "Create Room" button.

  2. Select "Local recording".

  3. Click "Create room".

Arrow points to Recording option on the Daily dashboard create room page

If only select participants should be able to start a recording, set the enable_recording property to "local" on those participants’ meeting tokens.

Once local recording is enabled, you can call the daily-js methods startRecording() and stopRecording() in your app to manage the recording process.

Retrieve local recordings

Local recordings will be immediately downloaded to the computer of the participant who stops the recording.

Using local recording with Daily Prebuilt

If you're using local recording with Daily Prebuilt, be sure to tell the participant who clicked "Start" recording to click "Stop" before they leave the call.

If the participant who started a recording leaves the room without stopping it, then the recording will be lost. Daily Prebuilt attempts to warn the user before they leave to avoid losing any recordings.

rtp-tracks captures each individual media track from a call separately. It stores them in Daily’s cloud servers as .webm files. The tracks can then be downloaded and combined into a final output file. Recordings are stored until you delete them.

If you need to manage individual media tracks separately, use this recording type. This is often useful for high-quality audio transcription and media production, like for podcasts or video blogs.

With rtp-tracks, tracks must be downloaded individually via the Daily REST API, and combined using third-party tools. If you don’t need to do that, we recommend another recording type (like cloud-beta).

Turn on rtp-tracks recording

To allow any call participant to start a recording, set enable_recording to "rtp-tracks" at the room level through a POST request to the Daily /rooms endpoint.

If only a specific participant or participants should be able to start a recording, set enable_recording to "rtp-tracks" at the meeting token level, with a POST request to the Daily /tokens endpoint.

Once rtp-tracks is enabled, you can call the daily-js methods startRecording() and stopRecording() in your app to manage the recording.

About rtp-tracks tracks

During an rtp-tracks recording, multiple files are saved for each individual track. An individual track refers to the audio and video data from a participant’s camera or screen share.

The following information for each track is available using the API:

  • Track ID
  • Download URL (used for retrieving the track)
  • File size, in bytes
  • Start and End Unix timestamps
  • Duration of the track, in seconds
  • Resolution (for video tracks)
  • Session ID
  • Media tag, indicating whether the audio or video track was from a camera or screen share
  • Track type, either video or audio
  • Owner, user name, and user id status for the user that generated the track

For example, here is a JSON-formatted response that the API returns for a single track:

Retrieve individual tracks from rtp-tracks recordings

You must use the Daily API to retrieve track information and download individual tracks from rtp-tracks recordings.

  1. Find the recording id. You can listen for recording events, or send a GET request to /recordings:

Once you have the id, you can also send another GET request to /recordings/:id to isolate the specific recording’s response object:

  1. Locate the recording_id’s "tracks" array. "tracks" contains all track information for the recording, including id’s for each individual track.

Using any of the track id's in the "tracks" array, you can send a GET to /recordings/:id/track/:id for more information about that specific track:

  1. Find the download_url for the track_id. The url specifies a relative path to the Daily REST API base URL (api.daily.co), and will look like: /v1/recordings/RECORDING_ID/track/TRACK_ID.webm

  2. Request the download_url from the Daily API.

In this example, we include the "location" argument -L to save the track in a new file.

Once downloaded, the file may need to be transcoded in order to compress the size and to be played back on most devices.

Create composited .mp4 files from rtp-tracks recordings using the Daily API

  1. Create a json data structure that describes which tracks to include in a composited video and how to size and position the video tracks, using information about the rtp-tracks recording’s tracks (found in the "tracks" array).

Here's an example json "recipe":

The recipe's required fields:

  • "composite_mode" must be set to "tracks-layout"
  • "size" is the size (resolution) of the video you are creating. It must be a string in the format "WIDTHxHEIGHT"
  • "tracks" is a list of tracks to include in the video. For audio tracks, just list the track id. Video tracks require an id, size, and position.
    • "size" is the size, in pixels, to scale the video track to. You'll need to use the resolution values from the video's track_id object in the recording's "tracks" array to make sure you give a size that doesn't distort the video's aspect ratio.
    • "position" is an X and Y coordinate indicating where to place the video track within the overall video canvas. Specify this as the top, left corner of this track, relative to the top/left of the canvas.

The recipe's optional fields:

  • "title" is the new video's "title" metadata
  • "duration" specifies how many seconds the video should be. This is useful for doing quick trial-runs of recipes.
  • "background_color" sets the background color to something other than the default black (explore color options).
  1. POST the recipe to the /recordings/:id/composites endpoint

The API returns a status and composite video id:

One composite allowed per room

Please note that you are allowed to have only one compositing process happening at a time for each room.

If you try to start another compositing process for the room, without letting the previous one finish, you'll receive an error response.

The compositing happens faster than real-time, but can still take several minutes per video.

Also, we only save one composited video per room. If you run the compositing process again, your new video will overwrite the previous one.

  1. Retrieve the final results from a GET to /recordings/:recording_id/composites

The API will return a JSON object with the final result, for example:

Using rtp-tracks recording with Daily Prebuilt

Daily Prebuilt does not show recording controls for rtp-tracks recording. Instead, you’ll need to build your own recording controls using Daily recording events.

output-byte-stream records byte-level data locally.

Use this recording type if you want fine-grained control over local recordings. output-byte-stream is also HIPAA-friendly.

Because output-byte-stream recording relies on local compositing, the final recording quality will be subject to browser and device limitations.

The participant recording the call must also be using Chrome on desktop.

Please refer to our best practices for guidelines on ensuring a smooth user experience.

Turn on output-byte-stream recording

To allow any call participant to start a recording, set enable_recording to "output-byte-stream" at the room level.

If only a specific participant or participants should be able to start a recording, set enable_recording to "output-byte-stream" on those participants' meeting tokens.

Once output-byte-stream recording is enabled, you can call the daily-js methods startRecording() and stopRecording() in your app to manage the recording process.

Retrieve output-byte-stream recordings

To retrieve output-byte-stream recordings, listen for the recording-data event during Daily calls.

Using output-byte-stream recording with Daily Prebuilt

Daily Prebuilt does not show recording controls for output-byte-stream recording. Instead, you’ll need to build your own recording controls using Daily recording events.

How to transcode .webm files

local, rtp-tracks, and output-byte-stream recording types all return .webm files.

They must be transcoded, converted to .mp4 files, for most use cases.

There are two ways to do so:

  1. CloudConvert: Browser software that offers free and paid plains
  2. Handbrake: A free app for Windows and macOS

Transcode with CloudConvert

  • Sign up at https://www.cloudconvert.com
  • In the gray top bar, select your conversion settings. You probably want 'webm' to 'mp4'. (If you're extracting audio only, convert 'webm' to 'mp3').
  • Click "Select Files". Your webm file needs to be cloud accessible, with Dropbox, Google Drive, Box, etc.
  • At the bottom of your window, select where you want your converted files saved.
  • Click "Start Conversion".

CloudConvert UI show dropdown list of options to convert CloudConvert UI displays button to Start Conversion

Transcode with Handbrake on Windows

  • Download and install Handbrake.
  • Select the video or folder with your videos for encoding. Drag the videos into Handbrake. Or click either "Folder (Batch Scan)" or "File", to browse your computer for video files.
  • Handbrake’s default settings should be fine. However, setting Presets to "Fast 1080p30" and Format to "MP4" will produce a widely accessible transcoded video.

Handbrake UI displays options for the format tracks and filters for transcoding the file

  • Click "Browse" (bottom right corner) to assign a name/location for your transcoded video.
  • Press "Start Encode" to begin transcoding

Transcode with Handbrake on MacOS

  • Download and install Handbrake.
  • Select the video or folder with your videos for encoding. By default when opening Handbrake a window should appear where you can make this selection; however, if this doesn't appear, you can click "Open Source" (top left corner) to browse your computer for video files.
  • Handbrake’s default settings should be fine. However, setting Format to "MP4 File" and Video Encoder to "H.264 (x264)" will produce a widely accessible transcoded video.

Handbrake UI displays options for the format tracks and filters for transcoding the file on mac

  • Click "Browse" (on the right in the "Destination" section of the window) to assign a name/location for your transcoded video.
  • Press "Start" to begin transcoding.

Viewing recordings without transcoding

You also can view .webm files without transcoding in two ways:

  1. Viewing them in your browser with Chrome or Firefox
  2. Or using VLC Media Player, a versatile, open source media player which can be found at: https://www.videolan.org/vlc/index.html

Need more help with transcoding? Contact us.

Best practices for recording calls with Daily

We suggest sharing the following tips across your team, so it can be shared in places like:

  • Onboarding guides
  • In-product links
  • Help center FAQs

Feel free to copy and paste and repurpose any of the below. Please include this in your own material, rather than directing your customers to the Daily site!

Tips for the best recording experience

Use ethernet if possible

If participants will be recording a lot of calls, they should use wired Ethernet connections if available, rather than WiFi. Ethernet reduces network packet loss and makes a big difference for audio and video quality.

Stop the recording before leaving the call

Before the participant who started recording leaves the call, make sure they stop the recording. If they don't, the recording status could become stuck 'in-progress' and the file unable to be retrieved.