Availability
Two endpoints deal with whether a night can be sold, and the difference trips people up often enough to be worth one page.
/v1/calendar | /v1/blocks | |
|---|---|---|
| What it is | A projection | A resource |
| Answers | "Can I sell this night, and for how much?" | "Why is this night closed, and who closed it?" |
| Has ids | No — addressed by property + date | Yes |
| You can delete | Nothing | A block |
The calendar is a view, not a store
GET /v1/calendar merges four things into one row per property per date:
reservations, blocks, per-date overrides and the property defaults. That is the
whole point — you get the answer instead of four queries and a join:
Code
blocked_by tells you which of the four caused the closure: reservation,
block, stop_sell, or null when the night is sellable.
Because it is a projection, there is nothing to delete. Writing to it sets
per-date prices and restrictions, including stop_sell to close a night with no
further explanation.
Blocks are things
A block has an id, a reason, and an owner. Only the integration that created one may amend or delete it — your blocks are yours, and a staff-created block is readable but immutable through the API. None of that fits in a date-addressed grid, which is why blocks are their own resource rather than a calendar flag.
Code
Which one should I use?
Use a block when there is a real-world reason worth recording — an owner stay, maintenance, a hold. It survives as an explanation, and you can remove it later by id.
Use stop_sell on the calendar when you just want the night closed and the
reason does not matter, for example while you decide on pricing.
Use last_day_is_checkout on a block when the occupant leaves that morning: the
final date stops being a held night and stays sellable as an arrival. Getting
this wrong is the most common cause of "we lost a bookable night".

