Facility Hours
Configure operating hours for facility resources. Hours determine when resources are available for booking.
Last updated: 2026-01-26 Where to find it: Facilities API > Hours Who can use it: Developers, integrators Prerequisites: API credentials Help link: /facility-hours
Overview
Facility hours define weekly operating schedules. Hours can be configured at:
- Resource type level - Default hours for all resources of a type
- Resource level - Override for a specific resource
The availability service integrates hours into its calculations, blocking reservations outside operating hours.
Hours Properties
| Field | Type | Description |
|---|---|---|
tenantId | string | Required - Tenant scope |
clubId | string | Optional - Club scope |
resourceId | string | Optional - Specific resource override |
resourceType | ResourceType | Optional - Hours for a resource type |
dayOfWeek | number | 0-6 (Sunday=0, Monday=1, ... Saturday=6) |
opensAtMinutes | number | Minutes since midnight (e.g., 360 = 6:00 AM) |
closesAtMinutes | number | Minutes since midnight (e.g., 1320 = 10:00 PM) |
timeZone | string | IANA time zone (e.g., "Africa/Johannesburg") |
REST API
List Hours
GET /facility-hours?tenantId=1&clubId=10&resourceType=TENNIS_COURT
Query Parameters:
tenantId(required) - Tenant scopeclubId(optional) - Filter by clubresourceType(optional) - Filter by resource typeresourceId(optional) - Filter by specific resourcedayOfWeek(optional) - Filter by day (0-6)
Create or Update Hours (Upsert)
Hours are upserted by unique combination of (tenantId, clubId, resourceType/resourceId, dayOfWeek):
POST /facility-hours
Content-Type: application/json
{
"tenantId": "t-1",
"clubId": "c-1",
"resourceType": "TENNIS_COURT",
"dayOfWeek": 1,
"opensAtMinutes": 360,
"closesAtMinutes": 1320,
"timeZone": "Africa/Johannesburg"
}
Bulk Create Hours
Set hours for all days in one request:
POST /facility-hours/bulk
Content-Type: application/json
{
"tenantId": "t-1",
"clubId": "c-1",
"resourceType": "TENNIS_COURT",
"timeZone": "Africa/Johannesburg",
"hours": [
{ "dayOfWeek": 0, "opensAtMinutes": 420, "closesAtMinutes": 1200 },
{ "dayOfWeek": 1, "opensAtMinutes": 360, "closesAtMinutes": 1320 },
{ "dayOfWeek": 2, "opensAtMinutes": 360, "closesAtMinutes": 1320 },
{ "dayOfWeek": 3, "opensAtMinutes": 360, "closesAtMinutes": 1320 },
{ "dayOfWeek": 4, "opensAtMinutes": 360, "closesAtMinutes": 1320 },
{ "dayOfWeek": 5, "opensAtMinutes": 360, "closesAtMinutes": 1320 },
{ "dayOfWeek": 6, "opensAtMinutes": 420, "closesAtMinutes": 1200 }
]
}
Delete Hours
DELETE /facility-hours/:id?tenantId=1
GraphQL API
Query Hours
query FacilityHours {
facilityHours(filters: {
tenantId: "t-1"
clubId: "c-1"
resourceType: TENNIS_COURT
}) {
id
dayOfWeek
opensAtMinutes
closesAtMinutes
timeZone
}
}
Create Hours
mutation CreateFacilityHours {
createFacilityHours(data: {
tenantId: "t-1"
clubId: "c-1"
resourceType: TENNIS_COURT
dayOfWeek: 1
opensAtMinutes: 360
closesAtMinutes: 1320
timeZone: "Africa/Johannesburg"
}) {
id
dayOfWeek
}
}
Time Conversion
Convert times to minutes since midnight:
| Time | Minutes |
|---|---|
| 5:00 AM | 300 |
| 6:00 AM | 360 |
| 7:00 AM | 420 |
| 8:00 AM | 480 |
| 9:00 PM | 1260 |
| 10:00 PM | 1320 |
| 11:00 PM | 1380 |
Formula: hours * 60 + minutes
Example Configurations
Tennis Courts (6 AM - 10 PM weekdays, 7 AM - 8 PM weekends)
[
{ "dayOfWeek": 0, "opensAtMinutes": 420, "closesAtMinutes": 1200 },
{ "dayOfWeek": 1, "opensAtMinutes": 360, "closesAtMinutes": 1320 },
{ "dayOfWeek": 2, "opensAtMinutes": 360, "closesAtMinutes": 1320 },
{ "dayOfWeek": 3, "opensAtMinutes": 360, "closesAtMinutes": 1320 },
{ "dayOfWeek": 4, "opensAtMinutes": 360, "closesAtMinutes": 1320 },
{ "dayOfWeek": 5, "opensAtMinutes": 360, "closesAtMinutes": 1320 },
{ "dayOfWeek": 6, "opensAtMinutes": 420, "closesAtMinutes": 1200 }
]
Gym (5 AM - 10 PM weekdays, 6 AM - 8 PM weekends)
[
{ "dayOfWeek": 0, "opensAtMinutes": 360, "closesAtMinutes": 1200 },
{ "dayOfWeek": 1, "opensAtMinutes": 300, "closesAtMinutes": 1320 },
{ "dayOfWeek": 2, "opensAtMinutes": 300, "closesAtMinutes": 1320 },
{ "dayOfWeek": 3, "opensAtMinutes": 300, "closesAtMinutes": 1320 },
{ "dayOfWeek": 4, "opensAtMinutes": 300, "closesAtMinutes": 1320 },
{ "dayOfWeek": 5, "opensAtMinutes": 300, "closesAtMinutes": 1320 },
{ "dayOfWeek": 6, "opensAtMinutes": 360, "closesAtMinutes": 1200 }
]
Blackout Periods
For temporary closures (maintenance, events, holidays), use blackout periods instead of modifying hours.
Create Blackout
POST /facility-blackouts
Content-Type: application/json
{
"tenantId": "t-1",
"clubId": "c-1",
"resourceId": "r-42",
"startTime": "2026-01-20T08:00:00Z",
"endTime": "2026-01-20T12:00:00Z",
"reason": "Scheduled maintenance - filter cleaning"
}
Blackouts can be scoped to:
- A specific resource (
resourceId) - All resources of a type (
resourceType) - All resources at a club (neither
resourceIdnorresourceType)
List Blackouts
GET /facility-blackouts?tenantId=1&clubId=10&startFrom=2026-01-01T00:00:00Z
Delete Blackout
DELETE /facility-blackouts/:id?tenantId=1
Hours Precedence
When checking availability:
- Resource-specific hours (if defined for the resource)
- Resource type hours (if defined for the type at club level)
- Tenant-level type hours (if defined at tenant level)
- No restriction (if no hours are defined)
If hours are defined, reservations outside operating hours are rejected.
Expected outcome
- Operating hours are configured per resource type.
- Blackouts handle temporary closures.
- Availability respects configured hours.
Related
- Availability — Check availability
- Booking Rules — Booking constraints
- Facility Reservations — Book resources