Recording

Record a channel to an S3-compatible bucket that belongs to you. We start the recording, compose it, and write it to your storage — and keep no copy, because there is nowhere on AppLooma for one to go.

Note

We do not store your recordings. Not for a retention window, not in a cache, not temporarily. Until you configure a bucket, recording returns an error rather than falling back to storage of ours. A platform that never holds the file cannot lose it, be compelled to produce it, or charge you for keeping it.

Point a project at your bucket#

In the dashboard, open the project and add a destination. Anything S3-compatible works — AWS S3, Cloudflare R2, Backblaze B2, MinIO, or your own server.

FieldNotes
bucketThe bucket name.
endpointRequired for anything other than AWS S3 — R2 and B2 both need one.
regionDefaults to auto, which is right for R2.
accessKeyA key with permission to write to that bucket, and nothing more.
secretKeyEncrypted at rest. Shown back to you only as its last four characters.
prefixA folder inside the bucket. Defaults to applooma/.

Note

Give the key write access to one bucket and nothing else. We need to put objects there; we never need to read, list or delete them.

Start and stop#

Both are server-side calls with your API key, so a viewer cannot start a recording of a room they are in.

Start
const res = await fetch('https://api.applooma.dev/v1/recordings/start', {
method: 'POST',
headers: {
'x-applooma-key': process.env.APPLOOMA_API_KEY,
'x-applooma-secret': process.env.APPLOOMA_API_SECRET,
'Content-Type': 'application/json',
},
body: JSON.stringify({ roomName: 'interview-42' }),
});
const { recordingId, destination } = await res.json();
// destination → { bucket: 'my-recordings', key: 'calls/interview-42/1757…mp4' }

Keep destination. It is the only record of where the file went that you will get from us — we do not hold an index of your objects.

Stop
await post('/v1/recordings/' + recordingId + '/stop');

Note

Someone has to be publishing. A recording captures what is on the air, so a channel where every participant is audience — nobody sending audio or video — never gives it a first frame. Starting returns a recording id all the same, but the file will not be written until a host or cohost publishes, and if none does within the wait the recording ends as failed. If you record from the moment a channel opens, start it once the host has joined and unmuted rather than when the channel is created.

When it will not start

CodeWhat it means
NO_RECORDING_STORAGEThe project has no destination yet. Add one in the dashboard.
RECORDING_NOT_AVAILABLEThis deployment cannot hold credentials securely. Only relevant if you self-host.
409That channel is already being recorded.

What it costs#

Recording minutes are billed like channel minutes, and appear under Recording in your usage breakdown. There is no storage line, because we are not storing anything — whatever your provider charges for the object is between you and them.

Why it works this way#

Most platforms record to their own storage and rent it back to you. That is simpler to sell and worse to live with: your users' video sits on someone else's infrastructure, under someone else's retention policy, reachable by someone else's subpoena, and priced by someone else.

Writing to your bucket means the recording is yours from the moment it exists. It also means we cannot help you recover one you deleted — which is the honest trade, and the right way round.