Skip to main content

The video registrant lifecycle

A registrant is a person who signed up for a scheduled video room before it went live. Registration is a first-class video capability: the room carries its own registration form, each signup produces a registrant record with its own join token, and the room’s join gate can refuse anyone the register does not approve. This page explains the registrant record itself — where it lives, which status it moves through, and how it becomes room access. The endpoint-by-endpoint contract lives in the Video API reference; the step-by-step walkthrough is the Registration-gated webinars guide. Both are implemented on the model described here.

When a registrant record exists

A registrant record exists across three phases of the room, and the shape of the record is the same in all three.
  • Pre-live — the organizer opens the room’s registration form, and each signup appends a record to the room’s register. Registration editing stays available while the room is pending (before it goes live). The record accumulates approval decisions: pending, approved, declined, blocked, or waitlisted.
  • During — the join gate consults the register live. An approved registrant’s join flips the record to attended, atomically, in the same step that mints their participant token. The register is a live input to admission, not just a pre-event list.
  • Post — the record feeds the registered-versus-attended report: totals by status, no-shows (approved but never checked in), attendance rate, and capacity remaining. Because the register lives on the room record, the room’s history and retention surfaces treat it as part of the room.
The register is stored on the room itself, inside the room’s per-room settings blob — so it is tenant-isolated by construction and disappears with the room when the room is deleted. No separate registrant table exists; a room’s register never leaks across tenants or across rooms.

Registration fields versus custom questions

The form always captures two platform fields:
  • name — the attendee display name.
  • email — the attendee address, deduplicated case-insensitively within the room (a second signup with the same email, in any case, is refused as a conflict).
On top of those, the organizer can attach custom questions — up to 20 of them, each with a stable machine key, a human label, and a required flag. Required questions are enforced at registration time: a submission missing a required answer is refused. Answers are stored on the record keyed by the question’s machine key, so your form’s fractional_seats key stays the same field even when you relabel it.

Check-in identity: the join token

Every registrant record carries a join token — an opaque, unique value minted at registration (~192 bits of entropy). The organizer distributes it in the confirmation email, and the attendee redeems it at the join gate. That token, or the registrant’s email, is the identity the gate matches against; a name alone never admits anyone.
The join token identifies the registrant within the one room it was minted for. It is not an API credential and it does not reuse the shared guest invite link — each registrant holds their own.
When the room arms the Registered participants only switch, both paths into the room — the authenticated join call and the guest invite redemption — run the same register check, so there is no seam an unregistered guest can step around. The guide to arming it is Registered participants only.

Lifecycle: the status workflow

A registrant moves through statuses, and check-in sits beside the status, not inside it: Transitions:
  • Register — a signup lands pending when the form requires approval. Without approval, the registrant is approved immediately if a capacity slot is free, otherwise waitlisted. Capacity counts approved registrants plus anyone already checked in; the slot is claimed at approval, not at registration.
  • Decide — the organizer approves, declines, blocks, or waitlists. Approving into a full room is refused with a conflict — capacity is enforced again at decision time, not just at registration.
  • Check in — only an approved registrant can be marked attended; declining or blocking someone soft-revokes their ability to check in. A repeat check-in is idempotent and keeps the first timestamp.
  • Attended — the attended flag and its timestamp sit beside the status. An approved attendee who never checked in is a no-show; the report surfaces that count explicitly.
  • Remove — deleting the record ends the lifecycle unconditionally, for any status.

Concurrency and privacy

The register is bounded and isolated by design:
  • Bounds — a room holds at most 2,000 registrants, 20 custom questions, and answers up to 2,000 characters each. The bound keeps a runaway registration form from bloating the hot room-read path. Audiences beyond the room’s participant ceiling belong to the broadcast surface, not the joinable room.
  • Tenant isolation — the register lives on the room row in the workspace’s own schema. A read or write is scoped to the caller’s own workspace, and missing rooms return a plain not-found — a room’s existence never leaks across workspaces.
  • Consent is yours to collect — the register stores the answers your form asks; it does not itself send confirmations or reminders to registrants. If your form later markets to registrants, collect that opt-in as a custom question and honor it in your own messaging — Orbit’s messaging consent controls apply to whatever you send, and the register simply records what the attendee answered.
  • Rate limits — every registrant endpoint is rate-limited, so a flooded form cannot degrade the room or the API.

Worked example: register, admit, join

  1. Open the form. PUT /video/rooms-scheduled/{roomId}/registration with enabled: true, optionally require_approval: true, a capacity, and any custom_fields.
  2. Register the attendee. POST /video/rooms-scheduled/{roomId}/registrants with name, email, and custom_answers. The response carries the record, including its join_token — pass that token to the attendee in the confirmation you send.
  3. Decide, if approval is required. PATCH /video/rooms-scheduled/{roomId}/registrants/{registrantId} with decision: "approve" (or decline, block, waitlist).
  4. Join. The attendee presents their email or join token at the gate. An approved match mints the participant token and flips the record to attended in the same atomic step.
  5. Read the report. GET /video/rooms-scheduled/{roomId}/registration returns the config, the register, and the report: totals per status, attended count, no-shows, attendance rate, and capacity remaining.
Check-in can also be recorded directly — POST /video/rooms-scheduled/{roomId}/registrants/{registrantId}/check-in — for a badge desk or an external admission system; the join path is simply the common self-service check-in.

How registrants hang off the room model

Registration is an attachment to the scheduled-room model, not a separate pillar:
  • The video room model owns the scheduled versus ad-hoc split and the join-token semantics; the registrant gate is the scheduled-room intent refined for a named, pre-registered audience.
  • Broadcast analytics counts the CDN audience that watched without joining; the registrant report answers the opposite question — the named attendees who intended to join and did (or did not).
  • Room usage, engagement, and the post-meeting report all read the room’s session history as usual; a webinar is still a room, and the register is an overlay on its admission.

See also

Registration-gated webinars — guide

Open the form, review registrants, approve, check in, and read the report end to end.

'Registered participants only' gate

Arm the hard join gate so unmatched guests are refused at token mint.

The video room model

Scheduled versus ad-hoc rooms, lifecycle, tokens, recording, and the analytics split.

Broadcast analytics

The CDN-audience metrics for viewers who watch without joining.

Video API reference

The endpoint contract for the registration and registrant management routes.