Checking availability through the API
After reading this article you can ask the API whether one room or all rooms of a workspace are free in a window — with the list of conflicts, a lead time buffer, the effective turnaround time per room and the context you need to read the answer correctly.
With the GET /api/v1/availability endpoint your own system asks Univents whether a period is free: for a single room or for every room of a workspace. That lets your website, your planning tool or another system give an answer without creating a booking.
The statement is the same one the booking page and the assistant use: all events of your workspace count (drafts and options included; only cancelled, declined and archived ones do not), plus run-of-show items, room groups and blocked periods. Open enquiries do not hold a room — but you can include them as a provisional occupancy if you like.
Key and permission
You need an API key with the Read locations permission. You create it under Integrations → Developer → API keys — the setup is described in the API keys article. Send it with every request as Authorization: Bearer <key>. A key without that permission gets a refusal, not an empty result.
The request
GET /api/v1/availability?from=2026-10-01&to=2026-10-03 GET /api/v1/availability?from=2026-10-01T18:00&to=2026-10-01T23:00&location_id=<room id> GET /api/v1/availability?from=2026-10-01&to=2026-10-03&buffer_minutes=120&include_soft_holds=true
| Parameter | Required | Meaning |
|---|---|---|
from | yes | Start of the period. A date (2026-10-01) or a date with a time (2026-10-01T18:00). |
to | yes | End of the period, written the same way. A plain date means the whole day. |
location_id | no | This one room. Without it the answer covers every room of the workspace. |
buffer_minutes | no | Lead and follow-up time in minutes (setup, teardown). 0 (the default) checks the requested period literally. The value is a lower bound: if a room has its own Turnaround and cleaning time (minutes), the larger of the two values applies for that room, not the sum. The answer names the value that was used on each conflict (see effectiveBufferMinutes). |
include_soft_holds | no | Defaults to false: open, undecided enquiries do not count as occupied — exactly as when a booking is submitted. With true you see them as a provisional occupancy (soft_hold). |
Without a time zone, date and time are read in your workspace's time zone. If you append a Z or an offset (2026-10-01T18:00Z), the value is taken literally.
The answer
{
"available": false,
"window": {
"requested_from": "2026-10-01",
"requested_to": "2026-10-03",
"from": "2026-09-30T22:00:00.000Z",
"to": "2026-10-03T22:00:00.000Z",
"buffer_minutes": 120
},
"free_location_ids": ["…"],
"locationAvailable": false,
"conflicts": [
{
"type": "event_overlap",
"location_id": "…",
"from": "2026-10-02T15:00:00.000Z",
"to": "2026-10-02T22:00:00.000Z",
"confirmed": true
},
{
"type": "soft_hold",
"location_id": "…",
"from": null,
"to": null
}
],
"notes": ["Soft holds (open, non-archived requests) are counted per day …"]
}
available— free or not, across every room that was checked. When you asked for a single room,locationAvailableis added for that room.window— what was actually checked. With a buffer the window is wider on both sides than what you asked for;requested_from/requested_tostill show what you sent. The window shows yourbuffer_minutes; a room's turnaround time is not in it but on each conflict ineffectiveBufferMinutes.free_location_ids— the rooms that are free in the window.conflicts— what is in the way.typesays what it is:
type | Meaning |
|---|---|
event_overlap | An event sits inside the window. confirmed tells you whether it is confirmed yet. |
schedule_item_overlap | A run-of-show item (setup, teardown, delivery) occupies the room. |
group_cascade | Another room of the same room group is taken — the group is held as a whole. |
soft_hold | An open enquiry is pending. Only with include_soft_holds=true. |
capacity | The limit for parallel enquiries is reached within the window. |
blocked_period | A blocked period applies. location_id is null here when the block covers the whole workspace. |
effectiveBufferMinutes appears on an occupancy conflict as soon as a turnaround and cleaning time applied for that room: the value in minutes that was used — max(buffer_minutes, the room's turnaround time), at most 1440. If it is missing, the check ran without a buffer. It does not appear on blocked_period conflicts or on the request limit (capacity).
degraded— present only when part of the check could not be read. The answer is then not conclusive: do not treat it as a commitment, ask again.notes— the fine print you need in order to read the answer correctly; see below.
What the answer is not
- Not a booking. The call reserves nothing. Between the request and your booking another process can take the room — the booking itself checks again.
- No personal data. The answer names room identifiers and periods, no names, no contacts, no contact persons.
- No page-level limit. The limit for parallel enquiries is configured per booking page, and an API call has no page context. That is why it is not part of this answer — its absence is not a zero.
- The day that is not the minute. Blocked periods and (with
include_soft_holds=true) open enquiries are evaluated per calendar day in the workspace's time zone, while events are compared to the minute. That makes the result never more permissive than the booking page, but it can be stricter. Thenotesin the answer say so for the case at hand.
Error cases
| Response | Meaning |
|---|---|
400 | from/to are missing, unreadable or the wrong way round; location_id is not a valid identifier; buffer_minutes is negative or above 1440. The answer names the reason. |
401 | No key, or an unknown one. |
403 | The key does not have the Read locations permission. |
429 | Too many requests in a short time. |
An empty window or a typo in the date never turns into "free" — such requests are rejected. You find the full description of the endpoint, including all of its parameters, in the API reference at /api/v1/docs.