Picker SDK API Reference
Complete API reference for the SeatSquirrel Picker SDK
Constructor Options
new SeatSquirrel.StatelessPicker(options)
| Option | Type | Required | Description |
|---|---|---|---|
container | string | HTMLElement | Yes | CSS selector or DOM element for the picker container |
onReady | function | No | Called when picker is ready to receive data |
onLayoutLoaded | function | No | Called when a layout is successfully loaded |
onSelectionChange | function | No | Called when selections change |
onComplete | function | No | Important: Called when user clicks checkout |
onError | function | No | Called when an error occurs |
baseUrl | string | No | Location of the SeatSquirrel app (default: https://seatsquirrel.com) |
primaryColor | string | No | Custom primary color for on-the-fly branding (hex without #, e.g., 3b82f6) |
secondaryColor | string | No | Custom secondary color for on-the-fly branding (hex without #) |
Methods
loadLayout(layoutData)
Load a layout into the picker for seat selection. This must be called before users can select seats.
Parameters:
layoutData(Object): The DesignerOutput JSON from the designer or your database
Example:
// Load layout from your backend
const layoutData = await fetch('/api/layouts/123').then(r => r.json());
picker.loadLayout(layoutData);setAvailability(availability)
Set which seats and areas are available for selection by ID.
Parameters:
availability(Object):seats(Object): Map of seat ID to boolean (true = available, false = sold)areas(Object): Map of area ID to number (available count)
Example:
picker.setAvailability({
seats: {
'seat-uuid-1': true, // Available
'seat-uuid-2': false, // Sold
'seat-uuid-3': true, // Available
},
areas: {
'area-uuid-1': 50, // 50 available
'area-uuid-2': 0, // Sold out
},
});setAvailabilityByLabels(availability)
Set availability using human-readable row/seat labels instead of UUIDs. More user-friendly than setAvailability().
Parameters:
availability(Object):seats(Array): Array of{ rowLabel, seatLabel, isAvailable }objectsareas(Array): Array of{ areaName, availableCount }objects
Example:
picker.setAvailabilityByLabels({
seats: [
{ rowLabel: 'A', seatLabel: '1', isAvailable: false },
{ rowLabel: 'A', seatLabel: '2', isAvailable: true },
{ rowLabel: 'B', seatLabel: '1', isAvailable: true },
],
areas: [
{ areaName: 'Standing Room', availableCount: 50 },
{ areaName: 'VIP Lounge', availableCount: 0 },
],
});setPricing(pricing)
Override the layout's pricing categories with custom prices.
Parameters:
pricing(Object):categories(Array): Array of pricing category objects to override
Example:
// Override prices for dynamic pricing (e.g., early bird, peak pricing)
picker.setPricing({
categories: [
{ id: 'standard', name: 'Standard', price: 5000, color: '#3b82f6' }, // R50.00 in cents
{ id: 'vip', name: 'VIP', price: 10000, color: '#f59e0b' }, // R100.00 in cents
],
});Important: Prices must be in cents (e.g., 5000 = R50.00).
getSelections()
Request current selections. The selections will be returned via the onSelectionChange callback.
Example:
// Trigger selection callback with current state
picker.getSelections();clearSelections()
Clear all selected seats and areas.
Example:
picker.clearSelections();getCurrentSelections()
Get the last known selections without triggering a callback.
Returns: (Array) Array of current selections
Example:
const selections = picker.getCurrentSelections();
console.log('Current selections:', selections);Note: For real-time state, use getSelections() instead.
getCurrentTotals()
Get the last known totals without triggering a callback.
Returns: (Object) { count: number, amount: number }
Example:
const totals = picker.getCurrentTotals();
console.log(`${totals.count} items, R${totals.amount / 100}`);getLayout()
Get the loaded layout metadata.
Returns: (Object | null) The loaded layout or null
Example:
const layout = picker.getLayout();
if (layout) {
console.log('Layout name:', layout.metadata.name);
}isPickerReady()
Check if the picker is ready to receive commands.
Returns: (boolean) Whether the picker is ready
Example:
if (picker.isPickerReady()) {
picker.loadLayout(data);
}destroy()
Cleanup the picker instance and remove event listeners.
Example:
picker.destroy();Callbacks
onReady()
Called when the picker iframe has loaded and is ready to receive commands.
Example:
onReady: function() {
console.log('Picker is ready');
// Now safe to call loadLayout(), setAvailability(), etc.
picker.loadLayout(layoutData);
}onLayoutLoaded(layoutData)
Called when a layout is successfully loaded into the picker.
Parameters:
layoutData(Object): The layout metadata
Example:
onLayoutLoaded: function(layoutData) {
console.log('Layout loaded:', layoutData.metadata.name);
console.log('Total seats:', layoutData.totals.totalSeats);
}onSelectionChange(data)
Called whenever the user selects or deselects seats/areas.
Parameters:
data(Object):selections(Array): Current selections with IDs and labelstotals(Object):{ count, amount }
Example:
onSelectionChange: function(data) {
console.log('Selected:', data.selections);
console.log(`Total: ${data.totals.count} items, R${data.totals.amount / 100}`);
// Update your UI
updateCartUI(data.selections, data.totals);
}onComplete(data)
Most Important Callback: Called when the user clicks the checkout button. This is where you handle payment processing.
Parameters:
data(Object): Same structure asonSelectionChange
Example:
onComplete: async function(data) {
// User wants to checkout with these selections
const response = await fetch('/api/checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
selections: data.selections,
total: data.totals.amount
})
});
if (response.ok) {
window.location.href = '/checkout/success';
}
}onError(error)
Called when an error occurs in the picker.
Parameters:
error(Object): Error details
Example:
onError: function(error) {
console.error('Picker error:', error);
alert('An error occurred. Please try again.');
}Data Structures
Layout Data (DesignerOutput)
The loadLayout() method accepts the same DesignerOutput structure exported by the Designer.
See the complete schema documentation in the Designer API Reference.
CheckoutData
The data structure returned by onSelectionChange and onComplete callbacks.
| Property | Type | Description |
|---|---|---|
selections | SelectionItem[] | Array of seat and area selections |
totals | object | { count: number, amount: number } |
{
selections: [
{ type: 'seat', ... },
{ type: 'area', ... }
],
totals: {
count: 3, // Total items selected
amount: 11000 // Total price in cents (e.g., R110.00)
}
}SeatSelection
Returned when a user selects a seat.
| Property | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique seat identifier (UUID) |
type | 'seat' | Yes | Discriminator for selection type |
rowId | string | Yes | Parent row identifier |
rowLabel | string | Yes | Row label (e.g., "A", "1") |
seatLabel | string | Yes | Seat label (e.g., "1", "12") |
sectionId | string | No | Section identifier |
sectionName | string | No | Section display name |
categoryId | string | Yes | Selected pricing category ID |
categoryName | string | No | Pricing category display name |
price | number | Yes | Price in cents (e.g., 5000 = R50.00) |
{
id: "seat-uuid-1",
type: "seat",
rowId: "row-uuid-a",
rowLabel: "A",
seatLabel: "1",
sectionId: "section-orchestra",
sectionName: "Orchestra",
categoryId: "standard",
categoryName: "Standard",
price: 5000
}AreaSelection
Returned when a user selects spots in an area.
| Property | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique area identifier (UUID) |
type | 'area' | Yes | Discriminator for selection type |
areaName | string | Yes | Area display name |
sectionId | string | No | Section identifier |
sectionName | string | No | Section display name |
categoryId | string | Yes | Selected pricing category ID |
categoryName | string | No | Pricing category display name |
quantity | number | Yes | Number of spots selected |
pricePerUnit | number | Yes | Price per spot in cents |
totalPrice | number | Yes | Total price in cents (quantity × pricePerUnit) |
{
id: "area-uuid-1",
type: "area",
areaName: "Standing Room",
sectionId: "section-ga",
sectionName: "General Admission",
categoryId: "general",
categoryName: "General",
quantity: 2,
pricePerUnit: 3000,
totalPrice: 6000
}Availability by ID
Set availability using internal UUIDs. Use this when you store seat/area IDs in your database.
picker.setAvailability({
seats: {
"seat-uuid-1": true, // Available
"seat-uuid-2": false, // Sold
"seat-uuid-3": true // Available
},
areas: {
"area-uuid-1": 50, // 50 spots available
"area-uuid-2": 0 // Sold out
}
});| Property | Type | Description |
|---|---|---|
seats | Record<string, boolean> | Map of seat ID → availability (true = available) |
areas | Record<string, number> | Map of area ID → available count |
Availability by Labels
Set availability using human-readable labels. More user-friendly for integrations that don't store UUIDs.
SeatAvailabilityByLabel
| Property | Type | Required | Description |
|---|---|---|---|
sectionId | string | No | Section ID (only if row/seat combo is ambiguous) |
rowLabel | string | Yes | Row label (e.g., "A", "1") |
seatLabel | string | Yes | Seat label (e.g., "1", "12") |
isAvailable | boolean | Yes | Whether the seat is available |
AreaAvailabilityByLabel
| Property | Type | Required | Description |
|---|---|---|---|
sectionId | string | No | Section ID (only if area name is ambiguous) |
areaName | string | Yes | Area name as defined in the layout |
availableCount | number | Yes | Number of available spots (0 = sold out) |
AvailabilityByLabels
| Property | Type | Required | Description |
|---|---|---|---|
seats | SeatAvailabilityByLabel[] | No | Array of seat availability |
areas | AreaAvailabilityByLabel[] | No | Array of area availability |
picker.setAvailabilityByLabels({
seats: [
{ rowLabel: "A", seatLabel: "1", isAvailable: false },
{ rowLabel: "A", seatLabel: "2", isAvailable: true },
{ rowLabel: "B", seatLabel: "1", isAvailable: true }
],
areas: [
{ areaName: "Standing Room", availableCount: 50 },
{ areaName: "VIP Lounge", availableCount: 0 }
]
});Pricing Override
Override pricing categories at runtime for dynamic pricing (early bird, peak pricing, etc.).
| Property | Type | Required | Description |
|---|---|---|---|
categories | PricingCategory[] | Yes | Array of pricing category overrides |
PricingCategory (for override)
| Property | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Must match existing category ID in layout |
name | string | Yes | Display name |
price | number | Yes | Price in cents |
color | string | Yes | Hex color (e.g., "#3b82f6") |
picker.setPricing({
categories: [
{ id: "standard", name: "Early Bird", price: 4000, color: "#22c55e" },
{ id: "vip", name: "VIP", price: 8000, color: "#f59e0b" }
]
});Note: The id must match an existing pricing category ID in the loaded layout. Only the name, price, and color will be overridden.
TypeScript Support
All data structures are validated using Zod schemas. For TypeScript users, types can be imported:
import type {
SeatSelection,
AreaSelection,
SelectionItem,
CheckoutData,
SeatAvailabilityByLabel,
AreaAvailabilityByLabel,
AvailabilityByLabels
} from '@seatsquirrel/sdk';Next Steps
- Picker Quick Start - Get started embedding the Picker
- Designer SDK Reference - API reference for the Designer SDK
- Self-Hosting Guide - Deploy SeatSquirrel on your own infrastructure