SeatSquirrel
EmbeddingPicker

Picker SDK API Reference

Complete API reference for the SeatSquirrel Picker SDK

Constructor Options

new SeatSquirrel.StatelessPicker(options)

OptionTypeRequiredDescription
containerstring | HTMLElementYesCSS selector or DOM element for the picker container
onReadyfunctionNoCalled when picker is ready to receive data
onLayoutLoadedfunctionNoCalled when a layout is successfully loaded
onSelectionChangefunctionNoCalled when selections change
onCompletefunctionNoImportant: Called when user clicks checkout
onErrorfunctionNoCalled when an error occurs
baseUrlstringNoLocation of the SeatSquirrel app (default: https://seatsquirrel.com)
primaryColorstringNoCustom primary color for on-the-fly branding (hex without #, e.g., 3b82f6)
secondaryColorstringNoCustom 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 } objects
    • areas (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 labels
    • totals (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 as onSelectionChange

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.

PropertyTypeDescription
selectionsSelectionItem[]Array of seat and area selections
totalsobject{ 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.

PropertyTypeRequiredDescription
idstringYesUnique seat identifier (UUID)
type'seat'YesDiscriminator for selection type
rowIdstringYesParent row identifier
rowLabelstringYesRow label (e.g., "A", "1")
seatLabelstringYesSeat label (e.g., "1", "12")
sectionIdstringNoSection identifier
sectionNamestringNoSection display name
categoryIdstringYesSelected pricing category ID
categoryNamestringNoPricing category display name
pricenumberYesPrice 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.

PropertyTypeRequiredDescription
idstringYesUnique area identifier (UUID)
type'area'YesDiscriminator for selection type
areaNamestringYesArea display name
sectionIdstringNoSection identifier
sectionNamestringNoSection display name
categoryIdstringYesSelected pricing category ID
categoryNamestringNoPricing category display name
quantitynumberYesNumber of spots selected
pricePerUnitnumberYesPrice per spot in cents
totalPricenumberYesTotal 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
  }
});
PropertyTypeDescription
seatsRecord<string, boolean>Map of seat ID → availability (true = available)
areasRecord<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

PropertyTypeRequiredDescription
sectionIdstringNoSection ID (only if row/seat combo is ambiguous)
rowLabelstringYesRow label (e.g., "A", "1")
seatLabelstringYesSeat label (e.g., "1", "12")
isAvailablebooleanYesWhether the seat is available

AreaAvailabilityByLabel

PropertyTypeRequiredDescription
sectionIdstringNoSection ID (only if area name is ambiguous)
areaNamestringYesArea name as defined in the layout
availableCountnumberYesNumber of available spots (0 = sold out)

AvailabilityByLabels

PropertyTypeRequiredDescription
seatsSeatAvailabilityByLabel[]NoArray of seat availability
areasAreaAvailabilityByLabel[]NoArray 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.).

PropertyTypeRequiredDescription
categoriesPricingCategory[]YesArray of pricing category overrides

PricingCategory (for override)

PropertyTypeRequiredDescription
idstringYesMust match existing category ID in layout
namestringYesDisplay name
pricenumberYesPrice in cents
colorstringYesHex 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