> ## Documentation Index
> Fetch the complete documentation index at: https://docs.anivahealth.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Availability

> Retrieve bookable slot starts for a single location

Returns the bookable slot starts for a single location across the requested window. Slots are
generated from the location's `open_hours`, with global / per-location blocked dates skipped and
already-booked Aniva test sessions subtracted, so the result reflects what your partners can
actually reserve client-side.

Requires the `test_sessions_schedule` scope. The location must also fall within your API key's location-group access context.

<Note>
  Use this endpoint instead of inferring availability from the static `open_hours` returned by [List
  Locations](/api/locations/list-locations) — only this endpoint accounts for live bookings and
  provider-side schedule changes.
</Note>

<Info>
  Responses are returned with `Cache-Control: private, max-age=30, stale-while-revalidate=60`, so
  the browser may serve a cached payload for up to \~30 seconds. A slot booked inside that window can
  still appear bookable until the next refresh — surface conflicts at booking time as well.
</Info>

## Path parameters

<ParamField path="id" type="string" required>
  Location identifier (UUID). Use the `id` from [List Locations](/api/locations/list-locations).
</ParamField>

## Query parameters

<ParamField query="start_date" type="string">
  Inclusive start of the window in `YYYY-MM-DD` (interpreted in `timezone`). Optional. Defaults to
  **today** when neither date is supplied, or to **`end_date − 30 days`** when only `end_date` is
  supplied. Past dates are silently clamped to today.
</ParamField>

<ParamField query="end_date" type="string">
  Inclusive end of the window in `YYYY-MM-DD` (interpreted in `timezone`). Optional. Defaults to
  **today + 30 days** when neither date is supplied, or to **`start_date + 30 days`** when only
  `start_date` is supplied. Must be on or after `start_date` and within 90 days of today.
</ParamField>

<ParamField query="timezone" type="string">
  IANA timezone (e.g. `Europe/Berlin`) used to interpret `start_date` / `end_date` and to group
  slots by calendar date. Optional — defaults to the location's own timezone. Slot start times
  themselves are always rendered as UTC instants (`Z`); the timezone only affects which calendar day
  a slot is grouped under.
</ParamField>

## Response

On success, the API returns `200 OK` with a single availability object.

<ResponseField name="location_id" type="string" required>
  Echoed location identifier.
</ResponseField>

<ResponseField name="timezone" type="string">
  IANA timezone used to render the response (e.g., `Europe/Berlin`) — echoes the `timezone` query
  param when supplied, otherwise the location's timezone. May be `null` if unknown.
</ResponseField>

<ResponseField name="slot_interval_minutes" type="integer">
  Spacing between consecutive bookable slot starts in minutes. The location-configured grid step —
  every slot in `availability` falls on this grid. `null` only when the location has no scheduling
  configuration. **Not a session-duration window:** overlapping bookings at different starts do not
  conflict; only exact-start collisions count toward concurrency.
</ResponseField>

<ResponseField name="availability" type="array" required>
  Per-day bookable slots. Days with zero bookable slots are omitted to keep the payload tight.
  Each entry has:

  <Expandable title="per-day entry">
    <ResponseField name="date" type="string" required>
      Calendar date in the response `timezone` (`YYYY-MM-DD`).
    </ResponseField>

    <ResponseField name="slots" type="array" required>
      Slot starts as UTC instants (ISO 8601 with `Z` suffix), ordered ascending.
    </ResponseField>
  </Expandable>
</ResponseField>

## Error responses

| Status | Description                                                                                                     |
| ------ | --------------------------------------------------------------------------------------------------------------- |
| `400`  | Invalid date or timezone format, `end_date` before `start_date`, or `end_date` more than 90 days in the future. |
| `403`  | Forbidden — missing `test_sessions_schedule` scope or location outside your access context.                     |
| `404`  | Location not found or inactive.                                                                                 |
| `500`  | Internal server error.                                                                                          |

<RequestExample>
  ```bash cURL theme={null}
  curl --request GET \
    --url 'https://anivahealth.com/api/v1/locations/b7e2d1f5-3c4a-4e8b-a2f1-9d0c1e2f3a4b/availability?start_date=2026-05-01&end_date=2026-05-07' \
    --header 'x-api-key: YOUR_API_KEY'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "location_id": "b7e2d1f5-3c4a-4e8b-a2f1-9d0c1e2f3a4b",
    "timezone": "Europe/Berlin",
    "slot_interval_minutes": 15,
    "availability": [
      {
        "date": "2026-05-04",
        "slots": ["2026-05-04T07:00:00Z", "2026-05-04T07:15:00Z", "2026-05-04T07:30:00Z"]
      },
      {
        "date": "2026-05-05",
        "slots": ["2026-05-05T06:00:00Z", "2026-05-05T06:15:00Z"]
      }
    ]
  }
  ```
</ResponseExample>
