Guides
Recording
Record a whole call on our media servers — screen shares included, whoever leaves — and get a webhook with a download link the moment it’s ready.
Turn it on
With the call UI, recording is on as soon as three things are true:
- Your backend has the recording routes — the catch-all route forwards all of them.
- The person may record: moderators always may, anyone else when your token route returns
permissions: { record: true }. - You didn’t pass
recordings: falsetocreateFetchBackend.
Everyone in the call then sees a red Recording pill while it runs, and past recordings are listed in the call’s Recordings panel (turn that off with recordingsList={false} if you list them elsewhere). To be told when each one is ready, add a webhook.
How a recording is made
Your server only starts and stops a recording. Nobody’s browser records or uploads anything.
When someone presses record, our media server joins the call as a hidden participant and records it. It keeps going until someone stops it or the room closes — whoever leaves, including whoever started it. Once it stops, we compress the file to keep it small; when that’s done — usually within a few minutes — it’s ready, and your webhook receives recording.ready with links to view and download it.
| Status | Means |
|---|---|
waiting | Every recorder was busy. It starts on its own as soon as one has room — usually within a few minutes — and becomes recording. Stopping it now cancels it (aborted). |
recording | Running now. The room can’t start a second one. |
processing | Stopped; the file is being written, then compressed. Usually a few minutes; longer after a long call or at busy times. |
ready | The file can be played and downloaded. |
failed | Nothing usable was recorded. Your webhook receives recording.failed. |
aborted | Someone threw it away. Nothing is kept. |
What’s in the file
- Everyone’s audio, mixed — including a shared tab’s sound.
- The picture: a screen share takes the frame whenever someone is sharing; otherwise whoever is talking is shown large, with everyone else beside them.
- The whiteboard, while a moderator has it open in the call UI: it takes the frame like a screen share, as that moderator sees it — the drawing itself, their laser pointer and their cursor. Closing it gives the frame back. A moderator who shares their screen as well is recorded on whichever they went to last — the same as everyone in the call sees: going back to the whiteboard (opening it, or Present on their tablet) presents it and brings the recording with it, and closing it or stopping presenting moves both back to the screen.
- MP4 (H.264 and AAC) at 720p, 15 frames a second — plays and seeks in every browser and player. It’s recorded at about 230 MB an hour, then compressed again after the call: a call that’s mostly faces and slides usually ends up a fraction of that. Calls with a lot of movement — scrolling, a video shared on screen — stay closer to the recorded size.
- Or, with
audioOnly: true, an Ogg/Opus sound file of about 20 MB an hour.
Show chat, Q&A and more
A recording can also show what happened in the call besides the pictures and voices: chat messages, questions, polls, reactions and raised hands. Each part is switched on its own, and each is drawn over the picture only while it matters — a message for a few seconds as it arrives, a question while it’s being answered — so the call itself stays in view. They’re drawn in InlineMeet’s colours unless the room’s template gives them yours. Try it:
PATCH /v1/rooms/algebra-101
{
"recordingActivity": {
"chat": true,
"qna": true,
"polls": true,
"reactions": true,
"hands": true
}
}| Part | In the recording |
|---|---|
chat | Each message pops up bottom left as it arrives and fades after about 8 seconds — up to 12 for a long one. At most three show at once; a fourth sends the oldest on its way. A host’s messages are highlighted. |
qna | A new question pops up like a message. While a host is answering one, it stays along the bottom — with who asked and its upvotes — until they mark it answered. |
polls | While a poll is open, its question and options stay along the bottom. Once a host shares the results, they show for 15 seconds, with a quiz’s right answer marked. |
reactions | Emoji float up the right edge with the sender’s first name, as they do in the call. |
hands | A chip in the top left: who has a hand up, in the order they went up. |
Turn it on
Set recordingActivity when you create the room, or any time after — it’s a room setting like autoRecord. true shows chat, Q&A, polls and reactions; false shows nothing; an object changes only the parts it names.
curl -X PATCH https://api.inlinemeet.com/v1/rooms/algebra-101 \
-H "Authorization: Bearer $INLINEMEET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"recordingActivity": {"chat": true, "qna": true, "polls": true, "reactions": true, "hands": false}}'Hosts can change it during the call too, from the call UI’s Settings tab, under Show activity in the recording — and when starting a meeting at /meet. A change shows in the recording from that moment on.
- Only what everyone in the call could see. Poll answers go to whoever asked, so a poll shows its question, and its results only if they’re shared.
- Joining late is fine. A recording started part-way through still knows the questions already asked and a poll already open, so it can show them when they come up.
- Sound-only recordings (
audioOnly: true) have no picture, so nothing is drawn.
Know when it’s ready
Set a webhook on the dashboard’s Settings page, and we’ll POST to it when each recording is ready — or failed. The event carries the recording and two links, valid for 24 hours: view plays it in a browser, download saves it.
{
"id": "evt_9f2c41d07a6b3e8c15d2a0f4",
"type": "recording.ready",
"createdAt": "2026-09-24T14:47:46.120Z",
"data": {
"recording": {
"id": "66f1c0a4e1b2c3d4e5f60718",
"roomCode": "algebra-101",
"status": "ready",
"hasVideo": true,
"mimeType": "video/mp4",
"startedBy": "teacher-12",
"startedByName": "Alex Morgan",
"startedAt": "2026-09-24T14:00:03.000Z",
"endedAt": "2026-09-24T14:47:40.000Z",
"durationSec": 2857,
"sizeBytes": 123731968,
"labels": { "courseId": "alg-1", "lessonId": "week-3" }
},
"links": {
"view": "https://…/66f1c0a4e1b2c3d4e5f60718.mp4?X-Amz-Expires=86400&…",
"download": "https://…/66f1c0a4e1b2c3d4e5f60718.mp4?response-content-disposition=attachment…",
"expiresAt": "2026-09-25T14:47:46.000Z"
}
}
}Copy the file to your own storage from download if you want to keep it, or store the recording’s id and ask for a fresh link each time someone presses play. Don’t store the links themselves: they expire. Webhooks covers verifying the signature and retries.
No webhook? Poll GET /v1/rooms/:code/recordings, or GET /v1/recordings?status=ready, until the recording is ready.
Label recordings
Attach your own ids as labels — up to 20 string pairs — so a recording can be found from your side. They come back in every webhook, too. Set them when recording starts (your route can add them, as it adds startedBy), or any time after:
curl -X PATCH https://api.inlinemeet.com/v1/rooms/algebra-101/recordings/66f1c0a4e1b2c3d4e5f60718 \
-H "Authorization: Bearer $INLINEMEET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"labels": {"courseId": "alg-1", "lessonId": "week-3"}}'Labels merge into what’s there; an empty value removes a key. Keys are letters, digits, - or _, up to 40 characters; values up to 200.
List them anywhere
Every recording in your workspace, newest first, across all rooms — including rooms that have since been closed. Filter by label to show a lesson’s recordings on the lesson page:
curl "https://api.inlinemeet.com/v1/recordings?label.courseId=alg-1&status=ready" \
-H "Authorization: Bearer $INLINEMEET_API_KEY"| Query | Description |
|---|---|
roomstring, repeatable | Only these rooms: ?room=a&room=b. |
label.<key>string | Recordings whose label <key> has this value. Combine several. |
statusstring | waiting, recording, processing, ready, failed or aborted. |
limitnumber | Up to 500. Default 200. |
{ "recordings": [{
"id": "66f1c0a4e1b2c3d4e5f60718",
"roomCode": "algebra-101",
"status": "ready",
"hasVideo": true,
"mimeType": "video/mp4",
"startedBy": "teacher-12",
"startedByName": "Alex Morgan",
"startedAt": "2026-09-24T14:00:03.000Z",
"endedAt": "2026-09-24T14:47:40.000Z",
"durationSec": 2857,
"sizeBytes": 123731968,
"labels": { "courseId": "alg-1", "lessonId": "week-3" }
}] }Play and download
Returns a link that plays the file in the browser for the next 15 minutes; add ?download=1 for one that saves it instead. Fetch it when someone presses play, rather than storing it. Asking before the recording is ready returns 409 recording_not_ready.
{
"url": "https://…/recordings/…/66f1c0a4e1b2c3d4e5f60718.mp4?X-Amz-Expires=900&…",
"expiresAt": "2026-09-24T15:02:40.000Z",
"mimeType": "video/mp4",
"sizeBytes": 123731968,
"durationSec": 2857
}Share with a link
On the dashboard’s Recordings page, Share on a recording makes a link anyone can watch it with — no account needed, so you can send it to people outside your workspace. They watch it on a page of its own, under your workspace’s name and brand; there’s no download button there. Signed-in members of the workspace who could see the recording on their dashboard get a Download button on the same page.
- The link is long and random, so it can’t be guessed, and it isn’t listed anywhere or shown to search engines.
- Stop sharing turns it off at once, for everyone who has it. Sharing again makes a new link; the old one stays dead. Deleting the recording ends its link too.
- The dashboard shows which recordings are shared, and how many times each link has been opened.
- A link is for watching, not downloading — but anyone who can watch a video can record their own screen. Share recordings you’re happy for those people to see.
Delete
Deletes the file and its record, for good — stopping it first if it’s still running. Closing a room never deletes its recordings; only this does.
Recording from your own client
Building your own call screen, or recording from your server on a schedule? It’s two calls, each made from your server so the key stays private.
1. Start
| Body | Description |
|---|---|
audioOnlyboolean | Record sound only — a much smaller file. Default false. |
startedBystring | Your id for who started it. Take it from your session, not the browser. |
startedByNamestring | Their display name, shown on the recording pill. |
labelsobject | Up to 20 string pairs of your own. |
Returns 201 and { recordingId, status: "recording" }. Someone has to be in the call: an empty room gets 409 room_not_live. Only one recording runs in a room at a time, so a second start gets 409 recording_in_progress. If every recorder is busy, you get 202 and { recordingId, status: "waiting" }: more recording capacity is being added, and the recording starts on its own as soon as there is room — there’s no need to ask again (doing so returns the same recording). Everyone in the call sees that it is about to start. If it can’t start within half an hour, or everyone leaves first, it fails and your webhook receives recording.failed.
2. Stop — or abort
Returns the recording, now processing; it becomes ready once the file is written and compressed. Stopping twice is harmless. Anyone your server allows can stop it — not only whoever started it. POST …/recordings/:id/abort stops it and throws it away instead, with no webhook.
You don’t have to stop it at all: a recording also ends when the call does, whether everyone left, a moderator ended it for everyone (POST /v1/rooms/:code/end) or you closed the room with DELETE /v1/rooms/:code. Either way it’s kept.
Good to know
- It records the call, not one person’s view of it. Nobody’s connection or laptop affects the recording, and closing a tab doesn’t stop it.
- Anyone who may record can stop a recording, including one someone else started — the call UI shows them the stop button.
- Storage: Pro includes 20 GB and Business 100 GB; beyond that it’s $0.05 per GB a month, counted by the day. An hour of video is at most about 0.23 GB, usually much less once compressed. Deleting a recording stops it counting.
- Recorded before server-side recording? Older recordings are WebM files made in the recorder’s browser. They play and download exactly as before.
Recording laws vary: in many places everyone in a call must know it’s being recorded. The call UI shows the recording pill to everyone for as long as it runs, and recordingNotice lets you tell the recorder more.