Recording and VOD
Record live broadcasts, then play them back as HLS or download them with S3 tools.
The commands reuse API, MOQ_API_TOKEN, PID, and KID from the quickstart. The project's Recordings page does the same through the dashboard.
Record broadcasts
A recording rule records every broadcast whose path matches one of its patterns, from the moment it goes live. This records everything under cameras and keeps it for 7 days:
sh
curl --fail-with-body --silent --show-error "$API/projects/$PID/recording/rules" \
-H "Authorization: Bearer $MOQ_API_TOKEN" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: "recording-rule-1"' \
--data '{"label":"Cameras","patterns":["cameras/**"],"retentionDays":7}'Patterns are relative to the project and use the same grammar as tokens. retentionDays is 1, 7, 30, 90, 180, or 365; more than 7 needs a payment method. Set vodEnabled to false to pause a rule without deleting it. The account token needs media:write.
Your own bucket
To keep recordings in an S3-compatible bucket you own, add bucket to the rule with an endpoint, region, bucket name, and a key that can write to it. Your bucket's lifecycle owns retention, and the secret is never returned. Set delivery to true, with a key that can also read, to play recordings back through the CDN.
List recordings
sh
curl --fail-with-body --silent --show-error "$API/projects/$PID/recording/sessions" \
-H "Authorization: Bearer $MOQ_API_TOKEN" | jq '.items[] | {id, broadcastPath, status, durationMs}'A recording is LIVE while its broadcast is, then ENDED. To follow changes, pass the response's sinceCursor back as since. A webhook for recording.ready saves polling.
Play a recording
sh
REC=<recording id>
PLAY=$(curl --fail-with-body --silent --show-error "$API/projects/$PID/recording/sessions/$REC/play" \
-H "Authorization: Bearer $MOQ_API_TOKEN")
URL=$(printf '%s' "$PLAY" | jq -er '.url')
VOD_TOKEN=$(printf '%s' "$PLAY" | jq -er '.token')
ffplay -headers "Authorization: Bearer $VOD_TOKEN" "$URL"url is an HLS playlist, and token grants that recording's playlists and media until expiresAt. Send the token as an Authorization: Bearer header or as the jwt query parameter. Call play again for a fresh one. A recording still LIVE has a growing playlist. The account token needs media:read.
The player is any HLS player. To embed one, give your page the URL and token from your server, never the account token.
Download with S3 tools
Managed recordings are readable through an S3-compatible endpoint, so aws-cli, rclone, and S3 SDKs can list and download them. Fetch the project's credentials once:
sh
S3=$(curl --fail-with-body --silent --show-error "$API/projects/$PID/recording/s3" \
-H "Authorization: Bearer $MOQ_API_TOKEN")The credentials alone read nothing. Each request also needs a media token that subscribes to the broadcasts you want, as the session token. Mint one with subscribe: ["**"] for everything, set S3_TOKEN to it, then:
sh
export AWS_ACCESS_KEY_ID=$(printf '%s' "$S3" | jq -er '.accessKeyId')
export AWS_SECRET_ACCESS_KEY=$(printf '%s' "$S3" | jq -er '.secretAccessKey')
export AWS_SESSION_TOKEN="$S3_TOKEN"
export AWS_REGION=auto
ENDPOINT=$(printf '%s' "$S3" | jq -er '.endpoint')
BUCKET=$(printf '%s' "$S3" | jq -er '.bucket')
aws s3 ls --recursive "s3://$BUCKET/" --endpoint-url "$ENDPOINT"Use path-style addressing; any region signs. Only the project owner can fetch the credentials, and they need keys:write. Recordings in your own bucket are not listed here.
Delete
Delete one recording with DELETE /v1/projects/{pid}/recording/sessions/{id}, or every recording a rule holds with DELETE /v1/projects/{pid}/recording/rules/{id}/sessions. Storage drains in the background and is metered until it is gone. To delete a rule, set its vodEnabled to false and delete its recordings first.
Cost
Recording bills for each GB written and stored, and playback and downloads bill as delivery. Usage and billing lists the meters.