---
title: "SeatingChart reference"
description: "Headless map options, callbacks, methods, live holds, GA, groups, floors, and error behavior."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.seatlayer.io/llms.txt
> Use this file to discover all available pages before exploring further.

# SeatingChart reference

`SeatingChart` mounts the live map canvas without SeatLayer's cart/tray chrome.
Your application owns totals, tier/GA controls, the checkout button, countdown,
and buyer messages.

```js title="browser/chart.js"
import { SeatingChart } from "@seatlayer/js";

const chart = new SeatingChart({
  container: "#chart",
  event: "ev_9f3a",
  onSelectionChange: renderCart,
  onError: reportPickerError,
});

await chart.render();
```

## Constructor options and callbacks

| Option | Type | Notes |
|---|---|---|
| `container` | `string \| HTMLElement` | Required, definite dimensions |
| `event` | `string` | Required event key |
| `apiBase` | `string` | Defaults to production API |
| `publicKey` | `string` | Reserved and currently not sent |
| `maxSelection` | `number` | Default `10` |
| `locale` / `messages` | `string` / overrides | Localized on-map copy |
| `currency` | `string` | Display fallback |
| `colorblindSafe` | `boolean` | Accessible palette and hollow booked state |
| `initialView` | `RendererViewMode` | Use `flat`; perspective modes deprecated |
| `seatTooltip` | `boolean` | Built-in hover tooltip, default `true` |
| `onSeatHover` | `(details \| null) => void` | Build a custom hover surface |
| `onSelectionChange` | `(seats) => void` | Manual, group, or tier change |
| `onHint` | `(message \| null) => void` | Non-blocking localized advice |
| `onHold` | `(hold) => void` | Any successful hold |
| `onHoldRestored` | `(hold) => void` | `resumeHold()` succeeds |
| `onHoldExpired` | `() => void` | Server expiry reached |
| `onGAClick` | `(area) => void` | Host should request quantity and call `holdGA()` |
| `onDeckTap` | `(floorId) => void` | Synchronize custom floor controls |
| `onError` | `(error) => void` | Public async methods report failures here |

## Selection and hold methods

| Method | Signature/behavior |
|---|---|
| `getMode()` | `"live" \| "test" \| null`; null before render |
| `getSelection()` | Current `SelectedSeat[]` |
| `hold({ ttlMs? })` | Hold current selection; `null` on failure/conflict |
| `resumeHold(holdId)` | Restore without extending |
| `extendHold(ttlMs?)` | Extend active hold within server limits |
| `getCurrentHold()` | Current `HoldResult \| null` |
| `getGAAreas()` | Live GA capacity records |
| `holdGA(areaId, qty, { tierId?, ttlMs? })` | Quantity hold |
| `bestAvailable(qty, categoryKey?, options?)` | Adjacent group hold |
| `setSeatTier(seatId, tierId)` | Change selected tier; null resets |
| `release()` | Release the full hold |
| `releaseLabels(labels)` | Partially release listed labels |

`hold()`, `resumeHold()`, `holdGA()`, and `bestAvailable()` catch public
transport errors, call `onError`, and resolve `null`. Do not wait for an
exception to render buyer recovery.

## View and lifecycle methods

| Method | Behavior |
|---|---|
| `render()` | Fetch, mount, seed live state; idempotent after success |
| `getFloors()` / `setFloor(id)` | Custom multi-floor navigation |
| `setColorblindSafe(on)` | Runtime accessible palette |
| `setViewMode(mode)` / `getViewMode()` | 2D renderer compatibility |
| `zoomIn()` / `zoomOut()` / `zoomToFit()` | Host map controls |
| `destroy()` | Socket/listener/timer/DOM cleanup |

The full 3D buyer experience belongs to `SeatPicker`; `SeatingChart.initialView`
does not enable that venue view.

## Core result types

```ts
interface HoldResult {
  holdId: string;
  expiresAt: number;
  seats?: SelectedSeat[];
  items?: HoldLineItem[];
}

interface BestAvailableResult extends HoldResult {
  labels: string[];
  zoneId?: string;
}

interface GAAreaAvailability {
  id: string;
  label: string;
  capacity: number;
  available: number;
  categoryKey: string;
  price: number;
  currency: string;
  displayLabel?: string;
  displayType?: string;
  tiers?: Array<{ id: string; name: string; price: number }>;
}
```

`HoldLineItem.unitPrice`, currency, tier, and quantity come from SeatLayer, but
your server still re-inspects the hold before payment.

## Build the custom cart safely

1. **Render selection**

   Derive immediate UI from `onSelectionChange`; keep stable ids separate from
   buyer labels.
2. **Create the hold**

   Call the appropriate hold method when the buyer continues. Disable duplicate
   submissions while it runs.
3. **Start a visible timer**

   Count down from server `expiresAt`, not a locally invented duration.
4. **Hand off only holdId**

   Your backend inspects authoritative items, runs payment/order logic, and
   books.
5. **Recover intentionally**

   Clear stale selection/cart on expiry, show adjacency-specific errors, and
   reuse `bookingRef` for uncertain server retries.

## Integration checklist

- [ ] The host container has a stable width and height.
- [ ] Every callback updates host state idempotently.
- [ ] `null` async results have explicit buyer copy.
- [ ] GA, tier, best-available, and partial release paths are tested if used.
- [ ] Hold time is based on `expiresAt`.
- [ ] Server checkout ignores browser prices.
- [ ] `destroy()` runs during unmount/navigation.
- [ ] Keyboard, touch, zoom, and colorblind-safe behavior pass.

Continue with [SeatPicker](/buyer-sdk/seat-picker),
[groups and GA](/integrations/groups-and-ga), or
[best available](/buyer-sdk/best-available).

Source: https://docs.seatlayer.io/buyer-sdk/seating-chart/index.mdx
