Record a Daily.co room to your own S3 bucket

Add server-side recording to a Daily application without a bespoke recording bot fleet.

The pipeline

  1. Daily source
  2. video mixer
  3. audio mixer
  4. S3 segment sink

What this replaces

Build it yourself

  • Create and schedule a recording bot for each call
  • Handle headless browser lifecycle and failures
  • Render the same layout across participant changes
  • Upload long recordings reliably after the call

With AVFlow

  • Provide the Daily room URL and scoped meeting token
  • Submit one Job for the composite and output
  • Write directly to your bucket and path prefix
  • Keep job state in your database through the REST API or webhooks

The validated Job

This is the same file 12-daily-recording.json serves. Replace platform credentials, output URLs, and storage secrets before running it.

12-daily-recording.json Download
{
  "name": "daily-recording",
  "sources": [
    {
      "name": "room_src",
      "type": "daily",
      "config": {
        "roomUrl": "https://your-domain.daily.co/meeting-room",
        "token": "<daily-meeting-token>",
        "select": {
          "mediaTypes": [
            "video",
            "audio"
          ]
        }
      }
    }
  ],
  "nodes": [
    {
      "name": "mix_video",
      "type": "video_mixer",
      "inputs": [
        "room_src"
      ],
      "config": {
        "canvas": {
          "width": 1920,
          "height": 1080,
          "backgroundColor": "#1a1a2e"
        },
        "layout": {
          "mode": "grid",
          "common": {
            "borderRadius": 8
          },
          "grid": {
            "maxColumns": 3,
            "gap": 4,
            "fit": "cover"
          }
        }
      }
    },
    {
      "name": "mix_audio",
      "type": "audio_mixer",
      "inputs": [
        "room_src"
      ],
      "config": {}
    }
  ],
  "sinks": [
    {
      "name": "segment_out",
      "type": "segment",
      "inputs": [
        "mix_video",
        "mix_audio"
      ],
      "config": {
        "storageType": "s3",
        "storageConfig": {
          "bucket": "recordings",
          "region": "us-east-1",
          "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
          "secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
          "pathPrefix": "daily/{jobName}/{date}/",
          "filename": "{jobName}_{timestamp}"
        },
        "encoding": {
          "videoCodec": "h264",
          "audioCodec": "aac"
        }
      }
    }
  ]
}
Submit it API
curl -X POST "https://api.avflow.dev/v1/jobs" \
  -H "Authorization: Bearer $AVFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d @12-daily-recording.json

Know the limits before you ship

  • Private Daily rooms require a meeting token with the necessary join scope.
  • The storage credentials and bucket policy remain under your control.
  • For captions, add an ASR path; the base recording Job only records media.

Run this Daily pipeline

Generate the Job in Playground, then run it with $20 promotional credit.