> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Video meetings and conferences

> Run a multi-party video meeting on Orbit — create a scheduled room from the dashboard or the Video API, share a guest link, and control capacity, recording, and participant permissions.

# Video meetings and conferences

A video meeting on Orbit is a **scheduled room** — a persistent, named room on
the Orbit Media stack that exists before anyone joins and outlives any single
session. A scheduled room is built for groups, not a single peer-to-peer call:
it carries a host, a capacity, a guest link, and an inbox entry, and it
survives a hang-up so people can rejoin or a recording can live on.

Reach for a scheduled room when you want a meeting — a standup, a sales call,
a webinar, a training session — rather than a single peer-to-peer video.

## Two ways to run a meeting

|                             | Dashboard                   | API                                                      |
| --------------------------- | --------------------------- | -------------------------------------------------------- |
| Create a meeting            | **Rooms → New room**        | `POST /video/rooms-scheduled`                            |
| Reuse a fixed meeting place | Save as a **template**      | `POST /video/rooms-scheduled/templates`                  |
| Get guests in               | **Share** the invite link   | `POST /video/rooms-scheduled/:id/invites`                |
| Join yourself               | Open the room               | `POST /video/rooms-scheduled/:id/join` (returns a token) |
| Search your meeting catalog | **Rooms** list search field | `GET /video/rooms-scheduled?keyword=`                    |

The dashboard is the fastest path: open **Rooms**, name the room, optionally
set a time and capacity, and share the invite link. Use the API when the
meeting must be created from your own product or scheduled on a recurrence.

## Create a meeting

Give the room a name — that is the label your guests and your inbox will use.
Set **scheduled\_at** to put it at a time, or leave it unset to start it now.
**max\_participants** caps the room from 2 up to 300; omit it to inherit your
tenant's participant ceiling.

```bash theme={null}
curl -X POST "https://api.orbit.devotel.io/api/v1/video/rooms-scheduled" \
  -H "X-API-Key: dv_live_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Weekly sales sync - Acme",
    "scheduled_at": "2026-06-02T09:00:00Z",
    "max_participants": 25,
    "recording_enabled": true
  }'
```

The response returns the room plus a **host\_token** for the creator, so you
can join right away without a second call. It also creates an inbox
conversation for the room.

<Note>
  A meeting that repeats — a daily standup, a weekly sync — is one scheduled
  room with a **`recurrence_rule`** (an RFC 5545 `RRULE` value) rather than
  separate rooms per occurrence. The calendar invite guests receive then carries
  the full series, so it lands correctly in Gmail, Apple Mail, and Outlook.
</Note>

## Bring people in, at the right permission level

Get a person in one of two ways. For a guest, mint an **invite link** and send
it; they open the link, redeem it, and are placed in the room with no account
and nothing to install. For someone whose meeting you own, call `POST
/video/rooms-scheduled/:id/join` to mint a per-participant token.

Whenever you join a participant, decide their permission tier rather than
assuming everyone is the same. The tier maps to what they may publish and see:

* **host** — full control; mute, spotlight, lock, and remove participants.
* **panelist** — can publish audio, video, and screen share; the working
  default for meeting attendees.
* **viewer** — can watch and hear but publish nothing.
* **hidden\_supervisor** — joins silently for compliance listen-in; publishes
  and is listed nowhere.

The default `role` on a join is `participant`, so a guest cannot promote
themselves to host over the wire — host is only granted explicitly by an
operator or by the room creator's own path.

<ParamField body="participant_tier" type="string" default="panelist">
  Set per joiner. `viewer` is right for an audience, `panelist` for a working
  attendee, and `host` only for a meeting moderator.
</ParamField>

## Capacity and recording behave like a meeting, not a one-off call

`max_participants` is a real participant ceiling (2–300), not a dialer fan-out
limit. Recording decisions are first-class: turn recording on at create with
`recording_enabled`, start and stop it on the live room, and exclude an
individual participant from the artifact if they ask not to be recorded.
Because a join can carry `allow_recording: false`, a participant can opt out
before their media ever lands in an egress.

When an operator needs the meeting to end at a fixed bound, `max_duration_minutes`
opts in a hard auto-end — useful for rooms left open accidentally.

<Warning>
  If a join returns 503 `SERVICE_UNAVAILABLE`, Orbit Media is not configured on
  your cluster — every video meeting endpoint depends on it. Check the cluster
  configuration and retry; do not fall back to the one-to-one voice flow as a
  substitute.
</Warning>

## Search your meeting catalog

Once your tenant accumulates rooms, finding a specific meeting becomes a
lookup problem rather than a creation problem. The rooms list — the same
`GET /video/rooms-scheduled` index the dashboard **Rooms** page renders —
accepts a `keyword` query parameter that filters the returned rooms by
case-insensitive substring match against the room **name** and its
**room\_sid** (the internal room identifier, useful when you have an
Orbit Media-side reference).

```bash theme={null}
curl -G "https://api.orbit.devotel.io/api/v1/video/rooms-scheduled" \
  -H "X-API-Key: dv_live_sk_..." \
  --data-urlencode "keyword=acme weekly" \
  --data-urlencode "status=ended" \
  --data-urlencode "limit=50"
```

* `keyword` — 1 to 120 characters. LIKE/ILIKE metacharacters (`%`, `_`,
  `\`) are treated as literal text, so guests cannot widen the match with
  wildcards.
* `status` — still applies, so combine `keyword` with
  `scheduled`/`live`/`ended` to search only the relevant slice.
* `limit` — the page size; defaults to 100, maximum 500.

The search is tenant-scoped: results are always rooms in your own tenant,
never another tenant's. On the dashboard, the **Rooms** page's search
field sends the same `keyword` parameter — the list refreshes as you type,
so you can jump to a room's join page or copy its invite link without
scrolling through history.

<Note>
  The keyword filter matches on the room name and `room_sid`, not on the
  transcript content or participant list. To search what was actually said
  during a meeting, query the room's transcript endpoint
  (`GET /video/rooms-scheduled/:id/transcripts`) and search client-side.
</Note>

## Meeting URLs on the list projection

Every room returned by the list route carries a `meeting_url` field — a
relative join path (e.g. `/join/meeting/weekly-sales-sync`) that resolves
against your dashboard origin. The dashboard uses this field for the
**Share** and open-actions on the Rooms page, and a workspace's own links
can safely copy it without reconstructing the public join route. Combine
it with your current origin and locale, or use the returned path directly
when both are relative to the same dashboard host.

```json theme={null}
{
  "id": "rm_9f2…",
  "name": "Weekly sales sync - Acme",
  "meeting_url": "/join/meeting/Weekly sales sync - Acme",
  "status": "scheduled",
  "scheduled_at": "2026-06-02T09:00:00Z"
}
```

## Where to go next

* [Room access tokens](/guides/video-room-access-tokens) — what an access token
  grants and exactly where to pass it to connect over WebRTC.
* [Video API reference](/api-reference/video) — the full scheduled-room
  endpoint surface, including recording, moderation, and simulive.
