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

# Search the EHR's appointment finder

> One search of the EHR's own appointment finder with every option it offers, grouped by provider and facility — the view staff see on the EHR's finder screen. It is the EHR's view, not the bookable one: Max AI holds and pending bookings are NOT subtracted, and override-only slots appear when `allowOverride=true`. Book from `GET /schedule/slots`, which applies both; a booking is re-checked against the EHR either way. Each group may be `truncated` (the EHR caps each provider per call; ModMed at 5 open days). Groups for providers or facilities Max AI has not mirrored are dropped and counted in `meta.unmappedGroupCount`. Options the EHR does not honour are a 400 naming the parameter (see `availabilitySearchOptions` on `GET /schedule/capabilities`); EHRs without a finder return 501 `capability_unsupported`. The search stops when the client disconnects and returns 502 `ehr_unavailable` if the EHR does not answer within 8 seconds.



## OpenAPI

````yaml /openapi-v2.json get /schedule/finder
openapi: 3.0.0
info:
  title: Max AI Public API
  description: API for third-party marketplace apps
  version: '2.0'
  contact: {}
servers:
  - url: https://api.maxcare.ai/v2
security: []
tags: []
paths:
  /schedule/finder:
    get:
      tags:
        - Schedule
      summary: Search the EHR's appointment finder
      description: >-
        One search of the EHR's own appointment finder with every option it
        offers, grouped by provider and facility — the view staff see on the
        EHR's finder screen. It is the EHR's view, not the bookable one: Max AI
        holds and pending bookings are NOT subtracted, and override-only slots
        appear when `allowOverride=true`. Book from `GET /schedule/slots`, which
        applies both; a booking is re-checked against the EHR either way. Each
        group may be `truncated` (the EHR caps each provider per call; ModMed at
        5 open days). Groups for providers or facilities Max AI has not mirrored
        are dropped and counted in `meta.unmappedGroupCount`. Options the EHR
        does not honour are a 400 naming the parameter (see
        `availabilitySearchOptions` on `GET /schedule/capabilities`); EHRs
        without a finder return 501 `capability_unsupported`. The search stops
        when the client disconnects and returns 502 `ehr_unavailable` if the EHR
        does not answer within 8 seconds.
      operationId: SchedulePublicController_findFinder
      parameters:
        - name: appointmentTypeId
          required: true
          in: query
          description: Appointment type ID (atp_…)
          schema:
            type: string
        - name: timeFrame
          required: true
          in: query
          description: >-
            Search mode. `first_available`: the earliest openings.
            `specific_date`: one clinic day (`date`). `time_frame`: within
            `offset` `offsetUnit` from today. `date_range`: `from`–`to`, both
            inclusive. A mode's own parameters are required and any other mode's
            parameters are refused.
          schema:
            example: date_range
            enum:
              - first_available
              - specific_date
              - time_frame
              - date_range
            type: string
        - name: facilityId
          required: false
          in: query
          description: >-
            Facility ID (fac_…). Repeat or comma-separate for several. Defaults
            to every facility on the EHR instance; facility-limited API keys
            must pass it.
          schema:
            type: string
        - name: providerIds
          required: false
          in: query
          description: >-
            Comma-separated provider IDs (prv_…). Applied to the EHR's answer:
            the finder itself always searches every provider.
          schema:
            type: string
        - name: date
          required: false
          in: query
          description: Clinic calendar day (YYYY-MM-DD). `specific_date` only.
          schema:
            example: '2026-11-02'
            type: string
        - name: from
          required: false
          in: query
          description: Window start (YYYY-MM-DD, inclusive). `date_range` only.
          schema:
            example: '2026-11-02'
            type: string
        - name: to
          required: false
          in: query
          description: >-
            Window end (YYYY-MM-DD, inclusive). `date_range` only; at most 120
            days after `from`.
          schema:
            example: '2026-11-15'
            type: string
        - name: offset
          required: false
          in: query
          description: How far ahead to search, in `offsetUnit`. `time_frame` only.
          schema:
            example: 2
            type: number
        - name: offsetUnit
          required: false
          in: query
          description: Unit of `offset`. `time_frame` only.
          schema:
            enum:
              - days
              - weeks
              - months
            type: string
        - name: weekday
          required: false
          in: query
          description: Only these weekdays. Repeat or comma-separate for several.
          schema:
            type: array
            items:
              type: string
              enum:
                - monday
                - tuesday
                - wednesday
                - thursday
                - friday
                - saturday
                - sunday
        - name: timeOfDay
          required: false
          in: query
          description: Part of the day. Defaults to `anytime`.
          schema:
            enum:
              - anytime
              - morning
              - afternoon
              - evening
            type: string
        - name: display
          required: false
          in: query
          description: >-
            Result order as the EHR presents it. Defaults to `by_provider`; the
            slots are the same.
          schema:
            enum:
              - by_provider
              - by_time
            type: string
        - name: durationMinutes
          required: false
          in: query
          description: >-
            Slot length in minutes (5–480). Defaults to the appointment type's
            default.
          schema:
            type: number
            example: 15
        - name: alternateDurations
          required: false
          in: query
          description: Let the type's alternate durations match. Defaults to `true`.
          schema:
            type: boolean
            example: true
        - name: allowOverride
          required: false
          in: query
          description: >-
            Also return slots that need a staff override; they carry
            `overrideAllowed: true`. Defaults to `false`.
          schema:
            example: false
            type: boolean
        - name: afterFirstAppointment
          required: false
          in: query
          description: >-
            Passed to the EHR's search as is; its effect is unverified. Defaults
            to `false`.
          schema:
            example: false
            type: boolean
        - name: bufferMinutes
          required: false
          in: query
          description: >-
            Passed to the EHR's search as is (0–240); presumably minutes kept
            free around booked appointments, effect unverified. Defaults to 0.
          schema:
            example: 0
            type: number
        - name: x-session-token
          required: false
          in: header
          description: >-
            The App Bridge token of the logged-in user (`maxcare.appToken()`),
            verified for this app and organization. With it the EHR is read
            through that user's own EHR login when they have a usable one on
            this EHR instance, else through the organization's system connector;
            without it, always the system connector. `meta.actingAs` says which.
            A token that does not verify is `401 authorizer_unverified`. Sent as
            a header so GET requests keep it out of URLs.
          schema:
            type: string
        - name: X-Organization-Id
          in: header
          required: true
          schema:
            type: string
          description: Target clinic organization ID
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FinderSuccessResponse'
        '400':
          description: Missing or invalid request parameter
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiBadRequestResponse'
        '401':
          description: Invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiUnauthorizedResponse'
        '403':
          description: Insufficient scope
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiForbiddenResponse'
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiNotFoundResponse'
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiRateLimitResponse'
        '501':
          description: >-
            This organization's EHR does not support the capability
            (`capability_unsupported`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiNotImplementedResponse'
        '502':
          description: EHR sync failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiBadGatewayResponse'
        '503':
          description: EHR integration unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiServiceUnavailableResponse'
      security:
        - api-key: []
components:
  schemas:
    FinderSuccessResponse:
      type: object
      properties:
        code:
          type: string
          description: Response code
          example: success
        data:
          $ref: '#/components/schemas/FinderData'
      required:
        - code
        - data
    PublicApiBadRequestResponse:
      type: object
      properties:
        code:
          type: string
          description: Error code
          example: bad_request
        message:
          type: string
          description: Human-readable error message
          example: '''id'' must be a valid UUID'
        trace_id:
          type: string
          description: Trace ID for debugging
          example: 550e8400-e29b-41d4-a716-446655440000
      required:
        - code
        - message
        - trace_id
    PublicApiUnauthorizedResponse:
      type: object
      properties:
        code:
          type: string
          description: Error code
          example: unauthorized
        message:
          type: string
          description: Human-readable error message
          example: Invalid or missing API key
        trace_id:
          type: string
          description: Trace ID for debugging
          example: 550e8400-e29b-41d4-a716-446655440000
      required:
        - code
        - message
        - trace_id
    PublicApiForbiddenResponse:
      type: object
      properties:
        code:
          type: string
          description: Error code
          example: forbidden
        message:
          type: string
          description: Human-readable error message
          example: Insufficient scope
        trace_id:
          type: string
          description: Trace ID for debugging
          example: 550e8400-e29b-41d4-a716-446655440000
      required:
        - code
        - message
        - trace_id
    PublicApiNotFoundResponse:
      type: object
      properties:
        code:
          type: string
          description: Error code
          example: not_found
        message:
          type: string
          description: Human-readable error message
          example: Resource not found
        trace_id:
          type: string
          description: Trace ID for debugging
          example: 550e8400-e29b-41d4-a716-446655440000
      required:
        - code
        - message
        - trace_id
    PublicApiRateLimitResponse:
      type: object
      properties:
        code:
          type: string
          description: Error code
          example: rate_limit_exceeded
        message:
          type: string
          description: Human-readable error message
          example: Rate limit exceeded. Maximum 1000 requests per 60 seconds.
        trace_id:
          type: string
          description: Trace ID for debugging
          example: 550e8400-e29b-41d4-a716-446655440000
      required:
        - code
        - message
        - trace_id
    PublicApiNotImplementedResponse:
      type: object
      properties:
        code:
          type: string
          description: Error code
          example: capability_unsupported
        message:
          type: string
          description: Human-readable error message
          example: This organization's EHR has no appointment finder.
        trace_id:
          type: string
          description: Trace ID for debugging
          example: 550e8400-e29b-41d4-a716-446655440000
      required:
        - code
        - message
        - trace_id
    PublicApiBadGatewayResponse:
      type: object
      properties:
        code:
          type: string
          description: Error code
          example: unexpected_integration_error
        message:
          type: string
          description: Human-readable error message
          example: EHR sync failed
        trace_id:
          type: string
          description: Trace ID for debugging
          example: 550e8400-e29b-41d4-a716-446655440000
      required:
        - code
        - message
        - trace_id
    PublicApiServiceUnavailableResponse:
      type: object
      properties:
        code:
          type: string
          description: Error code
          example: server_unresponsive
        message:
          type: string
          description: Human-readable error message
          example: EHR integration is not available for this note
        trace_id:
          type: string
          description: Trace ID for debugging
          example: 550e8400-e29b-41d4-a716-446655440000
      required:
        - code
        - message
        - trace_id
    FinderData:
      type: object
      properties:
        groups:
          type: array
          items:
            $ref: '#/components/schemas/FinderGroupResponse'
        meta:
          $ref: '#/components/schemas/FinderMetaResponse'
      required:
        - groups
        - meta
    FinderGroupResponse:
      type: object
      properties:
        providerId:
          type: string
          example: prv_35103413aaaa4bbbccccddddeeeeffff
        facilityId:
          type: string
          example: fac_2706aaaa4bbbccccddddeeeeffff1111
        timezone:
          type: string
          description: IANA zone of the facility
          example: America/Detroit
        truncated:
          type: boolean
          description: >-
            The EHR capped this group (ModMed returns at most 5 open days per
            provider per call); more availability exists beyond the last slot.
            Narrow or move the window to see it.
          example: false
        slots:
          type: array
          items:
            $ref: '#/components/schemas/FinderSlotResponse'
      required:
        - providerId
        - facilityId
        - timezone
        - truncated
        - slots
    FinderMetaResponse:
      type: object
      properties:
        actingAs:
          type: string
          description: >-
            `user`: the EHR was read through the `X-Session-Token` user's own
            EHR login. `system`: through the organization's system connector (no
            token, or the user has no usable personal login on this EHR
            instance).
          enum:
            - user
            - system
          example: user
        resolvedBy:
          type: string
          description: Which rule picked the EHR login, for support.
          enum:
            - personal_connector
            - facility_system_connector
            - org_system_connector
          example: personal_connector
        sourceKind:
          type: string
          enum:
            - live_read
          example: live_read
        strategy:
          type: string
          enum:
            - native
          example: native
        generatedAt:
          type: string
          example: '2026-10-26T12:00:00.000Z'
        unmappedGroupCount:
          type: number
          description: >-
            Groups the EHR returned for a provider or facility Max AI has not
            mirrored yet. They are dropped, never returned with an EHR id.
          example: 0
      required:
        - actingAs
        - resolvedBy
        - sourceKind
        - strategy
        - generatedAt
        - unmappedGroupCount
    FinderSlotResponse:
      type: object
      properties:
        startsAt:
          type: string
          description: ISO-8601 with the facility's offset
          example: '2026-10-26T08:15:00-04:00'
        endsAt:
          type: string
          description: ISO-8601 with the facility's offset
          example: '2026-10-26T08:30:00-04:00'
        durationMinutes:
          type: number
          example: 15
        remainingCapacity:
          type: number
          description: >-
            Open seats as the EHR counts them. Max AI holds and pending bookings
            are NOT subtracted.
          example: 1
        totalCapacity:
          type: number
          description: Seats the practice defines at this time
          example: 2
        overrideAllowed:
          type: boolean
          description: >-
            Bookable only with a staff override. Present only when
            `allowOverride=true` was requested.
          example: false
      required:
        - startsAt
        - endsAt
        - durationMinutes
        - remainingCapacity
        - totalCapacity
        - overrideAllowed
  securitySchemes:
    api-key:
      scheme: bearer
      bearerFormat: JWT
      type: http
      description: Marketplace API key

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.