List areas
Returns the organization’s bookable areas. Filter by club or sport to get just the padel courts.clubId(optional) - only return areas belonging to this clubsport(optional) - only return areas whose type lists this sport, for examplepadel
id as the areaId when creating a booking.
timezone is the IANA zone the gym keeps, and the one operatingHours are
expressed in. Convert a local wall time in it when you send startTime and
endTime - a booking sent in the wrong zone lands an hour out twice a year, at
the daylight-saving boundary, and looks correct the rest of the time. Map it once
when you map the courts.
Area availability
Returns everything you need to render a court’s calendar for a window: the club timezone, operating hours, the intervals already taken (busy), and ready-made
open slots with remaining capacity.
from(required) - window start, ISO date-timeto(required) - window end, ISO date-time, at most 31 days afterfromslotMinutes(optional) - slot granularity:15,30,60(default),90, or120
timezone- the IANA timezone theoperatingHoursare expressed in. Operating hours are per-weekday local times; slots are already resolved to absolute UTC instants for you (DST included), so preferslotsover re-deriving fromoperatingHours.slots- open slots computed from effective bookable hours (club ∩ area) minusbusy, honouringmaxConcurrentBookings.remainingis how many ofcapacityare still free;bookableisremaining > 0and no hard block.busyandoperatingHoursare still returned raw if you’d rather compute slots yourself. An area withmaxConcurrentBookingsgreater than 1 can hold that many overlapping bookings before a slot is full.busy[].subject- what holds the court for that interval:member_booking,class(a scheduled class holding its court),event, orarea_block(the gym closed the court for maintenance or a private hire). Same vocabulary asdetails.conflicts[].subjecton a refused booking, so an hour you cannot sell can be explained rather than shown as unattributed busy time. A class is a booking row underneath, sosubjectis the only thing that separates it from a customer’s reservation. No id or name is attached - an availability read is not a read of who booked. Use List bookings for the rows you may see.version- a consistency token (the highest change sequence for this area). Compare it to thesequenceon an availability webhook to know whether this read already reflects that change.
Conditional requests
The response sends anETag. Send it back as If-None-Match to get a cheap
304 Not Modified when nothing has changed - useful as a polling fallback where
you don’t run webhooks.
version, the window you
asked for, the slot size, and the shape of the response itself - so it changes
when we ship a new field, not only when a court’s availability moves. Store it
verbatim against the request that produced it and send it back unmodified; do not
parse it or rebuild it from version, or a release that adds a field will leave
you on a 304 and the old body.
Club availability grid
Render a whole club’s calendar in one request instead of one call per court.clubId (optional), sport (optional), from/to (required, ≤ 31 days), slotMinutes (optional).
cursor is the reconciliation cursor at read time - store it and pass it to the change feed to catch up later.
Availability change feed
Returns every availability change for your organization after a cursor, in order. Pair it with webhooks: webhooks push changes in near real time; this feed lets you catch up exactly after any missed delivery, so your calendar never drifts.since (required cursor; 0 for the start of retention), limit (optional, default 100, max 500).
cursor, apply each change by re-pulling
/availability for the affected area and window, then store the new cursor.
Keep paging while hasMore is true.
On first sync you have no cursor - do a full grid pull and start from the
cursor it returns (starting from 0 for a live club replays its whole
history). The feed serves a rolling history; if your cursor predates it
after a long outage, re-baseline with a full grid pull. Some changes (e.g.
area.updated) carry a coarse, wide from/to window rather than a single
slot - re-pull the whole window. See the
webhooks guide
for the full reconciliation flow.Availability is a snapshot. 1Club remains the source of truth: booking
creation re-checks availability atomically, so a slot that was open a moment
ago may be rejected if it was taken in between. Always handle a booking
rejection gracefully - and use webhooks
plus this feed to keep the snapshot fresh.
Area blocks
A block takes an area off the bookable schedule for a period: resurfacing, a holiday, a camp. Availability already reflects blocks, so a blocked slot simply won’t appear inslots. Read blocks directly when you want the reason and the period to show in your own calendar, or when migrating a schedule into 1Club.
A block with areaId: null is gym-wide: it blocks every area in its clubId. If you key your calendar by court, expand it against that gym’s areas.
List blocks
Requires theareas:read scope.
from(required) - window start, ISO date-timeto(required) - window end, at most 31 days afterfromclubId(optional) - only blocks for this clubareaId(optional) - only blocks affecting this area, gym-wide ones included
Create a block
Requires theareas:write scope.
Send areaId to close one court, and its gym is derived for you. To close a whole gym, send clubId and leave areaId out - one record rather than one per court, and areas added later are covered too.
startTime,endTime(required) - ISO date-times with offset.endTimemust be afterstartTime.areaId(optional) - the court to block. Omit or sendnullfor a gym-wide block.clubId- required whenareaIdis omitted ornull; otherwise derived from the area.note(optional) - up to 500 characters, shown on the gym’s schedule.
201 with the created block.
A block stops new bookings. Bookings already inside the period are not
cancelled, so migrate or cancel those separately if you need the period clear.
Delete a block
Requires theareas:write scope. Deleting a block reopens the period for booking.
{ "success": true }. A second delete of the same id returns 404.
Creating or deleting a block emits an availability change for every affected
area, so the
changes feed
and webhooks will tell you to
re-pull those courts. A gym-wide block emits one change per area in the gym.