bestAvailable() asks SeatLayer to find and hold a suitable adjacent group
without requiring the buyer to click individual seats.
Public methods
// SeatingChart
bestAvailable(
quantity: number,
categoryKey?: string,
options?: {
zoneId?: string;
preferPremium?: boolean;
ttlMs?: number;
},
): Promise<BestAvailableResult | null>
// SeatPicker
bestAvailable(
quantity: number,
categoryKey?: string,
options?: {
zoneId?: string;
preferPremium?: boolean;
},
): Promise<HoldResult | null>Find a group
const chart = new seatlayer.SeatingChart({
container: "#chart",
event: "ev_9f3a",
onHold: ({ holdId, expiresAt }) => {
saveCheckoutHandoff({ holdId, expiresAt });
},
onError: (error) => {
console.error("Best-available request failed", error);
},
});
await chart.render();
const result = await chart.bestAvailable(4);
if (!result) {
showAlternatives("No block of four seats is currently available.");
} else {
console.log(result.labels, result.holdId, result.expiresAt);
}A successful call updates selection, fires onSelectionChange, creates the
hold, and fires onHold.
Narrow the search
// Two adjacent VIP seats.
await chart.bestAvailable(2, "vip");
// Four seats in an authored venue zone.
await chart.bestAvailable(4, undefined, {
zoneId: "zone-east-stand",
});
// Prefer a premium block and use a ten-minute checkout window.
await chart.bestAvailable(2, undefined, {
preferPremium: true,
ttlMs: 10 * 60 * 1000,
});Use stable category keys and zone ids from the published chart, not translated labels or screen coordinates. Hidden or unrevealed inventory is not eligible.
Result contract
interface BestAvailableResult {
holdId: string;
expiresAt: number;
labels: string[];
seats?: SelectedSeat[];
items?: HoldLineItem[];
zoneId?: string;
}items contains authoritative hold line information when present. Your browser
still sends only holdId to your server; the server re-inspects the hold before
payment.
Failure behavior
The public method resolves to null for conflicts and routes the underlying
error through onError.
| Reason/code | Meaning | Buyer experience |
|---|---|---|
not_enough_together |
Enough seats may exist, but no adjacent block fits | Offer fewer seats, another zone/category, or manual selection |
sold_out |
Eligible inventory is exhausted | Offer another ticket type or waitlist |
invalid_zone |
Zone id is malformed | Treat as an integration error |
unknown_zone |
Zone is not in the published chart | Refresh configuration; do not retry blindly |
event_closed |
Sales are closed | Disable purchase controls |
Do not translate every null into “sold out.” Preserve enough error context in
onError to choose the correct message.
Premium fallback
preferPremium: true expresses preference, not an absolute filter. If a full
premium block does not exist, the buyer picker may hold the best overall group
and show a fallback note. Use categoryKey when the result must be restricted
to a specific inventory category.
Verification checklist
- Quantity is a positive integer within the buyer limit.
- Category and zone values are stable ids.
- Failure messages distinguish adjacency from sold out.
- The buyer controls any fallback to fewer or separated seats.
- A successful group appears in selection and
onHold. - The server inspects and atomically books the returned hold.
- Expiry clears the whole group from the cart.
Continue with groups and GA or holds and checkout.