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

# List free, bookable slots for a location and appointment type

> Computed from the same availability engine as the calendar and online booking, so a returned slot is one the practice would book. `visibility=online` (default) is the patient view: the location, appointment type and (if given) practitioner must be enabled for online booking, and every online-booking rule applies — minimum advance notice, months ahead, daily caps, online-only guides, clustering. `visibility=all` is the front-desk view: every open slot for practitioners who provide the service, subject only to physical capacity. Up to 50 slots are returned per day. Not to be confused with `practitioner_availabilities`, which are the raw working-hours records this is computed from. Book a slot with `POST /appointments` (`start`/`end`/`practitioner_id`; `group_master_id` for a group slot).



## OpenAPI

````yaml /openapi.json get /availability
openapi: 3.0.3
info:
  title: PracticeHub API
  version: 1.0.0
  description: >
    The canonical PracticeHub REST API. Every clinic account is a tenant
    addressed by the host the practice signs in on:
    `https://{clinic}.{region}.practicehub.io` (region host `neptune` London,
    `mercury` Frankfurt, `vulcan` Ohio, `jupiter` Singapore, `apollo` Sydney).


    ## Filtering

    List endpoints accept `?attribute=operator:value` with operators `eq`, `ne`,
    `gt`, `gte`, `lt`, `lte`, `null`, `not-null`, `like`, `contains`, `in`,
    `not-in`, `between` (`null`/`not-null` take no value; `in`, `not-in`,
    `between` take comma-separated values; `contains` is a case-insensitive
    substring match with no wildcards to escape). A value with no operator is an
    equality match. Only attributes marked filterable may be filtered (422
    otherwise).


    ## Metadata

    Every record carries an integrator-owned `metadata` object of string, number
    or boolean values (max 50 keys). Send `metadata` on create/update to merge
    keys (`null` removes a key) and filter with `?metadata[key]=operator:value`.


    ## Sorting & pagination

    `?sort=attr[,attr]:asc|desc` on sortable attributes; `?page=` and
    `?page_size=` (max 100). List responses wrap rows in `data` with `links` and
    `meta`.
servers:
  - url: https://{clinic}.{region}.practicehub.io/v3/api
    description: PracticeHub API — the host the practice signs in on
    variables:
      clinic:
        default: your-clinic
        description: The clinic subdomain
      region:
        default: neptune
        enum:
          - neptune
          - mercury
          - vulcan
          - jupiter
          - apollo
        description: >-
          The region host from the practice login URL: neptune (London), mercury
          (Frankfurt), vulcan (Ohio), jupiter (Singapore), apollo (Sydney)
security:
  - bearerAuth: []
tags:
  - name: Utility
    description: Liveness, identity and discovery
  - name: Availability
    description: Free, bookable slots — check before creating an appointment
  - name: Addresses
    description: The addresses resource
  - name: AppointmentTypes
    description: The appointment_types resource
  - name: Appointments
    description: The appointments resource
  - name: DeletedEntities
    description: The deleted_entities resource
  - name: Files
    description: The files resource
  - name: Invoices
    description: The invoices resource
  - name: LineItems
    description: The line_items resource
  - name: Locations
    description: The locations resource
  - name: Modalities
    description: The modalities resource
  - name: Numbers
    description: The numbers resource
  - name: PatientLogTags
    description: The patient_log_tags resource
  - name: PatientLogs
    description: The patient_logs resource
  - name: Patients
    description: The patients resource
  - name: PaymentAllocations
    description: The payment_allocations resource
  - name: PaymentMethods
    description: The payment_methods resource
  - name: Payments
    description: The payments resource
  - name: PractitionerAvailabilities
    description: The practitioner_availabilities resource
  - name: Practitioners
    description: The practitioners resource
  - name: ReferralSources
    description: The referral_sources resource
  - name: Resources
    description: The resources resource
paths:
  /availability:
    get:
      tags:
        - Availability
      summary: List free, bookable slots for a location and appointment type
      description: >-
        Computed from the same availability engine as the calendar and online
        booking, so a returned slot is one the practice would book.
        `visibility=online` (default) is the patient view: the location,
        appointment type and (if given) practitioner must be enabled for online
        booking, and every online-booking rule applies — minimum advance notice,
        months ahead, daily caps, online-only guides, clustering.
        `visibility=all` is the front-desk view: every open slot for
        practitioners who provide the service, subject only to physical
        capacity. Up to 50 slots are returned per day. Not to be confused with
        `practitioner_availabilities`, which are the raw working-hours records
        this is computed from. Book a slot with `POST /appointments`
        (`start`/`end`/`practitioner_id`; `group_master_id` for a group slot).
      operationId: availability
      parameters:
        - name: location_id
          in: query
          required: true
          description: Location to search
          schema:
            type: integer
        - name: appointment_type_id
          in: query
          required: true
          description: Appointment type to book
          schema:
            type: integer
        - name: practitioner_id
          in: query
          required: false
          description: Limit to one practitioner (omit for any)
          schema:
            type: integer
        - name: from
          in: query
          required: false
          description: >-
            Range start in the clinic timezone, `YYYY-MM-DD` or `YYYY-MM-DD
            HH:MM:SS` (default: start of today)
          schema:
            type: string
            example: '2026-09-01'
        - name: to
          in: query
          required: false
          description: >-
            Range end (inclusive; a date means the end of that day). Default 7
            days from `from`; at most 31 days
          schema:
            type: string
            example: '2026-09-07'
        - name: visibility
          in: query
          required: false
          description: Patient (`online`) or front-desk (`all`) view
          schema:
            type: string
            enum:
              - online
              - all
            default: online
        - name: max_per_day
          in: query
          required: false
          description: Cap on slots returned per day
          schema:
            type: integer
            minimum: 1
            maximum: 50
        - name: rescheduled_appointment_id
          in: query
          required: false
          description: >-
            When finding a new time for an existing appointment: its occupied
            time is treated as free for overlapping alternatives (its
            duration/columns are used), but its exact current start is not
            offered
          schema:
            type: integer
      responses:
        '200':
          description: Slots in the clinic timezone, earliest first
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Slot'
                  meta:
                    type: object
                    properties:
                      timezone:
                        type: string
                        example: Europe/London
                      from:
                        type: string
                        example: '2026-09-01 00:00:00'
                      to:
                        type: string
                        example: '2026-09-07 23:59:59'
                      visibility:
                        type: string
                        enum:
                          - online
                          - all
                      unavailable_dates:
                        type: array
                        items:
                          type: string
                          format: date
                        description: Dates in the range with no slots at all
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '422':
          description: >-
            Invalid input (`validation_failed`), unknown
            location/type/practitioner (`*_not_found`), or — for
            `visibility=online` — a location, appointment type or practitioner
            not enabled for online booking (`not_online_bookable`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    Slot:
      type: object
      description: >-
        A free, bookable time. Send start/end/practitioner_id (and
        group_master_id for a group slot) to POST /appointments.
      properties:
        start:
          type: string
          example: '2026-09-01 09:00:00'
          description: Clinic-local Y-m-d H:i:s
        end:
          type: string
          example: '2026-09-01 09:30:00'
        practitioner_id:
          type: integer
        practitioner_name:
          type: string
          nullable: true
        location_id:
          type: integer
        appointment_type_id:
          type: integer
        resource_id:
          type: integer
          nullable: true
          description: Resource (room/table) the slot sits on, in resource-view calendars
        type:
          type: string
          enum:
            - individual
            - group
        group_master_id:
          type: integer
          nullable: true
          description: >-
            For group slots: the session to join (POST /appointments with
            group_master_id)
        online_fee:
          type: number
          description: Online booking fee for the type, in the account currency
    Error:
      type: object
      required:
        - message
        - code
      properties:
        message:
          type: string
          description: Human-readable; may change — do not parse
        code:
          type: string
          description: >-
            Stable machine-readable code (snake_case), e.g. validation_failed,
            not_found, key_read_only, slot_unavailable, not_online_bookable,
            group_full, appointment_rule, billing_rule, idempotency_key_reused,
            rate_limited
        errors:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
          description: Present on validation failures, keyed by attribute
  responses:
    Unauthenticated:
      description: Missing or invalid credentials
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'API key from Developers → API Keys, sent as Authorization: Bearer <key>.'

````