> ## 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 room templates and the background library

> How Orbit's video room templates and branded background library work as artifacts — the frozen config graph, clone-on-instantiate semantics, the clone-vs-source drift decision, library validation rules, and the endpoint surface behind both

# Video room templates and the background library

Two artifact models back Orbit's video rooms: **room templates** — a saved,
named graph of room defaults — and the **background library** — a curated
registry of branded virtual-background images for the workspace. Both are
workspace-level artifacts that rooms consume at creation or join time. This
page explains the artifact model: what a template freezes, what cloning a
template copies into a mutable room, where the drift trade-off lives, and how
the background library validates the assets it registers. The
endpoint-by-endpoint reference lives in the [Video API
reference](/api-reference/video); the click-by-click flows live in the
[video room templates guide](/guides/video-room-templates) and the
[branded backgrounds guide](/guides/video-branded-backgrounds). This page is
the model those endpoints and guides implement.

## What a room template is

A room template is a **frozen graph of room-creation defaults**: a named,
saved snapshot of the settings a newly created room should open with. Where a
plain room-create body mixes identity (`name`, `scheduled_at`, consent
receipts) with policy (participant cap, recording, media policy), a template
captures only the policy half — the reusable, non-secret subset:

* **Capacity and duration** — `max_participants`, `max_duration_minutes`.
* **Recording defaults** — `recording_enabled`, `recording_format`
  (composite / per-participant tracks / both), `recording_output` encoding.
* **Media tuning** — `simulcast`, `spatial_layers`, `max_bitrate_kbps`,
  `video_codec`, `svc_scalability_mode`, `spatial_audio`.
* **Privacy and accessibility** — `e2ee`, `virtual_background`,
  `noise_suppression`, `audio_only`, `captions_required`.
* **Region and lobby** — `region`, `waiting_room`,
  `waiting_room_auto_promote`.

What the graph deliberately never holds:

* **Per-instance identity** — a room's `name` and `scheduled_at` are
  supplied on every instantiate call, so one template serves every occasion.
* **Secrets** — recording-storage credentials never persist into workspace
  settings; a two-party-consent receipt id is passed per instantiation, not
  stored.

The template config schema rejects unknown keys (`.strict()`) precisely so
credentials or arbitrary blobs can't be smuggled into the settings blob by a
buggy or hostile client. That is what "frozen" buys you: a saved template is
a safe, identifiable, reviewable unit of room policy — not a bag of raw
create-body fields.

## The background library: curated assets, not uploads

The second artifact is the **background library**: a registry of branded
virtual-background images that shows up in the in-call picker of every room
in the workspace, next to the built-in presets and blur.

The library is **curated**, not uploaded. Each entry is a label (up to 80
characters) plus an `https://` image URL the tenant hosts on its own CDN or
asset store. Orbit validates the reference; the tenant's CDN serves the
bytes. That split is the distinction from a custom upload flow:

|                 | Curated library (this model)                              | Custom CDN upload                                           |
| --------------- | --------------------------------------------------------- | ----------------------------------------------------------- |
| Stored in Orbit | A validated URL plus a label — no image bytes             | Image bytes on Orbit-managed object storage                 |
| Who hosts       | Your CDN / asset store                                    | Orbit's file storage (see the general file-upload pipeline) |
| Validation      | HTTPS-only scheme, 2048-char cap, duplicate-URL rejection | Content-type and size checks at upload                      |
| Pick-time fetch | Participant browser fetches your URL directly             | Participant browser fetches Orbit's URL                     |

The HTTPS-only rule is a hard validation, not a recommendation: the in-call
background processor fetches the URL client-side on the HTTPS dashboard, so
`http://` would die on mixed-content blocking, and non-HTTP schemes
(`data:`, `file:`, `javascript:`) are either unbounded blobs or injection
vectors. The library holds up to 50 entries per workspace; room templates
hold up to 100.

A room then decides whether participants may use these images at all through
its `virtual_background` media policy: `off` (picker disabled), `allowed`
(participants may pick), or `required` (participants must run a virtual
background) — the tenant-owned control that pins the workspace library
onto every room from a template.

## Clone semantics: what instantiating copies, what stays template-bound

`POST /video/room-templates/:id/instantiate` **clones** the template into a
real room definition. The clone is a snapshot copy, not a live reference:

**Copied into the room, permanently detached:**

* The whole config graph — capacity, duration, recording defaults, media
  tuning, privacy flags, region, and the waiting-room lobby, which is folded
  into the room's stored settings as `waiting_room_enabled` /
  `auto_promote_from_waiting_room` (the same keys a runtime waiting-room
  update writes).
* Tier and deployment gates, evaluated **at clone time**: the participant
  cap is clamped to your plan's ceiling, and a template that mandates live
  captions refuses instantiation on a deployment with no caption service
  configured.

**Stays on the template (template-bound):**

* The template itself — its name, description, and config graph — which
  rooms reference only by `template_id` on their audit trail.
* Editing or deleting a template after rooms were cloned from it changes
  **future clones only**; rooms already created keep the configuration the
  clone captured, down to the recording format.
* What instantiation deliberately does **not** inherit: a per-template room
  name (supplied per call) and the live moderator room-lock (a runtime-only
  action on a live room, valid nowhere else).

That asymmetry is the whole model: clone-copied defaults are mutable room
state from the moment of creation; template-bound fields stay immutable and
central. A template is a stamp, and instantiate presses it.

## Versioning: platform stamps versus clone drift

Orbit ships **no platform-version stamps on templates**. Templates are
tenant content — the only clocks on them are the `created_at` and
`updated_at` recorded when an owner, admin, or developer saves a change. The
platform never auto-rewrites your template graph on upgrade, and no
version marker is consulted at clone time.

That choice has a direct drift consequence: when the platform widens a knob
(a new codec, a new region), an old template may clone a stale value, and
clones taken before a fix keep the old value while the template row itself
still reads as current. The tenant-owned controls to manage that drift:

* `updated_at` is the freeze marker — audit it before relying on a template
  whose defaults you last touched a quarter ago.
* An update **full-replaces** the config (a validated, whole-preset write),
  not a deep-merge — so re-saving revalidates every field, including the
  cross-field rule that `svc_scalability_mode` only makes sense on a
  `vp9`/`av1` codec.
* Because clones detach at create time, "re-save the template" heals future
  rooms only; live rooms are reconfigured by editing the room itself.

## Tenant trust: likeness and adult-safety scoped to what you register

For the background library the likeness and adult-safe question collapses
into a hosting claim: the library stores URLs you registered, and your
participants' browsers fetch your CDN directly. The platform control is
validation at registration time — HTTPS-scheme, length bound, and duplicate
rejection — plus the workspace-level removal action every owner/admin can
take. What the platform does not do on curated assets: pixel-level likeness
or content screening, because the bytes never touch an Orbit bucket. If you
need screened, platform-hosted imagery instead, use the file-upload pipeline
with its own moderation surface and register the resulting hosted URL here.

## API surface

All routes below require `video:read` to list and `video:write` plus an
`owner` / `admin` / `developer` role to mutate; both libraries are scoped to
the tenant and audited on every create, update, and delete.

Room templates — `/api/v1/video/room-templates`:

| Method | Path               | Action                                           |
| ------ | ------------------ | ------------------------------------------------ |
| GET    | `/`                | List saved templates                             |
| GET    | `/:id`             | Fetch one template                               |
| POST   | `/`                | Save a new template                              |
| PATCH  | `/:id`             | Replace name / description / config              |
| DELETE | `/:id`             | Remove a template (existing clones unaffected)   |
| POST   | `/:id/instantiate` | Clone the template into a live or scheduled room |

Background library — `/api/v1/video/background-library`:

| Method | Path        | Action                                              |
| ------ | ----------- | --------------------------------------------------- |
| GET    | `/`         | List registered backgrounds                         |
| POST   | `/`         | Register a branded image URL                        |
| DELETE | `/:assetId` | Remove one (disappears from every picker instantly) |

Both libraries persist on the organization's settings as bounded JSONB
arrays — template ids are `vrtpl_`-prefixed and background ids `vbg_`
-prefixed — read on the room-create and join paths without touching per-call
media plane state.

## Related

<CardGroup cols={2}>
  <Card title="Video room templates — guide" href="/guides/video-room-templates">
    The click-by-click dashboard flow and per-field room defaults a template
    locks in.
  </Card>

  <Card title="Branded video-room backgrounds" href="/guides/video-branded-backgrounds">
    Registering background URLs and the room policy that gates the picker.
  </Card>

  <Card title="The video room model" href="/concepts/video-room-model">
    How the rooms a template stamps live, close, and feed history.
  </Card>

  <Card title="Video API reference" href="/api-reference/video">
    The endpoint-by-endpoint contract for both artifact surfaces.
  </Card>
</CardGroup>
