Company-wide appointment endpoints for querying bookings across all customers, browsing the service catalog, and checking facilitator availability. All endpoints require the appointments:read scope.
For customer-scoped appointments, see Customers — Appointments.
List appointment bookings
GET /appointments/bookings
Scope: appointments:read
List all appointment bookings for the company, with optional filters.
Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
facilitator_id | string | No | Filter by facilitator (e.g. fac_5) |
customer_id | string | No | Filter by customer (e.g. cust_456) |
start_date | string | No | Start date filter (YYYY-MM-DD). Defaults to all dates. |
end_date | string | No | End date filter (YYYY-MM-DD) |
status | string | No | Filter by status: SCHEDULED, COMPLETED, NO_SHOW, CANCELLED. Default: excludes CANCELLED. |
page | number | No | Page number (default 0) |
pageSize | number | No | Items per page (default 30, max 100) |
Response:
{
"data": [
{
"id": "appt_123",
"type": "appointment",
"status": "SCHEDULED",
"customer": {
"id": "cust_456",
"type": "customer",
"firstname": "Jane",
"lastname": "Smith"
},
"service": {
"id": "svc_10",
"type": "service",
"name": "Sports Massage",
"option_name": "60 minutes"
},
"facilitator": {
"id": "fac_5",
"type": "facilitator",
"name": "Sarah Jones"
},
"datetime": "2026-03-15T14:00:00",
"tz": "Europe/London",
"duration_minutes": 60,
"payment": {
"method": "CARD",
"currency": "GBP",
"base100_price_paid": 4500,
"status": "PAID"
},
"notes": "",
"created_at": "2026-03-01T10:00:00"
}
],
"total": 42,
"page": 0,
"pageSize": 30
}
Payment union
The payment field varies by payment method:
Card payment:
{ "method": "CARD", "currency": "GBP", "base100_price_paid": 4500, "status": "PAID" }
Pass (credit) payment:
{ "method": "PASS", "currency": "CR", "credits_used": 1, "status": "PAID" }
Get a single appointment booking
GET /appointments/bookings/{id}
Scope: appointments:read
| Parameter | Type | Description |
|---|---|---|
id | string | Appointment ID (e.g. appt_123) |
The response has the same shape as a single item from the list endpoint above, wrapped in { "data": { ... } }.
List services
GET /appointments/services
Scope: appointments:read
Returns all active appointment services (the service catalog). No pagination — services are a small catalog. Deleted services are excluded.
Response:
{
"data": [
{
"id": "svc_10",
"type": "service",
"name": "Sports Massage",
"description": "Deep tissue massage for sports recovery",
"buffer_minutes": 15,
"active": true,
"options": [
{
"name": "30 minutes",
"duration_minutes": 30,
"base100_price": 3000,
"credits": 1,
"active": true
},
{
"name": "60 minutes",
"duration_minutes": 60,
"base100_price": 5000,
"credits": 2,
"active": true
}
]
}
]
}
optionsare sub-objects without separate IDsbuffer_minutesis the gap required between consecutive appointments for this service- Deleted options within a service are excluded
Get a single service
GET /appointments/services/{id}
Scope: appointments:read
| Parameter | Type | Description |
|---|---|---|
id | string | Service ID (e.g. svc_10) |
Returns the service even if deleted (when requested by ID explicitly). Response has the same shape as a single item from the list endpoint.
Facilitator availability
GET /appointments/availability/{id}
Scope: appointments:read
Get computed availability time slots for a specific facilitator.
| Parameter | Type | Description |
|---|---|---|
id | string | Facilitator ID (e.g. fac_5) |
Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
service_id | string | No | Service ID to apply buffer minutes (e.g. svc_10) |
date | string | Conditional | Single date (YYYY-MM-DD). Cannot combine with start_date/end_date. |
start_date | string | Conditional | Range start (YYYY-MM-DD). Must be paired with end_date. |
end_date | string | Conditional | Range end (YYYY-MM-DD). Must be paired with start_date. |
One of date or start_date+end_date is required.
Response:
{
"data": {
"facilitator_id": "fac_5",
"dates": [
{
"date": "2026-03-15",
"windows": [
{
"start_time": "09:00",
"end_time": "17:00",
"slots": [
{ "start": "09:00", "end": "09:15", "available": true },
{ "start": "09:15", "end": "09:30", "available": false }
],
"available_slots": 28,
"total_slots": 32
}
]
}
]
}
}
For date ranges, the response contains multiple entries in the dates array.
Slot logic
- Slots are 15-minute intervals within each facilitator availability window
- A slot is
available: falseif it overlaps with an existing booking (including buffer time) - If
service_idis provided, the service’sbuffer_minutesis added to each booking’s duration for overlap checks - Cancelled bookings are excluded from conflict checks
- If the facilitator has no availability windows for a date, that date returns an empty
windowsarray
