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 blocking, section, cancellation, and reporting tools.

Trust boundary

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

control-room-flow.txttext
Operator browser -> your backend: request event access
Your backend -> SeatLayer: mint mse_ token for event + origin + capabilities
Your backend -> browser: token + expiry
Browser SeatManager -> SeatLayer: live reads and scoped actions

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:reports"
    ],
    "expiresInSeconds": 3600
  }'

Add event:cancel only for operators allowed to return booked inventory to sale. Box-office booking stays a trusted server action.

Mount the board

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

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

Mode Purpose Capability
view Live occupancy, activity, momentum, presence event:view; revenue also needs event:reports
inspect Read the current state and context of one seat event:view
block Select and block/unblock individual inventory event:block
sections Open, close, hide, or schedule sections/zones event:block

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);

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

Cancellation changes inventory only; your application owns refund policy and payment execution. The booking reference prevents releasing a newer sale.

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, 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 token mint.
  • The token carries only necessary capabilities.
  • The board has a bounded, responsive container.
  • Token rotation is tested across laptop sleep and network loss.
  • Revenue is blank/stale rather than reconstructed when reports are unavailable.
  • 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