booking_outside_bookable_hours
POST /v1/calendar/events named a time the tenant's bookable-hours policy does not admit - outside its open weekday windows, inside its minimum lead time, or past its booking horizon (migration 0079). Enforced at booking and not only at check_calendar, because book_meeting takes an arbitrary start_time rather than a slot id and a caller can name a time the agent never offered. detail names the rule that refused. Nothing was created; offer a slot from a fresh availability check. Distinct from calendar_slot_unavailable, which means the hour was open and has since been taken - this one means the hour was never on offer. A tenant that has written no policy is judged by the shipped default: Monday-Friday, 09:00-17:00, two hours' notice, sixty days out, no buffer - read in the zone POST /v1/calendar/availability names, and at booking in the zone start_time's own UTC offset names (UTC when it carries none), so the hours an availability call offered are the hours the booking is judged against. contact_timezone is not consulted for this: it names the party being invited, renders the appointment and the invitation, and cannot redefine the tenant's own hours.
Problem shape
Every non-2xx response is an RFC 9457 application/problem+json body. The type URI below is stable and machine-matchable, so branch on the final path segment (the code) and treat the status as redundant confirmation. See the error-handling guide.
{
"type": "https://docs.vocapable.com/errors/booking_outside_bookable_hours",
"title": "…",
"status": 409,
"detail": "…",
"instance": "/v1/…"
}