Record a room to S3 and get a VOD
Start a recording with one call, let egress and the upload job do the rest, and end up with a playable VOD in your own bucket. Including split parts and snapshots.
From live room to VOD in three moves
Recording in StreamHub is a fire-and-forget operation: you start it, and a background pipeline turns the live room into an uploaded, indexed VOD in your app's S3 bucket.
Make sure the app has S3 configured first (see the per-app S3 guide), then:
Start the recording
curl -s -X POST $BASE/apps/live/recording/start \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"roomName":"studio"}'
You get back a recording handle:
{ "data": { "vodId": 12, "egressId": "EG_xxx", "status": "recording" } }
Behind the scenes LiveKit egress starts writing a local MP4 and a VOD row is inserted with status=recording. The recording_started webhook fires.
Let the pipeline finish it
You do not poll or babysit. When egress ends:
- the file's status moves to
uploadingand an upload job is enqueued, - the job uploads to the app's S3, builds a public/presigned URL, generates a snapshot, and deletes the local file,
- status becomes
ready, metadata (duration, resolution, codec) is saved, andvod_readyfires.
If the upload fails, the local file is kept and recording_failed fires — nothing is lost silently.
Recording an already-live stream
If a stream is already publishing, record it in place by stream id:
curl -s -X POST $BASE/apps/live/streams/<id>/record/start \
-H "Authorization: Bearer $TOKEN"
Stop either kind with recording/:id/stop.
Split parts and snapshots
The output shape comes from the app config, not the request:
split_minutes> 0 cuts the recording every N minutes — each part becomes its own VOD, perfect for 24/7 cameras. Allowed values include 15, 30, 60, 90, 120.snapshot_seconds> 0 grabs a periodic JPEG thumbnail during the recording.
You can also grab a one-off frame any time:
curl -s -X POST $BASE/apps/live/snapshots \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"room":"studio"}'
Watch the VOD
Once status=ready, the VOD has a playable URL (presigned or public depending on your config), served by the video.js VOD player. Because recordings honor max_recording_minutes_month, you can cap spend per tenant while still recording everything that matters.