A room is where participants meet for a video or audio call. Two people are in the same call because their tokens are for the same room.
Your backend creates the room and makes tokens for it. Your app joins it:
Project → API key → backend creates a room and mints a token → app joins the room.
When to create a room
Pick the pattern that matches your app:
| Your app | Room pattern | Example name |
|---|---|---|
| Scheduled meetings or appointments | One room per meeting. | appointment-8812 |
| Support calls | One room per ticket or call. | ticket-4471 |
| A team's always-open "drop-in" call | One long-lived room per team. | team-design |
| A quick demo or test | One fixed room. | demo-room |
Use a name that comes from your own data (a meeting id, a ticket id). Then every participant's backend call finds the same room.
A room is a record, not a server
Creating a room is cheap. It doesn't start anything:
- Creating a room just saves a record. No server starts.
- A media server is assigned when the first person joins.
- It's released when the last person leaves.
- Closing the room sets its status to
CLOSED. Everyone still in the call is disconnected, and no one can join again. The record is kept for history.
On your backend, close a room when the meeting is over:
await livqeno.rooms.delete(roomId); // status → CLOSEDId and name
| Field | What it is |
|---|---|
id | A UUID that Livqeno picks. |
name | Your name for it. Unique in the project and environment. |
Make tokens with the room's id. When joining, the SDK accepts either the id or the name, because the token holds both.
On your backend, create the room, then make a token for it:
const room = await livqeno.rooms.create({ name: 'support-room' });
await livqeno.tokens.create({ room: room.id, identity: 'alice' });If several users' requests may create the same room at the same moment (the
usual case: everyone clicks "Join" at once), pass getOrCreate: true. The
second caller then gets the existing room instead of a 409. See the
Quickstart.
End-to-end encryption
Create a room with e2ee: true to encrypt its media end to end:
const room = await livqeno.rooms.create({ name: 'board-meeting', e2ee: true });The keys stay in your users' apps. Livqeno's servers forward the media but
can't read it. The setting is fixed when the room is created. Tokens for the
room say e2ee: true, room.joined does too, and the SDKs refuse to publish
unencrypted media into it.
Server-side features that need to see the media don't work in an E2EE room:
HLS, recording, restreaming, ingest and transcription fail with
E2EE_NOT_SUPPORTED. With getOrCreate, asking for a different e2ee value
than an existing room has is a 409 rather than a silent switch.
How many people fit
50 participants per room by default (SIGNALING_MAX_PARTICIPANTS_PER_ROOM).
The next person to join gets ROOM_FULL. For one host and many watchers,
use a live stream instead.
Who's in the room right now
On your backend, ask who is connected (for example, to show "3 people in this call" on a meeting list):
const participants = await livqeno.rooms.participants.list(roomId);
// null means the media server could not be reached — different from "empty"| Result | Meaning |
|---|---|
[] | The room is empty. |
null | Livqeno couldn't reach the media server. Not the same as empty. |
Next steps
- Participant and Track: what's inside a room once people join.
- Rooms & participants: joining and leaving from your app.
- RTC API: every room endpoint for your backend.