SeatSquirrel
EmbeddingDesigner

Designer SDK API Reference

Complete API reference for the SeatSquirrel Designer SDK

Constructor Options

new SeatSquirrel.Designer(options)

OptionTypeRequiredDescription
containerstring | HTMLElementYesCSS selector or DOM element for the designer container
onReadyfunctionNoCalled when designer is ready to receive data
onLayoutLoadedfunctionNoCalled when a layout is successfully loaded
onExportfunctionNoImportant: Called when user clicks Export button
onLayoutChangedfunctionNoCalled when unsaved changes status changes
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 an existing layout into the designer for editing.

Parameters:

  • layoutData (Object): The DesignerOutput JSON from a previous export

Example:

// Load a previously saved layout
const savedLayout = await fetchFromYourDatabase(layoutId);
designer.loadLayout(savedLayout);

getLayout()

Request the current layout data. The layout will be returned via the onExport callback.

Example:

// Trigger export callback
designer.getLayout();

setReadOnly(readOnly)

Enable or disable read-only mode. In read-only mode, users can view the layout but cannot make changes.

Parameters:

  • readOnly (boolean): Whether to enable read-only mode

Example:

// Enable read-only mode
designer.setReadOnly(true);

// Disable read-only mode
designer.setReadOnly(false);

clearLayout()

Clear the current layout and start with a blank canvas.

Example:

designer.clearLayout();

hasChanges()

Check if there are unsaved changes.

Returns: (boolean) Whether there are unsaved changes

Example:

if (designer.hasChanges()) {
  alert('You have unsaved changes!');
}

getCurrentLayout()

Get the last exported layout (not real-time). For real-time state, use getLayout().

Returns: (Object | null) The last exported layout or null

Example:

const lastExport = designer.getCurrentLayout();

isDesignerReady()

Check if the designer is ready to receive commands.

Returns: (boolean) Whether the designer is ready

Example:

if (designer.isDesignerReady()) {
  designer.loadLayout(data);
}

destroy()

Cleanup the designer instance and remove event listeners.

Example:

designer.destroy();

Callbacks

onReady()

Called when the designer iframe has loaded and is ready to receive commands.

Example:

onReady: function() {
  console.log('Designer is ready');
  // Now safe to call loadLayout(), setReadOnly(), etc.
}

onLayoutLoaded(layoutData)

Called when a layout is successfully loaded into the designer.

Parameters:

  • layoutData (Object): The layout metadata

Example:

onLayoutLoaded: function(layoutData) {
  console.log('Layout loaded with', layoutData.totals.totalSeats, 'seats');
}

onExport(layoutData)

Most Important Callback: Called when the user clicks the Export button or when getLayout() is called. This is how you get layout data out of the designer.

Parameters:

  • layoutData (Object): Complete DesignerOutput JSON

Example:

onExport: async function(layoutData) {
  // Save to your database
  await fetch('/api/layouts', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(layoutData)
  });

  alert('Layout saved!');
}

onLayoutChanged(data)

Called whenever the unsaved changes status changes.

Parameters:

  • data (Object): { hasChanges: boolean }

Example:

onLayoutChanged: function(data) {
  if (data.hasChanges) {
    document.title = '* Venue Editor'; // Add asterisk for unsaved
  } else {
    document.title = 'Venue Editor';
  }
}

onError(error)

Called when an error occurs in the designer.

Parameters:

  • error (Object): Error details

Example:

onError: function(error) {
  console.error('Designer error:', error);
  alert('An error occurred: ' + error.message);
}

Data Structures

DesignerOutput (Root Schema)

The layout data structure returned by onExport and accepted by loadLayout:

{
  type: 'seatSquirrelLayout',
  version: '1.0.0',
  layout: {
    sections: Section[],
    rows: SeatRow[],           // Each row contains its seats in row.seats[]
    areas?: Area[],
    pricingCategories: PricingCategory[],
    drawing?: Drawing,
    metadata: {
      name?: string,
      totalSections: number,
      totalRows: number,
      totalSeats: number,
      totalAreas?: number,
      totalPricingCategories: number,
      exportedAt: string,      // ISO 8601 timestamp
      dimensions: { width: number, height: number }
    }
  }
}

Validation

The SDK includes Zod schemas for runtime validation:

import { validateDesignerOutput } from '@seatsquirrel/sdk';

const result = validateDesignerOutput(layoutData);

if (result.success) {
  // result.data is typed as DesignerOutput
  console.log('Valid layout:', result.data);
} else {
  // result.error contains validation error messages
  console.error('Validation failed:', result.error);
}

PricingCategory

Defines a pricing tier that can be assigned to seats, rows, sections, or areas.

PropertyTypeRequiredDescription
idstringYesUnique identifier
namestringYesDisplay name (e.g., "Adult", "VIP")
slugstringYesURL-safe identifier
pricenumberYesPrice in your currency's smallest unit
colorstringYesHex color for visual representation
customerNotesstringNoNotes visible to customers during booking
{
  id: "cat_vip",
  name: "VIP",
  slug: "vip",
  price: 15000,        // e.g., $150.00
  color: "#8b5cf6",
  customerNotes: "Includes complimentary drinks"
}

Section

Organizes rows and areas into named venue sections with optional hierarchy.

PropertyTypeRequiredDescription
idstringYesUnique identifier
namestringYesDisplay name (e.g., "Orchestra", "Balcony")

SeatRow

A row of seats with positioning and labeling configuration. Seats are nested inside the row.

PropertyTypeRequiredDescription
idstringYesUnique identifier
labelstringYesRow label (e.g., "A", "1", "AA")
seatCountnumberYesNumber of seats in row
seatLabelType'numeric' | 'alphabetic-upper' | 'alphabetic-lower' | 'custom'YesHow seats are labeled
seatLabelStartnumber | stringNoStarting label (default: 1 or 'A')
seatLabelOrder'forward' | 'reverse'NoLabel direction
sectionIdstringNoParent section ID
entranceToUsestringNoPreferred entrance for this row
pricingCategoryIdsstring[]YesPricing categories (inherited by seats)
seatsSeat[]YesArray of seats in this row
drawingRowDrawingYesPosition and curve data

RowDrawing

PropertyTypeRequiredDescription
startXnumberYesRow start X coordinate
startYnumberYesRow start Y coordinate
endXnumberYesRow end X coordinate
endYnumberYesRow end Y coordinate
curvenumberYesCurve factor (-1 to 1, 0 = straight)
anglenumberYesRow angle in radians
seatSpacingnumberNoCustom spacing between seats
rowLabelPlacement'start' | 'end' | 'both' | 'none'NoWhere to show row labels

Seat

An individual seat within a row.

PropertyTypeRequiredDescription
idstringYesUnique identifier
rowIdstringYesParent row ID
indexInRownumberYesPosition index within the row (0-based)
rowstringYesRow label (for display)
numberstringYesSeat number/label
pricingCategoryIdsstring[]YesAvailable pricing categories for this seat
isAvailablebooleanNoWhether seat can be booked
isUnbookablebooleanNoPermanently unbookable (e.g., removed)
isAccessiblebooleanNoWheelchair accessible
hasRestrictedViewbooleanNoHas obstructed or limited view
customLabelstringNoOverride label (instead of row + number)
{
  id: "seat_a1",
  rowId: "row_a",
  indexInRow: 0,
  row: "A",
  number: "1",
  pricingCategoryIds: ["cat_standard", "cat_child"],
  isAccessible: true
}

Area

A bookable area (general admission, tables, VIP sections) with flexible pricing models.

PropertyTypeRequiredDescription
idstringYesUnique identifier
namestringYesInternal name
displayLabelstringNoCustomer-facing label
purchaseType'multiple-customer' | 'single-customer'YesMultiple tickets vs. exclusive booking
pricingMethod'per-person' | 'per-area'YesPrice per person or flat rate
sectionIdstringNoParent section ID
pricingCategoryIdsstring[]YesAvailable pricing categories
minOccupancynumberNoMinimum people required
maxOccupancynumberYesMaximum capacity
displayUnit'seat' | 'standing' | 'sofa' | nullNoHow capacity is labeled
entranceToUsestringNoPreferred entrance
showMaxOccupancybooleanNoShow capacity to customers
showMinOccupancybooleanNoShow minimum to customers
showOccupancyInfobooleanNoShow current availability
isUnbookablebooleanNoPermanently unavailable
isAccessiblebooleanNoWheelchair accessible
hasRestrictedViewbooleanNoHas obstructed view
currentOccupancynumberNoCurrent bookings (for availability display)
availableCountnumberNoRemaining capacity
isBookedbooleanNoSingle-customer area: is it booked?
bookedByCustomerIdstringNoSingle-customer: who booked it
lockedbooleanNoPrevent editing in designer
drawingAreaDrawingYesShape and visual properties

AreaDrawing

PropertyTypeRequiredDescription
shape'rectangle' | 'circle' | 'polygon' | 'custom'YesShape type
shapeDataAreaShapeDataYesShape-specific dimensions
fillstringYesFill color (hex)
strokestringNoStroke color
strokeWidthnumberNoStroke width in pixels
opacitynumberNoOpacity (0-1)
rotationnumberNoRotation in degrees
scaleXnumberNoHorizontal scale
scaleYnumberNoVertical scale
textstringNoText overlay
textFontSizenumberNoFont size for text
textXnumberNoText X offset
textYnumberNoText Y offset
textColorstringNoText color
textAlign'left' | 'center' | 'right'NoText alignment

AreaShapeData

Properties vary by shape type:

PropertyTypeUsed ByDescription
xnumberAllX position
ynumberAllY position
widthnumberrectangleWidth
heightnumberrectangleHeight
radiusnumbercircle (if equal radii)Circle radius
radiusXnumbercircle (ellipse)Horizontal radius
radiusYnumbercircle (ellipse)Vertical radius
sidesnumberpolygonNumber of sides (3-20)
pointsnumber[]customArray of [x,y,x,y,...] points
cornerRadiusnumberrectangleRounded corner radius

Drawing

Visual annotations that are not bookable (decorative shapes, labels, stage outlines).

PropertyTypeRequiredDescription
backgroundColorstringNoCanvas background color
linesLine[]NoLine elements
textElementsTextElement[]NoText labels
rectanglesRectangle[]NoRectangle shapes
circlesCircle[]NoCircle/ellipse shapes
polygonsPolygon[]NoRegular polygon shapes
customShapesCustomShape[]NoFreeform shapes

Line

PropertyTypeRequiredDescription
idstringYesUnique identifier
pointsnumber[]Yes[x1,y1,x2,y2,...] points
strokeWidthnumberYesLine width
strokeColorstringYesLine color
strokeStyle'solid' | 'dashed' | 'dotted'YesLine style
dashArraynumber[]NoCustom dash pattern
opacitynumberYesOpacity (0-1)
labelstringNoOptional label
lockedbooleanNoPrevent editing
closedbooleanNoConnect last to first point

TextElement

PropertyTypeRequiredDescription
idstringYesUnique identifier
xnumberYesX position
ynumberYesY position
textstringYesText content
fontSizenumberYesFont size
colorstringYesText color
boldbooleanNoBold text
italicbooleanNoItalic text
rotationnumberNoRotation in degrees
scaleXnumberNoHorizontal scale
scaleYnumberNoVertical scale
widthnumberNoText box width
align'left' | 'center' | 'right'NoText alignment
lockedbooleanNoPrevent editing

Rectangle

PropertyTypeRequiredDescription
idstringYesUnique identifier
xnumberYesX position
ynumberYesY position
widthnumberYesWidth
heightnumberYesHeight
fillstringYesFill color
cornerRadiusnumberYesCorner radius
strokestringNoStroke color
strokeWidthnumberNoStroke width
rotationnumberNoRotation in degrees
scaleXnumberNoHorizontal scale
scaleYnumberNoVertical scale
opacitynumberNoOpacity (0-1)
lockedbooleanNoPrevent editing
textstringNoText overlay
textFontSizenumberNoText font size
textXnumberNoText X offset
textYnumberNoText Y offset
textColorstringNoText color
textAlign'left' | 'center' | 'right'NoText alignment

Circle

Supports both circles (equal radii) and ellipses (different radiusX/radiusY).

PropertyTypeRequiredDescription
idstringYesUnique identifier
xnumberYesCenter X position
ynumberYesCenter Y position
radiusXnumberYesHorizontal radius
radiusYnumberYesVertical radius
fillstringYesFill color
strokestringNoStroke color
strokeWidthnumberNoStroke width
rotationnumberNoRotation in degrees
scaleXnumberNoHorizontal scale
scaleYnumberNoVertical scale
opacitynumberNoOpacity (0-1)
lockedbooleanNoPrevent editing
textstringNoText overlay
textFontSizenumberNoText font size
textXnumberNoText X offset
textYnumberNoText Y offset
textColorstringNoText color
textAlign'left' | 'center' | 'right'NoText alignment

Polygon

Regular polygons (triangles, hexagons, etc.).

PropertyTypeRequiredDescription
idstringYesUnique identifier
xnumberYesCenter X position
ynumberYesCenter Y position
radiusnumberYesDistance to vertices
sidesnumberYesNumber of sides (3-20)
fillstringYesFill color
strokestringNoStroke color
strokeWidthnumberNoStroke width
rotationnumberNoRotation in degrees
scaleXnumberNoHorizontal scale
scaleYnumberNoVertical scale
opacitynumberNoOpacity (0-1)
lockedbooleanNoPrevent editing
textstringNoText overlay
textFontSizenumberNoText font size
textXnumberNoText X offset
textYnumberNoText Y offset
textColorstringNoText color
textAlign'left' | 'center' | 'right'NoText alignment

CustomShape

Freeform shapes defined by arbitrary points.

PropertyTypeRequiredDescription
idstringYesUnique identifier
xnumberYesOrigin X position
ynumberYesOrigin Y position
pointsnumber[]Yes[x1,y1,x2,y2,...] points
fillstringYesFill color
strokestringNoStroke color
strokeWidthnumberNoStroke width
rotationnumberNoRotation in degrees
scaleXnumberNoHorizontal scale
scaleYnumberNoVertical scale
opacitynumberNoOpacity (0-1)
lockedbooleanNoPrevent editing
textstringNoText overlay
textFontSizenumberNoText font size
textXnumberNoText X offset
textYnumberNoText Y offset
textColorstringNoText color
textAlign'left' | 'center' | 'right'NoText alignment

Complete Example

{
  type: 'seatSquirrelLayout',
  version: '1.0.0',
  layout: {
    sections: [{
      id: 'section_orchestra',
      name: 'Orchestra',
      pricingCategoryIds: ['cat_vip', 'cat_standard']
    }],
    rows: [{
      id: 'row_a',
      label: 'A',
      seatCount: 10,
      seatLabelType: 'numeric',
      seatLabelStart: 1,
      sectionId: 'section_orchestra',
      pricingCategoryIds: ['cat_vip'],
      drawing: {
        startX: 100,
        startY: 200,
        endX: 400,
        endY: 200,
        curve: 0.1,
        angle: 0
      },
      seats: [
        {
          id: 'seat_a1',
          rowId: 'row_a',
          indexInRow: 0,
          row: 'A',
          number: '1',
          pricingCategoryIds: ['cat_vip']
        },
        // ... more seats
      ]
    }],
    areas: [{
      id: 'area_ga',
      name: 'General Admission',
      displayLabel: 'Standing Area',
      purchaseType: 'multiple-customer',
      pricingMethod: 'per-person',
      pricingCategoryIds: ['cat_standard'],
      maxOccupancy: 200,
      displayUnit: 'standing',
      drawing: {
        shape: 'rectangle',
        shapeData: { x: 500, y: 100, width: 300, height: 200 },
        fill: '#e5e7eb'
      }
    }],
    pricingCategories: [
      { id: 'cat_vip', name: 'VIP', slug: 'vip', price: 15000, color: '#8b5cf6' },
      { id: 'cat_standard', name: 'Standard', slug: 'standard', price: 5000, color: '#3b82f6' }
    ],
    drawing: {
      backgroundColor: '#ffffff',
      rectangles: [{
        id: 'stage',
        x: 200,
        y: 50,
        width: 200,
        height: 60,
        fill: '#1f2937',
        cornerRadius: 4,
        text: 'STAGE',
        textColor: '#ffffff',
        textFontSize: 24,
        textAlign: 'center'
      }],
      textElements: [{
        id: 'label_exit',
        x: 50,
        y: 400,
        text: 'EXIT',
        fontSize: 16,
        color: '#ef4444'
      }]
    },
    metadata: {
      name: 'Main Theater',
      totalSections: 1,
      totalRows: 1,
      totalSeats: 10,
      totalAreas: 1,
      totalPricingCategories: 2,
      exportedAt: '2024-01-15T10:30:00.000Z',
      dimensions: { width: 800, height: 600 }
    }
  }
}

Next Steps