Booking
A booking is a single row in the booking table claiming a bookable_id for a window of time. It is the core transaction in the platform. Everything else, timeslots, claims, actions, calendars, exists in service of getting bookings created cleanly and read back accurately.
How a booking is made
A client posts a booking with a bookable_id, a schedule, and a name. The booking handler runs three checks before the row is written:
- The caller has
ACCESS_EXECUTEon the bookable. - The schedule sits inside the bookable's attached timeslots, if any. A booking outside the timeslot windows returns
409 Conflictwith"outside of defined timeslots". - The schedule does not overlap a non cancelled booking already on the bookable. An overlap returns
409 Conflictwith the colliding booking.
If all three pass, the row is inserted, the booking_created trigger fires, and any actions registered on the bookable for that event run.
Schedule
A booking carries a Schedule with available: false, since a booking consumes a window rather than opening one. The schedule supports a single occurrence or a recurrence pattern of any of the NimCal types, daily, weekly, monthly, yearly. A recurring booking lives as one row in the database; recurrence is expanded on read.
Members
A booking can carry members, the users who participate in the reservation. The user who created the booking is included automatically. Members are how participation is surfaced in calendars and notifications without giving every participant write access to the booking row.
Deletion and cancellation
DELETE /booking/{id} removes the booking. The window it occupied becomes free again. This fires the booking_deleted trigger.
PUT /booking/{id} with a status change marks the booking as cancelled and fires the booking_canceled trigger. The row stays in place. Use this when you want to record a cancellation in the client UI without removing the booking.
See Cancel a Booking for the call and the response shape.
Reading bookings
GET /booking and the scoped variants under /me, /user, /bookable, /bookable_type, /location and /organization return raw rows. Recurring bookings come back as one row; recurrence expands on read.
GET /booking/{id}/calendar expands a single booking's recurrence inside a queried window. See Calendar and Availability and List Bookings.
Booking triggers
| Trigger | When it fires |
|---|---|
booking_created | After the row is inserted |
booking_updated | When the booking is modified through PUT /booking/{id} |
booking_canceled | When the booking is cancelled through PUT /booking/{id} with a cancellation |
booking_deleted | When the booking is soft deleted through DELETE /booking/{id} |
booking_ended | When the booking's time window ends |
These route to bound actions on the bookable, up the location chain, and up the organization chain.
API
See the Booking tag for the full endpoint reference, request and response shapes, and the audit log.