Scheduling
Scheduling is how you define when your products are available for booking. This guide covers schedule templates, overrides, blackout windows, and how the system generates available time slots.
Overview
Availability is determined in two stages:
- Schedules define operating hours — when a site or product is open
- Slot generation carves bookable time slots within those hours using product-specific settings
Schedules use a layered approach with three components:
- Schedule Templates: Base recurring patterns (e.g., Monday–Friday 10:00–18:00)
- Schedule Overrides: Temporary modifications to templates (e.g., early close on Dec 24)
- Blackout Windows: Complete closures (maintenance, holidays)
Priority Order:
- Blackout windows (highest priority — blocks everything)
- Schedule overrides (replace templates for affected dates)
- Schedule templates (base availability)
Once effective operating hours are resolved, the product's slot generation settings determine the actual bookable time slots.
Schedule Scope
Schedules can be configured at different levels:
Site-Level Schedules
- Apply to all products at a site
- Default availability for the entire venue
- Useful for site-wide hours of operation
Product-Level Schedules
- Specific to individual products
- Override site-level schedules
- Different availability for different products
Resource-Level Schedules
- Control resource availability
- Independent from product schedules
- Used for resource-specific constraints
Schedule Templates
Schedule templates define recurring availability patterns.
Creating Schedule Templates
Required Information:
- Scope Type: Site or Product
- Scope ID: Which site or product
- Day of Week: Which day(s) this applies (0=Sunday, 6=Saturday)
- Start Time: When availability begins
- End Time: When availability ends
- Recurrence Kind: How it repeats
Recurrence Options:
Weekly:
- Repeats every week on selected days
- Most common pattern
- Example: Every Monday-Friday
Daily:
- Every day
- For consistent daily availability
None:
- One-time template
- For special cases
Template Configuration
Time Format:
- Times are in site's timezone
- Format: HH:MM (24-hour format)
- Example: "10:00" for 10:00 AM, "18:00" for 6:00 PM
Day Selection:
- Bitmask for multiple days
- 0 = Sunday, 1 = Monday, ..., 6 = Saturday
- Can select multiple days
Example Weekly Template:
Scope: Site (Main Venue)
Days: Monday, Tuesday, Wednesday, Thursday, Friday (days 1-5)
Start Time: 10:00
End Time: 18:00
Recurrence: Weekly
Result: Monday-Friday 10am-6pm, every week
Advanced Template Features
Recurrence Patterns:
- Annual: Repeat on specific dates each year
- Monthly: Repeat on specific days of month
- Custom: Complex recurrence rules
Recurrence Fields:
- byDay: Days of week (bitmask)
- byMonth: Specific months (array)
- byMonthDay: Days of month (array)
- exdates: Excluded dates (array)
Example Annual Pattern:
Event: Summer Hours
byMonth: [6, 7, 8] (June, July, August)
byDay: Monday-Sunday
Start Time: 09:00
End Time: 21:00
Result: Extended hours during summer months
Schedule Overrides
Overrides allow temporary modifications to schedule templates.
When to Use Overrides
Common Scenarios:
- Extended hours for special events
- Reduced hours for low-demand periods
- Early closures before holidays
- Late openings after events
- One-time special availability
Creating Overrides
Required Information:
- Scope Type: Site or Product
- Scope ID: Which site or product
- Date From: Start date of override
- Date To: End date of override
- Start Time: New start time (or keep template time)
- End Time: New end time (or keep template time)
Override Types:
Time Modification:
- Change start/end times
- Extend hours
- Reduce hours
- Keep same pattern, different times
Pattern Override:
- Completely different schedule
- Override specific days
- Temporary schedule changes
Example Override:
Template: Monday-Friday 10am-6pm
Override: December 24, 10am-2pm (early close)
Result: Regular hours except Dec 24 when it closes at 2pm
Override Recurrence
Overrides can also have recurrence patterns:
Recurring Overrides:
- Repeat override pattern
- Useful for seasonal changes
- Example: Summer hours every year
One-Time Overrides:
- Apply once for specific date range
- No recurrence
- Example: Special event hours
Blackout Windows
Blackout windows completely block availability for maintenance, holidays, or closures.
When to Use Blackouts
Common Uses:
- Maintenance: Equipment or venue maintenance
- Holidays: Public or company holidays
- Closures: Temporary or permanent closures
- Events: Private events blocking public bookings
- Weather: Weather-dependent closures
Creating Blackout Windows
Required Information:
- Scope Type: Site or Product
- Scope ID: Which site or product
- Kind: Type of blackout (maintenance, holiday, closure)
- Date From: Start date of blackout
- Date To: End date of blackout
- Start Time: Start time of blackout period
- End Time: End time of blackout period
Blackout Kinds:
Maintenance:
- Equipment or venue maintenance
- Scheduled maintenance windows
- Emergency repairs
Holiday:
- Public holidays
- Company holidays
- Special closure days
Closure:
- Temporary closures
- Permanent closures
- Other closure reasons
Event:
- Private events
- Exclusive use periods
- Special events
Blackout Examples
Maintenance Blackout:
Scope: Site (Main Venue)
Kind: Maintenance
Date From: 2025-01-15
Date To: 2025-01-15
Start Time: 14:00
End Time: 18:00
Result: Closed 2pm-6pm on Jan 15 for maintenance
Holiday Blackout:
Scope: Site (All Products)
Kind: Holiday
Date From: 2025-12-25
Date To: 2025-12-25
Start Time: 00:00
End Time: 23:59
Result: Completely closed on Christmas Day
Recurring Holiday:
Scope: Site (All Products)
Kind: Holiday
Date From: 2025-12-25
Date To: 2025-12-25
Recurrence: Annual (every December 25)
Result: Closed every Christmas Day
Slot Generation
The system automatically generates available time slots by combining two separate concepts:
- Schedules define when you're open — operating-hour windows for each day (e.g., "Monday 10:00–18:00")
- Product slot settings define how slots are carved within those windows (e.g., every 30 minutes, or at fixed times like 10:00 and 14:00)
These are configured in different places:
- Schedules are managed here in the Scheduling section (templates, overrides, blackouts)
- Slot settings are configured per product in Catalog → Products (Step 7)
How They Work Together
Schedule Templates ─┐
├─► Effective Hours ─► Slot Generation ─► Capacity Check ─► Available Slots
Schedule Overrides ─┤ (operating (product config (resources, (shown to
Blackout Windows ───┘ windows) carves slots) bookings) customers)
Step by step:
- The scheduling engine evaluates templates, overrides, and blackouts for each day to produce effective hours — the actual operating windows. If an override exists for a day, it replaces the template. Hard blackouts subtract time from the result.
- The product's slot policy (
intervalorfixed) determines how bookable slots are placed within each operating window. - Setup and cleanup buffers are calculated around each slot candidate.
- Resource availability and capacity are checked to determine which slots are actually bookable.
Example: An escape room product with:
- Schedule template: Monday–Friday, 10:00–18:00
- Slot policy:
fixed, fixed times:["10:00", "12:00", "14:00", "16:00"] - Duration: 90 minutes, setup: 15 min, cleanup: 15 min
Produces 4 bookable slots per weekday. The 16:00 slot ends at 17:30 (with cleanup at 17:45), which fits within the 18:00 closing time. If a blackout blocks 12:00–14:00 on a specific Wednesday, only the 10:00, 14:00, and 16:00 slots are generated that day.
Slot Policy
Every product uses one of two slot policies:
| Policy | Value | Description |
|---|---|---|
| Interval | interval | Slots are generated at regular intervals within operating hours (default) |
| Fixed | fixed | Slots are generated only at predefined times |
Interval Policy
Slots start at the beginning of each operating-hours window and repeat every slotIntervalMin minutes. This is the default policy.
| Setting | Type | Default | Description |
|---|---|---|---|
slotIntervalMin | integer | 30 | Minutes between consecutive slot start times |
Example: A product with 60-minute duration and slotIntervalMin: 30 operating from 09:00–17:00 generates slots at 09:00, 09:30, 10:00, ..., 16:00 (the last slot that fits before 17:00).
Fixed Policy
Slots are generated only at the exact times listed in fixedSlotTimes, provided they fall within the operating hours.
| Setting | Type | Default | Description |
|---|---|---|---|
fixedSlotTimes | string[] | — | Array of HH:mm times, e.g. ["10:00","12:00","14:00"] |
Example: A product with fixedSlotTimes: ["10:00","14:00","18:00"] and operating hours 09:00–17:00 generates slots at 10:00 and 14:00 only (18:00 is outside operating hours).
Setup & Cleanup Time
Products can define buffer time before and after each slot for preparation and teardown. These buffers are not visible to customers but are used internally to prevent overlapping resource usage.
| Setting | Type | Default | Description |
|---|---|---|---|
setupTime | integer | 0 | Minutes reserved before the slot starts |
cleanupTime | integer | 0 | Minutes reserved after the slot ends |
Timeline example for a 60-minute slot starting at 10:00 with 15 min setup and 10 min cleanup:
09:45 10:00 11:00 11:10
|-- setup --|------- slot (60 min) ------|-- cleanup --|
The total blocked time for resource allocation is setupTime + duration + cleanupTime (85 minutes in this example). When using interval policy, ensure slotIntervalMin accounts for these buffers to avoid resource conflicts.
How Slots Are Generated
Generation Process:
- System reads schedule templates for the product's site
- Applies overrides (modifies template hours)
- Applies blackout windows (blocks slots in affected periods)
- Generates slot candidates using the product's slot policy
- Calculates setup/cleanup buffers for each candidate
- Checks resource availability against the full blocked time
- Produces bookable slots with capacity
Slot Characteristics:
- Start time and end time (visible to customers)
- Setup start and cleanup end (internal, used for resource allocation)
- Duration matches product duration
- Capacity based on product/resource capacity
- Labels applied if configured
When Schedules Change
Slots are generated up to 60 days ahead by a daily background worker. When you change a schedule template, override, or blackout, the system automatically regenerates affected slots:
- Unbooked slots that no longer match the schedule are deleted and new ones created
- Booked slots that no longer match are kept but flagged as orphaned — they appear highlighted in the admin calendar for manual review
- New time slots created by the schedule change are generated immediately
What triggers regeneration:
| Change Type | Affected Range |
|---|---|
| Schedule template created/updated/deleted | Today to 60-day horizon (full regeneration) |
| Schedule override created/deleted | Override's date range only |
| Blackout window created/deleted | Blackout's date range only |
Orphaned slots:
When a booked slot falls outside the updated schedule, it becomes "orphaned":
- The booking is not cancelled — the customer's reservation is preserved
- The slot appears flagged in the admin calendar
- The admin can manually reschedule or cancel the booking if needed
- If the schedule is changed back, the orphan flag is automatically cleared
Manual regeneration:
You can also trigger slot regeneration manually via the API:
POST /api/v1/admin/schedules/regenerate/preview (dry-run)
POST /api/v1/admin/schedules/regenerate (execute)
Both accept scopeType, scopeId, and optional dateFrom/dateTo parameters.
Slot Display
In Customer Interface:
- Only available slots shown
- Blacked out periods hidden
- Capacity displayed
- Labels shown if applicable
In Admin Calendar:
- All slots visible (including setup/cleanup windows)
- Availability status shown
- Booking status displayed
- Capacity utilization shown
Schedule Hierarchy
When multiple schedules apply, the system resolves them in priority order:
Resolution Order
-
Blackout Windows (highest priority)
- Blocks all availability
- Overrides everything
-
Schedule Overrides
- Modify template schedules
- Take precedence over templates
-
Schedule Templates
- Base availability
- Lowest priority
-
Product-Level vs Site-Level
- Product-level schedules override site-level
- If both exist, product schedules apply
Resolution Examples
Example 1: Simple Hierarchy
Site Template: Monday-Friday 10am-6pm
Product Override: Monday 12pm-8pm (extended hours)
Result: Monday 12pm-8pm, Tuesday-Friday 10am-6pm
Example 2: With Blackout
Site Template: Monday-Friday 10am-6pm
Blackout: Wednesday 14:00-16:00 (maintenance)
Result: Monday-Friday 10am-6pm, except Wednesday 2pm-4pm blocked
Example 3: Complex Override
Site Template: Daily 10am-6pm
Override: December 24-26, 10am-2pm (holiday hours)
Blackout: December 25, all day (holiday closure)
Result:
- Dec 24: 10am-2pm
- Dec 25: Closed (blackout overrides)
- Dec 26: 10am-2pm
- Other days: 10am-6pm
Timezone Handling
All schedules respect site timezones.
Timezone Configuration
Site Timezone:
- Each site has an IANA timezone
- Example: "Europe/Helsinki", "America/New_York"
- All schedules use site's timezone
Storage:
- Schedules stored in site's local time
- Timestamps stored in UTC
- Display converted to site timezone
Daylight Saving Time:
- Handled automatically by timezone
- No manual DST adjustments needed
- System converts times correctly
Best Practices
Timezone Tips:
- Always verify site timezone is correct
- Use IANA timezone codes
- Test schedule display in different timezones
- Consider customer timezones in communications
Recurrence Patterns
Advanced recurrence allows complex scheduling patterns.
Recurrence Types
None:
- One-time schedule
- No repetition
- For special cases
Weekly:
- Repeats every week
- Most common pattern
- Select days of week
Annual:
- Repeats every year
- Same date each year
- Useful for holidays, seasonal patterns
Monthly:
- Repeats monthly
- Specific day of month
- Example: First Monday of each month
Recurrence Fields
byDay (Bitmask):
- Days of week (0=Sunday, 6=Saturday)
- Multiple days: combine values
- Example: 31 = Monday-Friday (1+2+4+8+16)
byMonth (Array):
- Specific months (1-12)
- Example: [6, 7, 8] = June, July, August
byMonthDay (Array):
- Days of month (1-31)
- Example: [1, 15] = 1st and 15th of each month
exdates (Array):
- Explicitly excluded dates
- Override recurrence for specific dates
- Example: Exclude Dec 25 from annual pattern
Schedule Validation
The system validates schedules to prevent conflicts and errors.
Conflict Detection
Template Conflicts:
- Multiple templates for same scope/time
- Overlapping time ranges
- System warns or prevents conflicts
Override Conflicts:
- Overlapping overrides
- Ambiguous availability
- Resolution required
Blackout Conflicts:
- Existing bookings in blackout period
- System warns about conflicts
- Options: prevent blackout or warn only
Validation Rules
Time Validation:
- Start time must be before end time
- Times must be valid (00:00-23:59)
- Date ranges must be valid
Scope Validation:
- Scope ID must exist
- Scope type must be valid
- Tenant isolation enforced
Date Validation:
- Date from must be before date to
- Dates must be valid
- Past dates allowed (for historical records)
Common Scheduling Scenarios
Scenario 1: Standard Business Hours
Setup:
- Site-level template
- Monday-Friday: 10:00-18:00
- Saturday: 09:00-20:00
- Sunday: Closed
Configuration:
Template 1: Days 1-5 (Mon-Fri), 10:00-18:00
Template 2: Day 6 (Saturday), 09:00-20:00
No template for Sunday (closed)
Scenario 2: Seasonal Hours
Setup:
- Base template: Daily 10:00-18:00
- Summer override: June-August, 09:00-21:00
- Holiday blackouts: Specific dates
Configuration:
Base Template: All days, 10:00-18:00
Override: byMonth [6,7,8], 09:00-21:00
Blackout: Dec 25, all day
Scenario 3: Product-Specific Hours
Setup:
- Site template: Daily 10:00-18:00
- Product A: Monday-Friday only
- Product B: Weekends only
Configuration:
Site Template: All days, 10:00-18:00
Product A Template: Days 1-5, 10:00-18:00
Product B Template: Days 0,6, 10:00-18:00
Troubleshooting
Slots Not Generating
Check:
- Schedule template is active
- Template dates include current date
- No blackouts blocking slots
- Resource availability
- Product is active
Common Issues:
- Template outside date range
- Blackout covering desired time
- Resource unavailable
- Product inactive
Wrong Time Slots
Check:
- Site timezone correct
- Schedule times in correct format
- Day selection correct
- Override not conflicting
Common Issues:
- Timezone mismatch
- Wrong day selection
- Override modifying unexpectedly
- Recurrence pattern incorrect
Conflicts Not Detected
Check:
- Validation enabled
- Conflicting schedules exist
- Scope correctly set
- Date ranges overlap
Resolution:
- Review conflict warnings
- Adjust schedule times
- Remove conflicting schedules
- Use overrides instead
Best Practices
Organization
- Start with Site Templates: Set base availability at site level
- Use Product Overrides: Override for product-specific needs
- Plan Blackouts Ahead: Schedule maintenance in advance
- Document Special Cases: Note why overrides exist
Maintenance
- Review Regularly: Check schedules monthly
- Remove Expired: Clean up old overrides
- Test Changes: Verify slots generate correctly
- Backup Before Changes: Important schedules should be documented
Efficiency
- Use Templates: Reuse templates for similar patterns
- Batch Operations: Create multiple schedules at once
- Recurrence Patterns: Use annual recurrence for holidays
- Hierarchy: Use site-level when possible
Next Steps
- Learn about Calendar to see schedules in action
- Review Catalog Management for product configuration
- Check Dashboard for schedule overview
- Explore Reports for availability analytics