# Bookings

A booking is a receipt. It records that somebody took a seat on a
calendar, for a range of time.

## Bookable, calendar, seat

- A **bookable** is what a site takes bookings for.
- A **calendar** is a line of time with a capacity and an IANA time zone.
- A **seat** is which of that capacity a booking took, from 0 upward.

One database constraint holds every capacity, because a booking records
its seat. A class of six needs no second mechanism.

## Holds

A booking that waits for money is a hold, and a hold is an expiry rather
than a status. There is no `expired` value. A held booking past its expiry
**is** expired, and every reader works that out rather than wait for a
writer.

The next write to that calendar sweeps the dead holds. An hourly job is
only tidy-up.

## The visitor's door

A visitor books from the site's own page, at `POST /b/{public_id}`. That
door is on the API surface, because the checks live there: the Turnstile
check, the CORS grant and the rule about the client's address.

Three reads sit beside it, and each is unauthenticated: the bookable, its
days, and its free slots.

Clave keeps a hash of the visitor's address and not the address.

## A calendar is archived, never deleted

The row a calendar holds is a receipt of what somebody booked. A booking
that points at nothing would stop holding its seat.

## Where mail goes

`notify_to` on a bookable takes the same rule a form takes: an address on
the account. Read [Forms](/concepts/forms).

A message the visitor asked for by booking is outside that rule. A visitor
is not a Clave user and never can be.

Read [Bookings](/api/bookings).

---

## Where this page sits

This is one page of the Clave documentation.
Read it as a web page at https://docs.heyclave.party/concepts/bookings.
Every page has a `.md` address, and https://docs.heyclave.party/llms.txt lists them all.

- Previous: [Forms](https://docs.heyclave.party/concepts/forms.md)
- Next: [Payments](https://docs.heyclave.party/concepts/payments.md)
- Index: [Overview](https://docs.heyclave.party/index.md)
