{
  "openapi": "3.1.0",
  "info": {
    "title": "GetMax Public API",
    "description": "REST + JSON API for embedding a practice's provider directory, real-time availability, online booking and inbound referrals into websites, patient portals and partner applications. Authenticated with a single x-api-key header; every endpoint is scoped to the practice that owns the key.",
    "version": "1.1.0",
    "contact": {
      "name": "GetMax Developer Support",
      "email": "getmaxhealthcare@gmail.com",
      "url": "https://docs.getmaxhealthcare.com"
    },
    "license": {
      "name": "Terms of Service",
      "url": "https://portal.getmaxhealthcare.com/terms"
    }
  },
  "servers": [
    {
      "url": "https://evprod.getmaxhealthcare.com/api",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Providers",
      "description": "Provider directory and bookable availability"
    },
    {
      "name": "Booking",
      "description": "Patient verification, appointment creation, and patient-side management"
    },
    {
      "name": "Referrals",
      "description": "Inbound referrals through a partner link. Token-authenticated, no API key."
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "paths": {
    "/external/providers": {
      "get": {
        "tags": [
          "Providers"
        ],
        "summary": "List providers",
        "description": "Returns a paginated list of active, open-status providers for the practice owning the API key. Supports search and filtering.",
        "operationId": "listProviders",
        "parameters": [
          {
            "name": "search",
            "in": "query",
            "description": "Case-insensitive substring search across name, summary, and specialties.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "specialty",
            "in": "query",
            "description": "Filter by specialty. Repeat to pass multiple.",
            "required": false,
            "schema": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "insurance",
            "in": "query",
            "description": "Filter by insurance accepted. Repeat to pass multiple.",
            "required": false,
            "schema": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "modality",
            "in": "query",
            "description": "Filter by therapeutic modality. Repeat to pass multiple.",
            "required": false,
            "schema": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of providers",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProviderListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/external/providers/filters": {
      "get": {
        "tags": [
          "Providers"
        ],
        "summary": "Get available filter values",
        "description": "Returns distinct specialties, insurances, modalities, and states across the practice's active providers. Useful for populating filter dropdowns.",
        "operationId": "getProviderFilters",
        "responses": {
          "200": {
            "description": "Filter options",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FiltersResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/external/providers/{id}": {
      "get": {
        "tags": [
          "Providers"
        ],
        "summary": "Get a single provider",
        "description": "Returns a single provider by ID, scoped to the practice that owns the API key.",
        "operationId": "getProvider",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "24-character hex provider ID",
            "schema": {
              "type": "string",
              "pattern": "^[a-f0-9]{24}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Provider details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProviderResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/external/providers/{id}/availability": {
      "get": {
        "tags": [
          "Providers"
        ],
        "operationId": "getProviderAvailability",
        "summary": "Bookable availability",
        "description": "Bookable slots day by day for one provider, with the provider's existing appointments already removed. Slots sit on a 30-minute grid and are returned as HH:MM strings. The window may not exceed 60 days.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "First day, YYYY-MM-DD."
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Last day inclusive. Must be on or after `from`."
          },
          {
            "name": "visitType",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "In-Person",
                "Telehealth"
              ],
              "default": "In-Person"
            }
          },
          {
            "name": "duration",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 5,
              "maximum": 480,
              "default": 60
            },
            "description": "Slot length in minutes."
          }
        ],
        "responses": {
          "200": {
            "description": "Availability for the window.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AvailabilityResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing or malformed dates, reversed window, bad visitType or duration, or a range wider than 60 days.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown, revoked or expired API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks providers:availability.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Provider is not available for online booking.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Back off for Retry-After seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/external/booking/request-otp": {
      "post": {
        "tags": [
          "Booking"
        ],
        "operationId": "requestBookingOtp",
        "summary": "Email a verification code",
        "description": "Emails a code to a returning patient. Returns the same 200 whether or not a patient matched \u2014 a different answer would turn this into a way to test whether a given person is a patient at a given practice. Rate limited to 5/min.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email",
                  "dateOfBirth"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "dateOfBirth": {
                    "type": "string",
                    "format": "date"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Accepted, whether or not a patient matched.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Ok"
                }
              }
            }
          },
          "400": {
            "description": "email and dateOfBirth are required, or dateOfBirth is unparseable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown, revoked or expired API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks appointments:book.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Back off for Retry-After seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/external/booking/verify-otp": {
      "post": {
        "tags": [
          "Booking"
        ],
        "operationId": "verifyBookingOtp",
        "summary": "Exchange the code for a verification token",
        "description": "Returns a 30-minute token bound to both the patient and the practice. Rate limited to 10/min.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email",
                  "code"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "code": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Verified.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VerifyOtpResponse"
                }
              }
            }
          },
          "400": {
            "description": "Wrong or expired code.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown, revoked or expired API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks appointments:book.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Back off for Retry-After seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/external/booking/book": {
      "post": {
        "tags": [
          "Booking"
        ],
        "operationId": "createBooking",
        "summary": "Book an appointment",
        "description": "Send `verificationToken` for a returning patient, or a full `patient` block to create a new one. Availability is re-checked at write time, so a slot taken since your availability call returns 409 rather than double-booking a clinician. Rate limited to 5/min and 50/hour.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "providerId",
                  "scheduledDate",
                  "scheduledTime",
                  "consent"
                ],
                "properties": {
                  "providerId": {
                    "type": "string",
                    "description": "Provider must have public booking enabled."
                  },
                  "scheduledDate": {
                    "type": "string",
                    "format": "date"
                  },
                  "scheduledTime": {
                    "type": "string",
                    "pattern": "^[0-9]{2}:[0-9]{2}$",
                    "description": "Must match a slot's `time` from the availability call exactly."
                  },
                  "duration": {
                    "type": "integer",
                    "default": 60
                  },
                  "visitType": {
                    "type": "string",
                    "enum": [
                      "In-Person",
                      "Telehealth"
                    ],
                    "default": "In-Person",
                    "description": "Anything unrecognised falls back to In-Person."
                  },
                  "appointmentType": {
                    "type": "string"
                  },
                  "reasonForVisit": {
                    "type": "string"
                  },
                  "verificationToken": {
                    "type": "string",
                    "description": "Returning patients. Omit for the new-patient branch."
                  },
                  "patient": {
                    "$ref": "#/components/schemas/PatientInput"
                  },
                  "insurance": {
                    "$ref": "#/components/schemas/InsuranceInput"
                  },
                  "consent": {
                    "type": "object",
                    "required": [
                      "hipaa"
                    ],
                    "properties": {
                      "hipaa": {
                        "type": "boolean",
                        "enum": [
                          true
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Appointment created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BookingResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing required field, missing HIPAA consent, an appointment type this provider does not offer online, or an incomplete new-patient block.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Bad API key, or an invalid/expired verificationToken.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks appointments:book, or the verification token belongs to another practice.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Provider is not available for online booking, or the patient record was not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "The slot was taken between your availability call and this one. Re-fetch and re-offer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Back off for Retry-After seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/external/booking/manage/{token}": {
      "get": {
        "tags": [
          "Booking"
        ],
        "operationId": "getManagedAppointment",
        "summary": "Read an appointment by manage token",
        "description": "Patient-side management. The manage token is returned once, when the appointment is created \u2014 it is what lets a patient act without an account. Rate limited to 30/min across all three manage routes.",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The appointment.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Ok"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown, revoked or expired API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks appointments:manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Unknown, expired or already-used manage token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Back off for Retry-After seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/external/booking/manage/{token}/cancel": {
      "post": {
        "tags": [
          "Booking"
        ],
        "operationId": "cancelManagedAppointment",
        "summary": "Cancel an appointment",
        "description": "Patient-side management. The manage token is returned once, when the appointment is created \u2014 it is what lets a patient act without an account. Rate limited to 30/min across all three manage routes.",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [],
                "properties": {
                  "reason": {
                    "type": "string",
                    "description": "Optional. Recorded against the cancellation."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Cancelled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Ok"
                }
              }
            }
          },
          "400": {
            "description": "The appointment cannot be cancelled in its current state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown, revoked or expired API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks appointments:manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Unknown, expired or already-used manage token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Back off for Retry-After seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/external/booking/manage/{token}/reschedule": {
      "post": {
        "tags": [
          "Booking"
        ],
        "operationId": "rescheduleManagedAppointment",
        "summary": "Reschedule an appointment",
        "description": "Patient-side management. The manage token is returned once, when the appointment is created \u2014 it is what lets a patient act without an account. Rate limited to 30/min across all three manage routes.",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "scheduledDate",
                  "scheduledTime"
                ],
                "properties": {
                  "scheduledDate": {
                    "type": "string",
                    "format": "date"
                  },
                  "scheduledTime": {
                    "type": "string",
                    "pattern": "^[0-9]{2}:[0-9]{2}$"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Rescheduled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Ok"
                }
              }
            }
          },
          "400": {
            "description": "Missing or malformed new date/time.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "The new slot is no longer available.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown, revoked or expired API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Key lacks appointments:manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Unknown, expired or already-used manage token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Back off for Retry-After seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/external/refer/{token}": {
      "get": {
        "tags": [
          "Referrals"
        ],
        "operationId": "getReferralLink",
        "security": [],
        "summary": "Read a partner link",
        "description": "Confirms the token is live and names the practice and partner, so a form can identify itself. No API key.",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Link is live.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReferralLinkInfo"
                }
              }
            }
          },
          "404": {
            "description": "This referral link is not valid \u2014 unknown token, or the partner is inactive.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Referrals"
        ],
        "operationId": "submitReferral",
        "security": [],
        "summary": "Submit a referral",
        "description": "Creates the patient and the referral together. Every field is optional, but at least one of a name, a contact detail, a reason or an attachment must be present. Rate limited to 8/min.",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReferralInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Referral created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReferralCreated"
                }
              }
            }
          },
          "400": {
            "description": "Nothing identifying in the submission.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "This referral link is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Back off for Retry-After seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/external/refer/{token}/ai-parse": {
      "post": {
        "tags": [
          "Referrals"
        ],
        "operationId": "parseReferralDocument",
        "security": [],
        "summary": "Parse a referral document into form fields",
        "description": "Upload a photo or PDF (10 MB max), or paste text, and get structured field values back to prefill the form. Only images are read; other types are stored and attached with `fields: null` and a 200 \u2014 that is a normal outcome, not an error. Rate limited to 4/min.",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "PNG, JPG, WEBP, GIF or PDF. 10 MB max, one file."
                  }
                }
              }
            },
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "text": {
                    "type": "string",
                    "description": "Pasted referral text. Wins over an uploaded file and skips OCR."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Parsed, or stored-but-unreadable. Check `fields` for null.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AiParseResponse"
                }
              }
            }
          },
          "400": {
            "description": "Neither a file nor text was sent, or the file type is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "This referral link is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Back off for Retry-After seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "The document could not be read. The file is still stored and attachable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "AI assist is not configured. Fill the form in manually.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "GetMax API key, prefix 'gmax_', 45 characters. Obtained from the Developer dashboard."
      }
    },
    "schemas": {
      "Provider": {
        "type": "object",
        "properties": {
          "_id": {
            "type": "string",
            "description": "24-char hex provider ID"
          },
          "fullName": {
            "type": "string"
          },
          "profileImage": {
            "type": [
              "string",
              "null"
            ],
            "description": "Short-lived signed S3 URL"
          },
          "status": {
            "type": "string",
            "enum": [
              "Open"
            ]
          },
          "summary": {
            "type": "string"
          },
          "credentials": {
            "type": "string"
          },
          "specialties": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "therapeuticModalities": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "insurancesTaken": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "serviceTypes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "settingTypes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "genderIdentities": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "agesSeen": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "clientsNeeded": {
            "type": "number"
          },
          "interpretingServicesSupported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "availability": {
            "type": "string"
          },
          "statesOfPractice": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 2,
              "maxLength": 2
            }
          },
          "rating": {
            "type": "number",
            "minimum": 0,
            "maximum": 5
          },
          "primaryLocationId": {
            "type": [
              "string",
              "null"
            ]
          },
          "practice": {
            "type": "string"
          }
        }
      },
      "ProviderListResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "practice": {
            "type": "object",
            "properties": {
              "_id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "pagination": {
            "type": "object",
            "properties": {
              "total": {
                "type": "integer"
              },
              "page": {
                "type": "integer"
              },
              "limit": {
                "type": "integer"
              },
              "pages": {
                "type": "integer"
              }
            }
          },
          "providers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Provider"
            }
          }
        }
      },
      "ProviderResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "provider": {
            "$ref": "#/components/schemas/Provider"
          }
        }
      },
      "FiltersResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "object",
            "properties": {
              "specialties": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "insurances": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "modalities": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "states": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "message": {
            "type": "string"
          }
        }
      },
      "Ok": {
        "description": "Generic success envelope. Endpoint-specific data hangs off `data`.",
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "AvailabilityResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "object",
            "properties": {
              "providerId": {
                "type": "string"
              },
              "fromDate": {
                "type": "string",
                "format": "date"
              },
              "toDate": {
                "type": "string",
                "format": "date"
              },
              "visitType": {
                "type": "string",
                "enum": [
                  "In-Person",
                  "Telehealth"
                ]
              },
              "duration": {
                "type": "integer"
              },
              "days": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "date": {
                      "type": "string",
                      "format": "date"
                    },
                    "dayName": {
                      "type": "string",
                      "example": "Monday"
                    },
                    "slots": {
                      "type": "array",
                      "description": "Empty is a normal answer: fully booked, or not a working day.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "time": {
                            "type": "string",
                            "example": "09:00"
                          },
                          "endTime": {
                            "type": "string",
                            "example": "09:30"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "PatientInput": {
        "description": "New-patient branch. All four required fields must be present when no verificationToken is sent.",
        "type": "object",
        "required": [
          "firstName",
          "lastName",
          "dateOfBirth",
          "email"
        ],
        "properties": {
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "dateOfBirth": {
            "type": "string",
            "format": "date"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "phone": {
            "type": "string"
          }
        }
      },
      "InsuranceInput": {
        "description": "Optional throughout.",
        "type": "object",
        "properties": {
          "payerName": {
            "type": "string"
          },
          "memberId": {
            "type": "string"
          },
          "groupNumber": {
            "type": "string"
          },
          "planName": {
            "type": "string"
          },
          "planType": {
            "type": "string"
          }
        }
      },
      "VerifyOtpResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "verificationToken": {
            "type": "string",
            "description": "Valid 30 minutes. Bound to the patient and the practice."
          },
          "patient": {
            "type": "object",
            "properties": {
              "_id": {
                "type": "string"
              },
              "firstName": {
                "type": "string"
              },
              "lastName": {
                "type": "string"
              },
              "email": {
                "type": "string"
              },
              "dateOfBirth": {
                "type": "string"
              },
              "phone": {
                "type": "string"
              }
            }
          }
        }
      },
      "BookingResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "object",
            "properties": {
              "appointmentNumber": {
                "type": "string",
                "example": "APT-002417"
              },
              "manageToken": {
                "type": "string",
                "description": "Returned once. Keep it out of logs and analytics \u2014 it is the patient's only credential for this appointment."
              },
              "manageUrl": {
                "type": "string",
                "format": "uri"
              },
              "scheduledDate": {
                "type": "string",
                "format": "date-time"
              },
              "scheduledTime": {
                "type": "string",
                "example": "09:30"
              },
              "duration": {
                "type": "integer"
              },
              "visitType": {
                "type": "string"
              },
              "provider": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  }
                }
              },
              "practice": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      },
      "ReferralLinkInfo": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "practiceName": {
            "type": "string"
          },
          "partnerName": {
            "type": "string"
          },
          "organization": {
            "type": "string"
          }
        }
      },
      "ReferralAttachment": {
        "description": "Pass back verbatim from an ai-parse response. Do not construct one.",
        "type": "object",
        "properties": {
          "s3Key": {
            "type": "string"
          },
          "fileName": {
            "type": "string"
          },
          "fileType": {
            "type": "string"
          },
          "fileSize": {
            "type": "integer"
          },
          "sig": {
            "type": "string",
            "description": "Signature issued by ai-parse. Unsigned attachments are dropped on submit."
          }
        }
      },
      "ReferralInput": {
        "description": "Every field is optional, but at least one of a name, a contact detail, a reason or an attachment must be present. Address and insurance fields are flat top-level keys, not nested objects.",
        "type": "object",
        "properties": {
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "dateOfBirth": {
            "type": "string",
            "format": "date"
          },
          "phone": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "gender": {
            "type": "string"
          },
          "street": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "zipCode": {
            "type": "string"
          },
          "reason": {
            "type": "string",
            "description": "Why the patient is being referred. The single most useful field here."
          },
          "typeOfService": {
            "type": "string"
          },
          "preferredVisitType": {
            "type": "string"
          },
          "urgency": {
            "type": "string"
          },
          "referringProvider": {
            "type": "string"
          },
          "referringProviderNpi": {
            "type": "string"
          },
          "clinicalNotes": {
            "type": "string"
          },
          "notes": {
            "type": "string"
          },
          "payerName": {
            "type": "string"
          },
          "memberId": {
            "type": "string"
          },
          "groupNumber": {
            "type": "string"
          },
          "planName": {
            "type": "string"
          },
          "planType": {
            "type": "string"
          },
          "consentToContact": {
            "type": "boolean",
            "description": "Send true only if the patient actually agreed."
          },
          "attachments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReferralAttachment"
            }
          }
        }
      },
      "ReferralCreated": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "message": {
            "type": "string"
          },
          "referralNumber": {
            "type": "string",
            "example": "REF-001042"
          }
        }
      },
      "AiParseResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "fields": {
            "type": [
              "object",
              "null"
            ],
            "description": "Structured values for the form, or null when the document could not be read. Null is a normal outcome.",
            "additionalProperties": true
          },
          "attachment": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ReferralAttachment"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present even when parsing failed \u2014 the file is stored before it is read."
          },
          "message": {
            "type": "string",
            "description": "Human-readable explanation when `fields` is null."
          },
          "warning": {
            "type": [
              "string",
              "null"
            ],
            "description": "Set when the file could not be stored but the request otherwise succeeded. Show it."
          }
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "API key is missing, invalid, revoked, or expired.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found or does not belong to the calling practice.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded (1,000 requests per 15 minutes per IP).",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Seconds until limit resets"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    }
  },
  "externalDocs": {
    "description": "Full documentation",
    "url": "https://docs.getmaxhealthcare.com"
  }
}