Designer SDK API Reference
Complete API reference for the SeatSquirrel Designer SDK
Constructor Options
new SeatSquirrel.Designer(options)
| Option | Type | Required | Description |
|---|---|---|---|
container | string | HTMLElement | Yes | CSS selector or DOM element for the designer container |
onReady | function | No | Called when designer is ready to receive data |
onLayoutLoaded | function | No | Called when a layout is successfully loaded |
onExport | function | No | Important: Called when user clicks Export button |
onLayoutChanged | function | No | Called when unsaved changes status changes |
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 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.
| Property | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier |
name | string | Yes | Display name (e.g., "Adult", "VIP") |
slug | string | Yes | URL-safe identifier |
price | number | Yes | Price in your currency's smallest unit |
color | string | Yes | Hex color for visual representation |
customerNotes | string | No | Notes 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.
| Property | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier |
name | string | Yes | Display name (e.g., "Orchestra", "Balcony") |
SeatRow
A row of seats with positioning and labeling configuration. Seats are nested inside the row.
| Property | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier |
label | string | Yes | Row label (e.g., "A", "1", "AA") |
seatCount | number | Yes | Number of seats in row |
seatLabelType | 'numeric' | 'alphabetic-upper' | 'alphabetic-lower' | 'custom' | Yes | How seats are labeled |
seatLabelStart | number | string | No | Starting label (default: 1 or 'A') |
seatLabelOrder | 'forward' | 'reverse' | No | Label direction |
sectionId | string | No | Parent section ID |
entranceToUse | string | No | Preferred entrance for this row |
pricingCategoryIds | string[] | Yes | Pricing categories (inherited by seats) |
seats | Seat[] | Yes | Array of seats in this row |
drawing | RowDrawing | Yes | Position and curve data |
RowDrawing
| Property | Type | Required | Description |
|---|---|---|---|
startX | number | Yes | Row start X coordinate |
startY | number | Yes | Row start Y coordinate |
endX | number | Yes | Row end X coordinate |
endY | number | Yes | Row end Y coordinate |
curve | number | Yes | Curve factor (-1 to 1, 0 = straight) |
angle | number | Yes | Row angle in radians |
seatSpacing | number | No | Custom spacing between seats |
rowLabelPlacement | 'start' | 'end' | 'both' | 'none' | No | Where to show row labels |
Seat
An individual seat within a row.
| Property | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier |
rowId | string | Yes | Parent row ID |
indexInRow | number | Yes | Position index within the row (0-based) |
row | string | Yes | Row label (for display) |
number | string | Yes | Seat number/label |
pricingCategoryIds | string[] | Yes | Available pricing categories for this seat |
isAvailable | boolean | No | Whether seat can be booked |
isUnbookable | boolean | No | Permanently unbookable (e.g., removed) |
isAccessible | boolean | No | Wheelchair accessible |
hasRestrictedView | boolean | No | Has obstructed or limited view |
customLabel | string | No | Override 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.
| Property | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier |
name | string | Yes | Internal name |
displayLabel | string | No | Customer-facing label |
purchaseType | 'multiple-customer' | 'single-customer' | Yes | Multiple tickets vs. exclusive booking |
pricingMethod | 'per-person' | 'per-area' | Yes | Price per person or flat rate |
sectionId | string | No | Parent section ID |
pricingCategoryIds | string[] | Yes | Available pricing categories |
minOccupancy | number | No | Minimum people required |
maxOccupancy | number | Yes | Maximum capacity |
displayUnit | 'seat' | 'standing' | 'sofa' | null | No | How capacity is labeled |
entranceToUse | string | No | Preferred entrance |
showMaxOccupancy | boolean | No | Show capacity to customers |
showMinOccupancy | boolean | No | Show minimum to customers |
showOccupancyInfo | boolean | No | Show current availability |
isUnbookable | boolean | No | Permanently unavailable |
isAccessible | boolean | No | Wheelchair accessible |
hasRestrictedView | boolean | No | Has obstructed view |
currentOccupancy | number | No | Current bookings (for availability display) |
availableCount | number | No | Remaining capacity |
isBooked | boolean | No | Single-customer area: is it booked? |
bookedByCustomerId | string | No | Single-customer: who booked it |
locked | boolean | No | Prevent editing in designer |
drawing | AreaDrawing | Yes | Shape and visual properties |
AreaDrawing
| Property | Type | Required | Description |
|---|---|---|---|
shape | 'rectangle' | 'circle' | 'polygon' | 'custom' | Yes | Shape type |
shapeData | AreaShapeData | Yes | Shape-specific dimensions |
fill | string | Yes | Fill color (hex) |
stroke | string | No | Stroke color |
strokeWidth | number | No | Stroke width in pixels |
opacity | number | No | Opacity (0-1) |
rotation | number | No | Rotation in degrees |
scaleX | number | No | Horizontal scale |
scaleY | number | No | Vertical scale |
text | string | No | Text overlay |
textFontSize | number | No | Font size for text |
textX | number | No | Text X offset |
textY | number | No | Text Y offset |
textColor | string | No | Text color |
textAlign | 'left' | 'center' | 'right' | No | Text alignment |
AreaShapeData
Properties vary by shape type:
| Property | Type | Used By | Description |
|---|---|---|---|
x | number | All | X position |
y | number | All | Y position |
width | number | rectangle | Width |
height | number | rectangle | Height |
radius | number | circle (if equal radii) | Circle radius |
radiusX | number | circle (ellipse) | Horizontal radius |
radiusY | number | circle (ellipse) | Vertical radius |
sides | number | polygon | Number of sides (3-20) |
points | number[] | custom | Array of [x,y,x,y,...] points |
cornerRadius | number | rectangle | Rounded corner radius |
Drawing
Visual annotations that are not bookable (decorative shapes, labels, stage outlines).
| Property | Type | Required | Description |
|---|---|---|---|
backgroundColor | string | No | Canvas background color |
lines | Line[] | No | Line elements |
textElements | TextElement[] | No | Text labels |
rectangles | Rectangle[] | No | Rectangle shapes |
circles | Circle[] | No | Circle/ellipse shapes |
polygons | Polygon[] | No | Regular polygon shapes |
customShapes | CustomShape[] | No | Freeform shapes |
Line
| Property | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier |
points | number[] | Yes | [x1,y1,x2,y2,...] points |
strokeWidth | number | Yes | Line width |
strokeColor | string | Yes | Line color |
strokeStyle | 'solid' | 'dashed' | 'dotted' | Yes | Line style |
dashArray | number[] | No | Custom dash pattern |
opacity | number | Yes | Opacity (0-1) |
label | string | No | Optional label |
locked | boolean | No | Prevent editing |
closed | boolean | No | Connect last to first point |
TextElement
| Property | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier |
x | number | Yes | X position |
y | number | Yes | Y position |
text | string | Yes | Text content |
fontSize | number | Yes | Font size |
color | string | Yes | Text color |
bold | boolean | No | Bold text |
italic | boolean | No | Italic text |
rotation | number | No | Rotation in degrees |
scaleX | number | No | Horizontal scale |
scaleY | number | No | Vertical scale |
width | number | No | Text box width |
align | 'left' | 'center' | 'right' | No | Text alignment |
locked | boolean | No | Prevent editing |
Rectangle
| Property | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier |
x | number | Yes | X position |
y | number | Yes | Y position |
width | number | Yes | Width |
height | number | Yes | Height |
fill | string | Yes | Fill color |
cornerRadius | number | Yes | Corner radius |
stroke | string | No | Stroke color |
strokeWidth | number | No | Stroke width |
rotation | number | No | Rotation in degrees |
scaleX | number | No | Horizontal scale |
scaleY | number | No | Vertical scale |
opacity | number | No | Opacity (0-1) |
locked | boolean | No | Prevent editing |
text | string | No | Text overlay |
textFontSize | number | No | Text font size |
textX | number | No | Text X offset |
textY | number | No | Text Y offset |
textColor | string | No | Text color |
textAlign | 'left' | 'center' | 'right' | No | Text alignment |
Circle
Supports both circles (equal radii) and ellipses (different radiusX/radiusY).
| Property | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier |
x | number | Yes | Center X position |
y | number | Yes | Center Y position |
radiusX | number | Yes | Horizontal radius |
radiusY | number | Yes | Vertical radius |
fill | string | Yes | Fill color |
stroke | string | No | Stroke color |
strokeWidth | number | No | Stroke width |
rotation | number | No | Rotation in degrees |
scaleX | number | No | Horizontal scale |
scaleY | number | No | Vertical scale |
opacity | number | No | Opacity (0-1) |
locked | boolean | No | Prevent editing |
text | string | No | Text overlay |
textFontSize | number | No | Text font size |
textX | number | No | Text X offset |
textY | number | No | Text Y offset |
textColor | string | No | Text color |
textAlign | 'left' | 'center' | 'right' | No | Text alignment |
Polygon
Regular polygons (triangles, hexagons, etc.).
| Property | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier |
x | number | Yes | Center X position |
y | number | Yes | Center Y position |
radius | number | Yes | Distance to vertices |
sides | number | Yes | Number of sides (3-20) |
fill | string | Yes | Fill color |
stroke | string | No | Stroke color |
strokeWidth | number | No | Stroke width |
rotation | number | No | Rotation in degrees |
scaleX | number | No | Horizontal scale |
scaleY | number | No | Vertical scale |
opacity | number | No | Opacity (0-1) |
locked | boolean | No | Prevent editing |
text | string | No | Text overlay |
textFontSize | number | No | Text font size |
textX | number | No | Text X offset |
textY | number | No | Text Y offset |
textColor | string | No | Text color |
textAlign | 'left' | 'center' | 'right' | No | Text alignment |
CustomShape
Freeform shapes defined by arbitrary points.
| Property | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier |
x | number | Yes | Origin X position |
y | number | Yes | Origin Y position |
points | number[] | Yes | [x1,y1,x2,y2,...] points |
fill | string | Yes | Fill color |
stroke | string | No | Stroke color |
strokeWidth | number | No | Stroke width |
rotation | number | No | Rotation in degrees |
scaleX | number | No | Horizontal scale |
scaleY | number | No | Vertical scale |
opacity | number | No | Opacity (0-1) |
locked | boolean | No | Prevent editing |
text | string | No | Text overlay |
textFontSize | number | No | Text font size |
textX | number | No | Text X offset |
textY | number | No | Text Y offset |
textColor | string | No | Text color |
textAlign | 'left' | 'center' | 'right' | No | Text 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
- Designer Quick Start - Get started embedding the Designer
- Picker SDK Reference - API reference for the Picker SDK
- Self-Hosting Guide - Deploy SeatSquirrel on your own infrastructure