Slots Endpoints
Get available appointment slots for products.
V1 Endpoint
GET /wc-appointments/v1/slots
Compute available appointment slots via product logic (non-indexed path).
Permissions: Public read. Non-readable products are filtered out.
Parameters:
| Parameter | Type | Description |
|---|---|---|
product_ids | array|int | Product IDs to include (also accepts singular product_id) |
category_ids | array|int | Category IDs to include (also accepts singular category_id) |
staff_ids | array|int | Staff IDs to include (also accepts singular staff_id); see Staff IDs Architecture |
min_date | string | Date window start (YYYY-MM-DD) |
max_date | string | Date window end (YYYY-MM-DD) |
get_past_times | bool | Include past times |
page | int | Pagination page number |
limit | int | Results per page |
hide_unavailable | bool | Exclude results with available = false |
Response Fields:
product_id(int)product_name(string)date(string,YYYY-MM-DD)timestamp(int, epoch seconds, V1 omits when not applicable)duration(int)duration_unit(string)available(bool)scheduled(int, quantity)staff_id(int|null)
Notes:
- Honors product configuration: duration, interval, padding, min/max dates, restricted days, staff assignment
- Avoids deep nesting and favors early returns for performance internally
Example Request:
GET /wp-json/wc-appointments/v1/slots?product_ids=123&min_date=2025-01-01&max_date=2025-01-31
Example Response:
[
{
"product_id": 123,
"product_name": "Haircut",
"date": "2025-01-15",
"timestamp": 1736966400,
"duration": 60,
"duration_unit": "minute",
"available": true,
"scheduled": 0,
"staff_id": 5
}
]
V2 Endpoint
GET /wc-appointments/v2/slots
Same as V1 but uses cached/indexed implementations when available and within cache horizon.
Permissions: Public read; filters out non-readable products.
Parameters:
| Parameter | Type | Description |
|---|---|---|
product_ids | array|int | Product IDs to include (also accepts singular product_id) |
category_ids | array|int | Category IDs to include (also accepts singular category_id) |
staff_ids | array|int | Staff IDs to include (also accepts singular staff_id); see Staff IDs Architecture |
min_date | string | Date window start (YYYY-MM-DD) |
max_date | string | Date window end (YYYY-MM-DD) |
min_timestamp | int | Start timestamp (epoch seconds) |
max_timestamp | int | End timestamp (epoch seconds) |
get_past_times | bool | Include past times |
page | int | Pagination page number |
per_page | int | Results per page (preferred) |
limit | int | Alias for per_page (backwards compatible) |
hide_unavailable | bool | Exclude unavailable slots |
combine_staff | bool | Union across staff so each timestamp appears once per product with summed remaining capacity |
paged_stream | bool | Page-aware, day-by-day generation that stops early after page * per_page records; only active when combine_staff = true and pagination is requested |
Response:
{
"records": [
{
"product_id": 123,
"product_name": "Haircut",
"date": "2025-01-15",
"timestamp": 1736966400,
"duration": 60,
"duration_unit": "minute",
"available": true,
"scheduled": 0,
"staff_id": 5
}
],
"count": 1
}
Response Fields:
records(array): Array of slot objectscount(int): Total number of records
Slot Object Fields:
product_id(int)product_name(string)date(string,YYYY-MM-DD)timestamp(int, epoch seconds)duration(int)duration_unit(string)available(bool)scheduled(int, quantity)staff_id(int|null)
Notes:
- Falls back to non-indexed path when outside cache window or when indexing is disabled
limitis a backwards-compatible alias forper_pageand is supported for existing clients- Use
combine_staff=trueto get union of all staff availability - Use
paged_stream=truewithcombine_staff=truefor efficient pagination
Example Requests:
Basic query:
GET /wp-json/wc-appointments/v2/slots?product_ids=123&min_date=2025-01-01&max_date=2025-01-31
With staff union:
GET /wp-json/wc-appointments/v2/slots?product_id=123&min_date=2025-01-01&max_date=2025-01-31&combine_staff=true&hide_unavailable=true
Paginated with timestamp range:
GET /wp-json/wc-appointments/v2/slots?product_id=123&min_timestamp=1735689600&max_timestamp=1738195200&page=2&limit=25
Paged stream (efficient pagination):
GET /wp-json/wc-appointments/v2/slots?product_id=123&min_timestamp=1735689600&max_timestamp=1738195200&per_page=10&page=1&combine_staff=true&paged_stream=true
Differences: V1 vs V2
| Feature | V1 | V2 |
|---|---|---|
| Caching | No | Yes (when available) |
| Response Format | Array | Object with records and count |
| Timestamp Parameters | No | Yes (min_timestamp, max_timestamp) |
| Staff Union | No | Yes (combine_staff) |
| Paged Stream | No | Yes (paged_stream) |
| Pagination | limit | per_page (or limit alias) |
Best Practices
- Use V2 for production - Better performance with caching
- Use timestamp parameters - More precise than date strings
- Use
combine_staff=true- When you don't need staff-specific slots - Use
paged_stream=true- For efficient pagination with large datasets - Set
hide_unavailable=true- To filter out unavailable slots - Cache results client-side - Reduce API calls
Related Documentation
- Staff IDs Architecture - Understanding staff_id vs staff_ids
- Index Endpoint - For precomputed availability
- Products Endpoints - Get product details
- Caching & Performance - Understanding cache behavior