Recipes← all recipesView on GitHub

Manage video rooms over REST

Videovideo room lifecycle management

Create a room for each meeting with a member cap and a join window. List and update your rooms over REST, and delete a room when the meeting is over.

Also called room per meeting, scheduled video rooms, conference room CRUD

rest

The claim

create-a-video-room-and-join-from-the-browser makes one room and joins it. This recipe is the rest of a room’s life. The vendored REST spec, tools/openapi/rest.json, is the authority.

Why it holds

  • POST /api/fabric/resources/conference_rooms requires name and enable_room_previews. max_members is 0 to 300. join_from and join_until bound when joining works, remove_at empties the room at a time, and remove_after_seconds_elapsed (0 to 200000) removes each participant that long after they joined.
  • GET on the collection lists rooms, GET .../{id} reads one, and GET /api/fabric/resources/conference_room/{id}/addresses gives the address the browser dials.
  • PUT .../{id} updates a room and requires enable_room_previews and sync_audio_video on every call, so the recipe reads the room first and sends its current values with the change. The read can return sync_audio_video as null and the update does not accept null, so an unset flag is sent as false.
  • DELETE .../{id} answers 204.

The SDKs wrap the five as client.fabric.conference_rooms in Python and client.fabric.conferenceRooms in TypeScript. The helpers refuse a cap or a removal delay outside the spec’s bounds before any request, because the platform would answer 422.

How it works

def create_room(name, max_members=None, join_from=None, join_until=None, remove_at=None):
    body = {"name": name, "display_name": name, "enable_room_previews": False}
    if max_members is not None:
        body["max_members"] = _bounded("max_members", max_members, MAX_MEMBERS)
    ...
    return client.fabric.conference_rooms.create(**body)

def update_room(room_id, **changes):
    current = get_room(room_id)["conference_room"]
    body = {"enable_room_previews": current["enable_room_previews"],
            "sync_audio_video": current["sync_audio_video"], **changes}
    return client.fabric.conference_rooms.update(room_id, **body)   # a PUT

What the platform receives for a room that opens at 08:50, locks at 09:30 and empties at 10:00:

POST /api/fabric/resources/conference_rooms
{"name": "standup-0900", "display_name": "standup-0900", "enable_room_previews": false,
 "max_members": 12, "join_from": "2026-11-03T08:50:00Z",
 "join_until": "2026-11-03T09:30:00Z", "remove_at": "2026-11-03T10:00:00Z"}

The response carries the room’s id, which the other four calls take. Its address is /public/<name>, and the addresses call confirms it.

Limitations

The verifier proves the requests, not the room. The spec says joining before join_from “will result in failure to join”; what a browser sees at that moment is live behaviour. What happens to participants when a room is deleted while they are in it is not documented, so use remove_at to end a session. Who was in a room and when is the room sessions API, /api/video/room_sessions, which this recipe does not touch.

What to change first

Pass record_on_start=True to create_room so every session of the room is recorded, then read the recordings with record-a-video-room.