This document is the source of truth for the API. All bodies are JSON.
The service starts with three rooms. Rooms cannot be created or changed.
| id | name | capacity |
|---|---|---|
mistborn |
Mistborn | 4 |
martian |
The Martian | 8 |
stormlight |
Stormlight | 12 |
200 — [{ "id": "mistborn", "name": "Mistborn", "capacity": 4 }, ...]
- Request times are ISO 8601 strings with an offset:
2026-10-14T09:00:00Zor2026-10-14T11:00:00+02:00. A time without an offset is invalid. - Response times are always UTC, in the form
2026-10-14T09:00:00Z. - A booking covers the half-open interval
[start, end). A booking that ends at 10:00 and a booking that starts at 10:00 do not overlap. startandendmust be on a 15-minute grid (minutes 00, 15, 30, 45; seconds 0).startmust be beforeend. The maximum duration is 4 hours.
Request:
{ "roomId": "mistborn", "title": "Weekly sync", "start": "2026-10-14T09:00:00Z", "end": "2026-10-14T10:00:00Z", "attendees": 3 }The service checks the request in this order:
- Body shape: all fields present,
titlea non-empty string,attendeesan integer >= 1, times valid ISO 8601 with an offset. Else422. - Room exists. Else
404. - Booking rules: the time rules above,
attendees <= capacity. Else422. - No overlap with an existing booking in the same room. Else
409.
Responses:
| Status | Body |
|---|---|
201 |
{ "id": "<string>", "roomId": "mistborn", "title": "Weekly sync", "start": "2026-10-14T09:00:00Z", "end": "2026-10-14T10:00:00Z", "attendees": 3 } |
404 |
{ "error": "room_not_found" } |
409 |
{ "error": "conflict", "conflictingBookingId": "<id>" } |
422 |
{ "error": "validation_failed", "message": "<text>" } |
Invalid JSON also gives 422.
| Status | Body |
|---|---|
204 |
(empty) |
404 |
{ "error": "booking_not_found" } |
Returns the free intervals of the room for the UTC day [date 00:00Z, next day 00:00Z). Intervals are sorted, do not overlap, and are not empty.
200:
{
"roomId": "mistborn",
"date": "2026-10-14",
"free": [
{ "start": "2026-10-14T00:00:00Z", "end": "2026-10-14T09:00:00Z" },
{ "start": "2026-10-14T10:00:00Z", "end": "2026-10-15T00:00:00Z" }
]
}| Status | Body |
|---|---|
404 |
{ "error": "room_not_found" } |
422 |
{ "error": "validation_failed", "message": "<text>" } — date missing or not a real YYYY-MM-DD date |
Use the provided freeSlots / free_slots function to compute free.