Skip to content

Embedded control room

Give authorized operators a live, capability-scoped SeatManager board inside your own application.

Updated View as Markdown

SeatManager is a same-document operator board—not an iframe. It renders the event map, subscribes to live inventory, shows occupancy and activity, and exposes controlled custom selection, blocking, category, table, section, channel, cancellation, and reporting tools.

Trust boundary

Your backend authorizes the operator and asks SeatLayer to mint an event-scoped mse_… token. The browser receives only that token. Never put an account secret key in the page.

  1. Operator browserRequests Event access

    The operator opens your application and asks for the control room for one Event.

  2. Your backendGrants explicit capabilities

    It authorizes the operator, then mints an mse_ token for the Event, origin, and exact allowed actions.

  3. BrowserMounts SeatManager

    The page receives only the temporary token and expiry, not an account secret key.

  4. SeatLayerProvides live scoped operations

    SeatManager reads live inventory and can perform only the actions the issued capability permits.

Mint a manage session

curl -sX POST \
  "https://api.seatlayer.io/v1/events/ev_9f3a/manage-sessions" \
  -H "authorization: Bearer $SEATLAYER_SECRET_KEY" \
  -H "content-type: application/json" \
  -d '{
    "allowedOrigin": "https://admin.example.com",
    "capabilities": [
      "event:view",
      "event:block",
      "event:categories:manage",
      "event:tables:manage",
      "event:reports"
    ],
    "expiresInSeconds": 3600
  }'

Add event:cancel only for operators allowed to return booked inventory to sale. A browser manage token cannot confirm a booking: the platform backend does that through /book. Managed Box Office is a separate commerce surface and capability.

If your backend omits capabilities, the API issues a view-only token with exactly event:view. Blocking, cancellation, reports, channels, and Managed Ticketing operations always require an explicit capability.

Mount the board

browser/control-room.jsjs
import { SeatManager } from "@seatlayer/js/manager";

const session = await fetch("/api/events/ev_9f3a/manage-session", {
  method: "POST",
}).then((response) => response.json());

const room = new SeatManager({
  container: "#control-room",
  eventKey: "ev_9f3a",
  token: session.token,
  tokenExpiresAt: session.expiresAt,
  mode: "view",
  keepLiveWhileHidden: true,
  followLive: false,
  onTokenRefresh: async () => {
    const next = await fetch("/api/events/ev_9f3a/manage-session", {
      method: "POST",
    }).then((response) => response.json());
    return { token: next.token, expiresAt: next.expiresAt };
  },
  onError: (error) => showOperatorError(error),
});

await room.render();

Give the container a real height. SeatManager fills that box and watches it with ResizeObserver. Fullscreen uses the browser Fullscreen API.

Operator modes

Tools are grouped in the toolbar as Watch (view, inspect — read-only), Manage (block, sections, categories, tables, channels — changes this event only) and Host tools (select, filterSections — hands a selection or filter to your app). Pass tools to offer a subset; it filters what is shown and never grants a capability.

Mode Purpose Capability
view Live occupancy, activity, momentum, presence, and aggregate inventory performance event:view
inspect Read the current state and context of one seat event:view
select Select live event objects for a host-owned custom operation; no inventory mutation event:view
filterSections Filter and frame matching section labels for host-owned reporting event:view
block Select and block/unblock individual inventory event:block
sections Open, close, hide, or schedule sections/zones event:block
categories Change event-only category assignments event:categories:manage
tables Change free tables between per-chair and whole-table booking event:tables:manage
channels Inspect or manage private sales allocations event:channels:view / event:channels:manage

event:reports is separate from the live board. Add it only when the embedded staff workflow must open booking history, category/section/channel breakdowns, downloadable inventory reports, or the full audit history. SeatLayer Orders, tickets, refunds, and attendance are not part of the Platform/SDK Control room.

Following live activity is off by default so a busy event does not repeatedly move the operator’s camera. Heat overlays express sales velocity without replacing chart category colors.

Common actions

operator/actions.tsts
room.setMode("block");
room.selectSection("sec-stalls");

await room.block(undefined, {
  releaseAt: Date.parse("2026-08-01T19:00:00Z"),
  reason: "Soundcheck hold",
});

await room.unblock(["A-3"]);
await room.unblockAll();

await room.cancelBooking(["C-14", "C-15"], "order_5567");
await room.setHoldTtl(10 * 60 * 1000);

room.setMode("select");
room.selectObjects(["A-1", "A-2"]);
const selectionState = room.getSelectionValidity();

room.setMode("filterSections");
const matchedSections = room.setFilteredSection("Balcony");
room.clearFilteredSection();

await room.setCategory("vip", ["A-1", "A-2"]);
await room.setTableBooking(["table-1"], "whole");

const report = await room.getReport();
const log = await room.getLog({ limit: 50 });

Cancellation changes inventory only; your application owns its commercial order, ticket cancellation, refund policy, payment execution, and buyer communication. The booking reference prevents releasing a newer booking.

Category assignments are event-only: the reusable venue chart is unchanged, and existing hold/booking price snapshots are not rewritten. Table-mode changes alter inventory identity and are therefore refused while any affected table is held, booked, or blocked, or when a private-channel allocation would be lost.

Long-running boards

Pass both tokenExpiresAt and onTokenRefresh. SeatManager proactively requests a replacement and also retries once after an authorization failure. Your refresh endpoint must repeat the full host-user authorization check rather than accepting the expired token as proof.

keepLiveWhileHidden: true forces a fresh paint after live deltas when browsers throttle background animation frames. Use it for a wallboard; consider battery and resource costs on laptops.

Custom operator UI

Use ManageApi when the packaged board does not match your workflow. It exposes the same token-authenticated reads and mutations: availability, category/table management, block/unblock, cancellation, hold TTL, report, control-room snapshot, audit log, and CSV Blob. Keep capability rules identical to SeatManager.

Verification

  • The backend authorizes event and tenant before every SeatLayer session request.
  • The token carries only necessary capabilities.
  • The board has a bounded, responsive container.
  • Token rotation is tested across laptop sleep and network loss.
  • Detailed reports and full audit history stay unavailable unless event:reports is minted.
  • Cancellation is paired with an explicit refund workflow.
  • Conflict errors ask the operator to reload or reselect.
  • destroy() runs during unmount and logout.
  • Revocation occurs when access ends.

Continue to the SeatManager reference, embed sessions, and reports.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close