> For the complete Lynkow documentation index in agent-friendly format, see [llms.txt](/llms.txt).

# List a bookable product's available slots

**Publié le** : 2026-08-19
**Catégorie** : Commerce

## `GET /products/:idOrSlug/availability`

**List a bookable product's available slots**

Returns the computed open slots for a PUBLISHED bookable product over a date range
(`?from=&to=`, both required, date-only), scoped to the `:siteId` in the URL and served
behind a required storefront publishable key. Optional `offeringId` selects a live
formula's effective duration and buffers while the offering-selection flag is on; an
invalid id returns 422 `OFFERING_NOT_FOUND`, and omitting it always keeps the normal
product/resource grid. An offering whose minimum party size exceeds the storefront party
maximum is treated as not selectable: its id resolves to that same 422 `OFFERING_NOT_FOUND`
(a buyer could never book it). With the offering flag off, the id is ignored so this
shipped route remains available. When the `reservations_resource_pools`
flag is on and the product has several interchangeable calendars, availability is the
UNION across the pool: a slot is `available` while ANY resource has room, and
`seatsRemaining` is the pool's total headroom (ADR-0038 decision F). With the flag off
(or a single-calendar product) it is the single calendar's availability, byte-for-byte
as before. Each slot carries its instants, an `available` flag (capacity + notice/advance
bounds folded in), and `seatsRemaining`; no internal capacity split, tenant, resource, or
booking field is surfaced. The notice/advance bounds are the product's EFFECTIVE booking
window: a service carrying a per-service override is bounded by that override rather than
by its calendar's window, unless the `reservations_per_product_window` kill-switch is
forced off. A missing / draft / archived / cross-tenant product, a
non-`bookable` product, and a product with no configured calendar all return an
identical 404 (no existence oracle). An inverted range is 422; an over-wide span is
clamped to `min(effective max advance, 62)` days (the widest effective advance window
across a pool), not rejected. The response echoes the effective window in `window: { from, to }`
(`to` is the clamped bound) so a client can tell a silently-narrowed span from a genuine
end of availability. Availability is real-time, so the response is not edge-cached.

> **Note:** This endpoint requires the e-commerce feature to be enabled on your site.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `idOrSlug` | path | string | Yes |  |
| `from` | query | string | Yes | Required. Start of the availability window, a calendar date (`YYYY-MM-DD`). Inclusive of this day. |
| `to` | query | string | Yes | Required. End of the availability window, a calendar date (`YYYY-MM-DD`). Inclusive of this day; an over-wide span is clamped to the maximum lookahead rather than rejected. |
| `partySize` | query | integer | No | Number of guests included in the reservation. Between 1 and 50 |
| `offeringId` | query | string | No | Reservation offering identifier (roff_ prefixed id). 1-200 characters |


### Responses

| Status | Description |
| --- | --- |
| `200` | Successful response |
| `401` | Missing or invalid storefront publishable key |
| `402` | The site subscription does not currently permit this operation |
| `403` | The storefront key origin is not allowed |
| `404` | Not found |
| `422` | Validation error |


---