> ## 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.

# What this organization's EHR supports

> Vendor capability for this organization, stated up front so an admin can validate a booking configuration at publish time instead of discovering a gap from a patient at 11pm. Every value is a fact about the EHR, never inferred from whether a particular response happened to be empty — a practice that has configured no visit reasons still reports `visitReasons: true` on an EHR that models them.



## OpenAPI

````yaml /openapi-v1.json get /schedule/capabilities
openapi: 3.0.0
info:
  title: Max AI Public API
  description: API for third-party marketplace apps
  version: '1.0'
  contact: {}
servers:
  - url: https://api.maxcare.ai/v1
security: []
tags: []
paths:
  /schedule/capabilities:
    get:
      tags:
        - Schedule
      summary: What this organization's EHR supports
      description: >-
        Vendor capability for this organization, stated up front so an admin can
        validate a booking configuration at publish time instead of discovering
        a gap from a patient at 11pm. Every value is a fact about the EHR, never
        inferred from whether a particular response happened to be empty — a
        practice that has configured no visit reasons still reports
        `visitReasons: true` on an EHR that models them.
      operationId: SchedulePublicController_getCapabilities
      parameters:
        - name: facilityId
          required: false
          in: query
          description: Facility ID (fac_…) selecting the EHR instance
          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/ScheduleCapabilitiesSuccessResponse'
        '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'
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiRateLimitResponse'
        '503':
          description: EHR integration unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiServiceUnavailableResponse'
      security:
        - api-key: []
components:
  schemas:
    ScheduleCapabilitiesSuccessResponse:
      type: object
      properties:
        code:
          type: string
          description: Response code
          example: success
        data:
          $ref: '#/components/schemas/ScheduleCapabilitiesData'
      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
    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
    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
    ScheduleCapabilitiesData:
      type: object
      properties:
        ehr:
          type: string
          description: The EHR backing this organization
          example: modmed
        slotSearchStrategy:
          type: string
          description: >-
            How slots are produced. `synthesized` means Max AI computes them and
            confirms each booking against the EHR; `native` means the EHR has a
            bulk availability endpoint. See the same field on `GET
            /schedule/slots` for what consumes capacity.
          enum:
            - native
            - synthesized
          example: synthesized
        visitReasons:
          type: boolean
          description: >-
            Whether the EHR models reason-for-visit as its own catalogue.
            `false` means `GET /visit-reasons` is always empty and a booking
            form should hide its reason picker — NOT that this practice has
            configured none.
          example: true
        calendarEvents:
          type: boolean
          description: >-
            Whether the EHR exposes standalone calendar events (blocks,
            vacation).
          example: true
        availabilityCompleteness:
          type: string
          description: >-
            Whether slot search returns the WHOLE truth or a floor. `complete`
            means an absent slot really is unavailable. `lower_bound` means real
            availability may exceed what is listed, because this EHR exposes no
            readable availability-template surface — fully-booked windows are
            invisible and per-window concurrency reads as 1. Under-offering
            cannot cause a double-book, but design your empty state accordingly:
            say 'none bookable online', not 'the practice is full'. Mirrors
            `meta.completeness` on every slot-search response.
          example: complete
          enum:
            - complete
            - lower_bound
        cancelReasons:
          type: boolean
          description: >-
            Whether the EHR has a cancellation-reason catalogue for `POST
            /appointments/{id}/cancel`.
          example: true
        nativeHolds:
          type: boolean
          description: >-
            Whether the EHR has a reservation primitive we can mint before a
            booking. `false` on every EHR today, which is why holds are
            ADVISORY: they stop two sessions on our side colliding, but a human
            booking directly in the EHR can still take the slot.
          example: false
        providerChangeOnReschedule:
          type: boolean
          description: >-
            Whether `PATCH /appointments/{id}` may move the appointment to a
            different provider. `false` on EZDerm, where the provider lives on
            the encounter's care team and a provider change is rejected rather
            than silently reinterpreted.
          example: true
        meta:
          $ref: '#/components/schemas/FreshnessMetaResponse'
      required:
        - ehr
        - slotSearchStrategy
        - visitReasons
        - calendarEvents
        - availabilityCompleteness
        - cancelReasons
        - nativeHolds
        - providerChangeOnReschedule
        - meta
    FreshnessMetaResponse:
      type: object
      properties:
        sourceSyncedAt:
          type: string
          description: >-
            When the underlying data was last synced from, or read from, the
            EHR. Null means complete sync coverage for the requested scope and
            dates is unknown. Read `sourceKind` before treating this as a lag
            measurement — on a live read it is the moment of the read itself, so
            `now - sourceSyncedAt` is always ~0 and measures nothing.
          nullable: true
          example: '2026-07-26T12:59:31.000Z'
        sourceKind:
          type: string
          enum:
            - live_read
            - mirror
          description: >-
            What `sourceSyncedAt` actually is. `live_read`: the endpoint went to
            the EHR for this request, so the timestamp is the read time and
            there is no lag to measure. `mirror`: the timestamp is a real sync
            watermark and `now - sourceSyncedAt` IS the lag. Slot searches use
            `mirror` unless strong consistency is requested. A consumer
            computing mirror lag must skip `live_read` responses rather than
            average a structural zero into its numbers.
          example: live_read
        maxStalenessSeconds:
          type: number
          description: The staleness this endpoint is designed to stay within, in seconds
          example: 60
        strongConsistency:
          type: boolean
          description: >-
            Whether the response bypassed caches and read the EHR live
            (`?consistency=strong`)
          example: false
      required:
        - sourceSyncedAt
        - sourceKind
        - maxStalenessSeconds
        - strongConsistency
  securitySchemes:
    api-key:
      scheme: bearer
      bearerFormat: JWT
      type: http
      description: Marketplace API key

````