Slots not showing or calendar gaps
Hours vs calendars, services, dining engine, closures, and subscription paused booking.
Slots not showing or calendar gaps
Two different “hours” concepts
Settings → Business hours sets venue wide opening and weekly defaults. Calendar Availability at /dashboard/calendar-availability sets per calendar working hours, breaks, and similar for schedule backed models. If calendar hours are narrower than venue hours, online slots shrink.
Services must attach to working calendars
For unified scheduling, each service needs to be linked to calendar columns that are actually open on the day you test. A practitioner on leave or a calendar with no working hours that day produces empty grids.
Buffers, duration, and variants
Long buffers, long durations, or variant rules can remove most apparent slots. Temporarily reduce buffers in the service editor to confirm that was the cause.
Closures and exceptions
Settings → Business hours → Closures & special days edits venue wide blocks. Restaurant tiers can add Reduced capacity for table bookings. Always check the test date for overlapping blocks.
Dining tables need the service engine
When the primary model is table_reservation and the venue uses the service availability engine, /api/booking/availability returns 503 with a message that you need at least one active dining service under Dining Availability (/dashboard/availability). Until that exists, guests see no slots even if opening hours look fine.
Public booking paused by billing
The public page shows Online booking unavailable when billing rules block public booking APIs: Appointments Light while Plan is past_due, or any tier once the subscription has fully ended (cancelled with no remaining paid access).
Complimentary venues from superuser free billing are not blocked here. Fixing Settings → Plan (card, resubscribe, or invoice) clears the pause when the underlying status updates.
Overlapping rules
If a single calendar column mixes conflicting weekly patterns, simplify to one clear pattern, save, then reload the public page.