Skip to content

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:

  1. The caller has ACCESS_EXECUTE on the bookable.
  2. The schedule sits inside the bookable's attached timeslots, if any. A booking outside the timeslot windows returns 409 Conflict with "outside of defined timeslots".
  3. The schedule does not overlap a non cancelled booking already on the bookable. An overlap returns 409 Conflict with 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

TriggerWhen it fires
booking_createdAfter the row is inserted
booking_updatedWhen the booking is modified through PUT /booking/{id}
booking_canceledWhen the booking is cancelled through PUT /booking/{id} with a cancellation
booking_deletedWhen the booking is soft deleted through DELETE /booking/{id}
booking_endedWhen 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.