{
  "components": {
    "responses": {},
    "schemas": {
      "Address": {
        "properties": {
          "city": {
            "description": "City, or suburb in AU.",
            "nullable": true,
            "type": "string"
          },
          "country": {
            "description": "ISO 3166-1 alpha-2, where known (clinics only).",
            "nullable": true,
            "type": "string"
          },
          "line1": {
            "nullable": true,
            "type": "string"
          },
          "postal_code": {
            "nullable": true,
            "type": "string"
          },
          "state": {
            "nullable": true,
            "type": "string"
          }
        },
        "required": [
          "line1",
          "city",
          "state",
          "postal_code"
        ],
        "title": "Address",
        "type": "object"
      },
      "Appointment": {
        "description": "A booking at the clinic. Operational (appointments:read); `patient` also needs patients:read, and `notes` needs clinical_content:read and the clinic's opt-in for the app. A field the caller may not see is absent, not null.",
        "properties": {
          "appointment_type": {
            "nullable": true,
            "type": "string"
          },
          "booked_via": {
            "description": "manual, walk_in, phone, online, screening_queue, external_sync or internal. Treat an unknown value as manual.",
            "nullable": true,
            "type": "string"
          },
          "clinic": {
            "description": "clinic_…",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "end_at": {
            "format": "date-time",
            "type": "string"
          },
          "external_ids": {
            "items": {
              "$ref": "#/components/schemas/ExternalId"
            },
            "type": "array"
          },
          "id": {
            "description": "appt_… Opaque.",
            "type": "string"
          },
          "notes": {
            "description": "The clinic's booking notes. Clinical content: needs clinical_content:read and the clinic's opt-in for the app.",
            "nullable": true,
            "type": "string"
          },
          "object": {
            "description": "Always appointment.",
            "type": "string"
          },
          "patient": {
            "description": "pat_…, null for a booking with no patient. Needs patients:read.",
            "nullable": true,
            "type": "string"
          },
          "practitioners": {
            "description": "prac_… ids of the practitioners booked.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "start_at": {
            "format": "date-time",
            "type": "string"
          },
          "status": {
            "description": "booked, confirmed, arrived, in_progress, completed, cancelled or no_show. Treat an unknown value as booked.",
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "object",
          "clinic",
          "practitioners",
          "start_at",
          "end_at",
          "status",
          "appointment_type",
          "booked_via",
          "external_ids",
          "created_at",
          "updated_at"
        ],
        "title": "Appointment",
        "type": "object"
      },
      "AppointmentList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/Appointment"
            },
            "type": "array"
          },
          "has_more": {
            "type": "boolean"
          },
          "next_cursor": {
            "description": "Send as `cursor` for the next page; null on the last.",
            "nullable": true,
            "type": "string"
          },
          "object": {
            "description": "Always list.",
            "type": "string"
          }
        },
        "required": [
          "object",
          "data",
          "has_more",
          "next_cursor"
        ],
        "title": "AppointmentList",
        "type": "object"
      },
      "Clinic": {
        "description": "A clinic, which in Claro is one location. Operational.",
        "properties": {
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "country": {
            "description": "ISO 3166-1 alpha-2.",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "email": {
            "nullable": true,
            "type": "string"
          },
          "external_ids": {
            "items": {
              "$ref": "#/components/schemas/ExternalId"
            },
            "type": "array"
          },
          "id": {
            "description": "clinic_… Opaque.",
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "object": {
            "description": "Always clinic.",
            "type": "string"
          },
          "org": {
            "allOf": [
              {
                "$ref": "#/components/schemas/OrgRef"
              }
            ],
            "nullable": true
          },
          "phone": {
            "nullable": true,
            "type": "string"
          },
          "timezone": {
            "description": "IANA, e.g. Australia/Sydney.",
            "type": "string"
          }
        },
        "required": [
          "id",
          "object",
          "name",
          "org",
          "timezone",
          "country",
          "address",
          "phone",
          "email",
          "external_ids",
          "created_at"
        ],
        "title": "Clinic",
        "type": "object"
      },
      "ClinicList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/Clinic"
            },
            "type": "array"
          },
          "has_more": {
            "type": "boolean"
          },
          "next_cursor": {
            "description": "Send as `cursor` for the next page; null on the last.",
            "nullable": true,
            "type": "string"
          },
          "object": {
            "description": "Always list.",
            "type": "string"
          }
        },
        "required": [
          "object",
          "data",
          "has_more",
          "next_cursor"
        ],
        "title": "ClinicList",
        "type": "object"
      },
      "Error": {
        "description": "Every error, whatever its status.",
        "properties": {
          "error": {
            "properties": {
              "code": {
                "description": "The specific problem. Stable.",
                "type": "string"
              },
              "message": {
                "description": "For the developer. May change.",
                "type": "string"
              },
              "param": {
                "description": "The parameter or header at fault, if any.",
                "nullable": true,
                "type": "string"
              },
              "request_id": {
                "description": "This response's x-request-id. Quote it to support.",
                "nullable": true,
                "type": "string"
              },
              "type": {
                "description": "The class of problem: authentication_error, permission_error, invalid_request_error, idempotency_error, rate_limit_error or api_error. Treat an unknown value as api_error.",
                "type": "string"
              }
            },
            "required": [
              "type",
              "code",
              "message",
              "param",
              "request_id"
            ],
            "type": "object"
          }
        },
        "required": [
          "error"
        ],
        "title": "Error",
        "type": "object"
      },
      "Event": {
        "description": "One event, exactly as a webhook delivery of it carries it, plus `id`.\n`data` depends on `event`; every payload names its objects twice: the\ninternal references it has always carried (`clinic_id`, `patient_uuid`,\n`appointment_id`, `practitioner_id`, …) and, beside each, the public\nid you can fetch: `clinic_public_id` (GET /clinics/{id}),\n`patient_public_id` (GET /patients/{id}), `appointment_public_id`\n(GET /appointments/{id}) and `practitioner_public_id`\n(GET /practitioners/{id}). A public id is null when its reference is.\nWho the patient is (`patient_uuid`, `patient_public_id`) needs\npatients:read and is absent without it. Ignore keys you do not know:\nkeys are added without a new version.\n",
        "properties": {
          "data": {
            "additionalProperties": true,
            "description": "The event's details; see the description above.",
            "type": "object"
          },
          "event": {
            "description": "The event type: patient.created, patient.updated, note.created, note.updated, note.discarded, appointment.booked, appointment.updated, appointment.cancelled, appointment.completed or sale.completed. Skip a type you do not know.",
            "type": "string"
          },
          "id": {
            "description": "The delivery's `webhook-id` (`msg_…`), the same on every retry: dedupe on it.",
            "type": "string"
          },
          "occurred_at": {
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "event",
          "occurred_at",
          "data"
        ],
        "title": "Event",
        "type": "object"
      },
      "EventList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/Event"
            },
            "type": "array"
          },
          "has_more": {
            "type": "boolean"
          },
          "next_cursor": {
            "description": "Send as `cursor` for the next page. Returned on the last page too: poll with it for what happens next. Null only when nothing has been read yet.",
            "nullable": true,
            "type": "string"
          },
          "object": {
            "description": "Always list.",
            "type": "string"
          }
        },
        "required": [
          "object",
          "data",
          "has_more",
          "next_cursor"
        ],
        "title": "EventList",
        "type": "object"
      },
      "ExternalId": {
        "description": "This object's id in another system, as this clinic has linked it. An object may carry several, from several systems.",
        "properties": {
          "id": {
            "description": "That system's id, exactly as it gave it.",
            "type": "string"
          },
          "source": {
            "description": "The other system, e.g. cliniko, halaxy.",
            "type": "string"
          }
        },
        "required": [
          "source",
          "id"
        ],
        "title": "ExternalId",
        "type": "object"
      },
      "OrgRef": {
        "description": "The group a clinic belongs to.",
        "properties": {
          "id": {
            "description": "org_… Opaque.",
            "type": "string"
          },
          "name": {
            "nullable": true,
            "type": "string"
          }
        },
        "required": [
          "id",
          "name"
        ],
        "title": "OrgRef",
        "type": "object"
      },
      "Patient": {
        "description": "One clinic's record of a person. Clinical metadata; needs patients:read. Never carries government identifiers.",
        "properties": {
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "date_of_birth": {
            "format": "date",
            "nullable": true,
            "type": "string"
          },
          "email": {
            "nullable": true,
            "type": "string"
          },
          "external_ids": {
            "items": {
              "$ref": "#/components/schemas/ExternalId"
            },
            "type": "array"
          },
          "first_name": {
            "nullable": true,
            "type": "string"
          },
          "gender": {
            "description": "The patient's own words, where given.",
            "nullable": true,
            "type": "string"
          },
          "gender_identity": {
            "description": "Coded: man, woman, non_binary, different_term, prefer_not_to_say. Treat an unknown value as not given.",
            "nullable": true,
            "type": "string"
          },
          "id": {
            "description": "pat_… Opaque.",
            "type": "string"
          },
          "interpreter_required": {
            "nullable": true,
            "type": "boolean"
          },
          "last_name": {
            "nullable": true,
            "type": "string"
          },
          "middle_name": {
            "nullable": true,
            "type": "string"
          },
          "mobile": {
            "nullable": true,
            "type": "string"
          },
          "object": {
            "description": "Always patient.",
            "type": "string"
          },
          "preferred_language": {
            "nullable": true,
            "type": "string"
          },
          "preferred_name": {
            "nullable": true,
            "type": "string"
          },
          "pronouns": {
            "nullable": true,
            "type": "string"
          },
          "sex": {
            "nullable": true,
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "object",
          "first_name",
          "middle_name",
          "last_name",
          "preferred_name",
          "date_of_birth",
          "sex",
          "gender",
          "gender_identity",
          "pronouns",
          "email",
          "mobile",
          "address",
          "preferred_language",
          "interpreter_required",
          "external_ids",
          "created_at",
          "updated_at"
        ],
        "title": "Patient",
        "type": "object"
      },
      "PatientList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/Patient"
            },
            "type": "array"
          },
          "has_more": {
            "type": "boolean"
          },
          "next_cursor": {
            "description": "Send as `cursor` for the next page; null on the last.",
            "nullable": true,
            "type": "string"
          },
          "object": {
            "description": "Always list.",
            "type": "string"
          }
        },
        "required": [
          "object",
          "data",
          "has_more",
          "next_cursor"
        ],
        "title": "PatientList",
        "type": "object"
      },
      "Practitioner": {
        "description": "A clinician with a practitioner or prescriber membership at the clinic. Operational; needs practitioners:read.",
        "properties": {
          "email": {
            "nullable": true,
            "type": "string"
          },
          "external_ids": {
            "items": {
              "$ref": "#/components/schemas/ExternalId"
            },
            "type": "array"
          },
          "first_name": {
            "nullable": true,
            "type": "string"
          },
          "id": {
            "description": "prac_… The person's, the same at every clinic.",
            "type": "string"
          },
          "last_name": {
            "nullable": true,
            "type": "string"
          },
          "name": {
            "nullable": true,
            "type": "string"
          },
          "object": {
            "description": "Always practitioner.",
            "type": "string"
          },
          "practitioner_type": {
            "description": "e.g. doctor, nurse. Treat an unknown value as other.",
            "nullable": true,
            "type": "string"
          },
          "prescriber": {
            "description": "Prescribes at this clinic.",
            "type": "boolean"
          },
          "registrations": {
            "items": {
              "$ref": "#/components/schemas/Registration"
            },
            "type": "array"
          },
          "specialty": {
            "nullable": true,
            "type": "string"
          },
          "title": {
            "nullable": true,
            "type": "string"
          }
        },
        "required": [
          "id",
          "object",
          "name",
          "title",
          "first_name",
          "last_name",
          "practitioner_type",
          "specialty",
          "email",
          "registrations",
          "prescriber",
          "external_ids"
        ],
        "title": "Practitioner",
        "type": "object"
      },
      "PractitionerList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/Practitioner"
            },
            "type": "array"
          },
          "has_more": {
            "type": "boolean"
          },
          "next_cursor": {
            "description": "Send as `cursor` for the next page; null on the last.",
            "nullable": true,
            "type": "string"
          },
          "object": {
            "description": "Always list.",
            "type": "string"
          }
        },
        "required": [
          "object",
          "data",
          "has_more",
          "next_cursor"
        ],
        "title": "PractitionerList",
        "type": "object"
      },
      "Registration": {
        "description": "A professional register entry.",
        "properties": {
          "authority": {
            "description": "ahpra (AU) or npi (US). Treat an unknown value as other.",
            "type": "string"
          },
          "number": {
            "type": "string"
          }
        },
        "required": [
          "authority",
          "number"
        ],
        "title": "Registration",
        "type": "object"
      }
    },
    "securitySchemes": {
      "bearer": {
        "description": "An API key (claro_sk_live_au_…, claro_sk_live_us_…, claro_sk_test_…) or an OAuth access token.",
        "scheme": "bearer",
        "type": "http"
      }
    }
  },
  "info": {
    "description": "Claro's public API: a stable contract for partners, the clinic's own\ndevelopers and AI agents. Read-only in this version: clinics,\npractitioners, patients and appointments, and the events a webhook\nsubscription is sent.\n\n**Authentication.** An API key (`claro_sk_live_au_…` /\n`claro_sk_live_us_…`, or `claro_sk_test_…` on the sandbox) or an OAuth\naccess token, as `Authorization: Bearer …`. A signed-in app session is\nrefused.\n\n**One realm per credential.** Each realm (AU, US) is its own\ndeployment and database, at its own host: `https://api-au.claro.clinic`\nfor AU and `https://api-us.claro.clinic` for the US. A credential,\nand every id it sees, belongs to one realm; every response says\nwhich in `x-claro-realm`. An API key names its realm in its prefix;\nsent to the other realm's host it gets 421 `wrong_region`, with the\nright base URL in `param`.\n\n**One clinic per request.** Send the clinic's id (from `GET /clinics`)\nin the `Claro-Clinic` header. A credential that reaches one clinic may\nleave it out.\n\n**Data classes.** Operational data needs the resource's scope; who a\npatient is needs `patients:read`; clinical content needs\n`clinical_content:read` AND the clinic's opt-in for your app. A field\nyou may not see is absent, not null. Government identifiers (IHI,\nMedicare, DVA) are never returned.\n\n**Conventions.** Ids are opaque, prefixed strings. Lists are\ncursor-paginated (`limit`, `cursor`, `next_cursor`) and, where a\nresource records changes, filterable by `updated_since`. Every error\nhas one shape (`type`, `code`, `message`, `param`, `request_id`),\nincluding a path that does not exist (404 `route_not_found`) and a\nmethod a path does not take (405 `method_not_allowed`, with `Allow`).\nPOSTs accept `Idempotency-Key`. Responses carry `RateLimit-Limit`,\n`RateLimit-Remaining`, `RateLimit-Reset` and `RateLimit-Policy`.\nTreat an unknown value of any string field as its documented default:\nvalues are added without a new version.\n\nEvery read is audited and visible to the clinic.\n",
    "title": "Claro public API",
    "version": "2026-11-01"
  },
  "openapi": "3.0.0",
  "paths": {
    "/api/public/v1/appointments": {
      "get": {
        "callbacks": {},
        "description": "Appointments at the clinic, every status, oldest change first. Needs appointments:read.",
        "operationId": "ClaroWeb.PublicApi.V1.AppointmentController.index",
        "parameters": [
          {
            "description": "The clinic to read (`clinic_…` from GET /clinics). Required when the credential reaches more than one clinic; an API key reaches one and may leave it out.",
            "in": "header",
            "name": "Claro-Clinic",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Page size, 1 to 100. Default 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "`next_cursor` from the previous page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only records changed at or after this time (ISO 8601 with offset). Pages run oldest change first, so walking to the end and keeping the newest `updated_at` seen is a complete sync.",
            "in": "query",
            "name": "updated_since",
            "required": false,
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AppointmentList"
                }
              }
            },
            "description": "Appointments"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A parameter or header is invalid"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No valid machine credential"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential may not do this"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such object, or not one this credential reaches"
          },
          "421": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API key belongs to the other region (wrong_region); param is the base URL to use"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited; see Retry-After"
          }
        },
        "summary": "List appointments",
        "tags": [
          "Appointments"
        ]
      }
    },
    "/api/public/v1/appointments/{id}": {
      "get": {
        "callbacks": {},
        "operationId": "ClaroWeb.PublicApi.V1.AppointmentController.show",
        "parameters": [
          {
            "description": "The clinic to read (`clinic_…` from GET /clinics). Required when the credential reaches more than one clinic; an API key reaches one and may leave it out.",
            "in": "header",
            "name": "Claro-Clinic",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "An appointment id (`appt_…`).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Appointment"
                }
              }
            },
            "description": "Appointment"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A parameter or header is invalid"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No valid machine credential"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential may not do this"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such object, or not one this credential reaches"
          },
          "421": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API key belongs to the other region (wrong_region); param is the base URL to use"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited; see Retry-After"
          }
        },
        "summary": "Get an appointment",
        "tags": [
          "Appointments"
        ]
      }
    },
    "/api/public/v1/clinics": {
      "get": {
        "callbacks": {},
        "description": "The clinics this credential reaches, by id. Any valid credential may call it. updated_since is not supported: clinics do not record when they change.",
        "operationId": "ClaroWeb.PublicApi.V1.ClinicController.index",
        "parameters": [
          {
            "description": "Page size, 1 to 100. Default 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "`next_cursor` from the previous page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClinicList"
                }
              }
            },
            "description": "Clinics"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A parameter or header is invalid"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No valid machine credential"
          },
          "421": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API key belongs to the other region (wrong_region); param is the base URL to use"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited; see Retry-After"
          }
        },
        "summary": "List clinics",
        "tags": [
          "Clinics"
        ]
      }
    },
    "/api/public/v1/clinics/{id}": {
      "get": {
        "callbacks": {},
        "operationId": "ClaroWeb.PublicApi.V1.ClinicController.show",
        "parameters": [
          {
            "description": "A clinic id (`clinic_…`).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Clinic"
                }
              }
            },
            "description": "Clinic"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No valid machine credential"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such object, or not one this credential reaches"
          },
          "421": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API key belongs to the other region (wrong_region); param is the base URL to use"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited; see Retry-After"
          }
        },
        "summary": "Get a clinic",
        "tags": [
          "Clinics"
        ]
      }
    },
    "/api/public/v1/events": {
      "get": {
        "callbacks": {},
        "description": "The events one webhook subscription is sent (its clinic, its event types, from its creation on), oldest first, each exactly as its delivery carries it plus `id`, the delivery's `webhook-id`. Use it to catch up after downtime or replay. Needs events:read; who the patient is needs patients:read, and clinical content needs clinical_content:read, the clinic's opt-in for your app and a subscription that takes it. `next_cursor` is returned on the last page too: keep it and poll with it for what happens next. Events from the last few seconds wait for the next page, so a late commit is never skipped. Order is not a promise about the records: re-fetch them.",
        "operationId": "ClaroWeb.PublicApi.V1.EventController.index",
        "parameters": [
          {
            "description": "The clinic to read (`clinic_…` from GET /clinics). Required when the credential reaches more than one clinic; an API key reaches one and may leave it out.",
            "in": "header",
            "name": "Claro-Clinic",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The webhook subscription (`whsub_…`, its `public_id` in the webhook API) whose events to list. It must belong to the clinic.",
            "in": "query",
            "name": "subscription",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only these event types, comma-separated (e.g. `appointment.booked,appointment.cancelled`). Each must be one the subscription takes. Default: all of them.",
            "in": "query",
            "name": "type",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only events that occurred at or after this time (ISO 8601 with offset).",
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Page size, 1 to 100. Default 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "`next_cursor` from the previous page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventList"
                }
              }
            },
            "description": "Events"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A parameter or header is invalid"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No valid machine credential"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential may not do this"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such object, or not one this credential reaches"
          },
          "421": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API key belongs to the other region (wrong_region); param is the base URL to use"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited; see Retry-After"
          }
        },
        "summary": "List a webhook subscription's events",
        "tags": [
          "Events"
        ]
      }
    },
    "/api/public/v1/llms.txt": {
      "get": {
        "callbacks": {},
        "operationId": "ClaroWeb.PublicApi.V1.DocsController.llms",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "Plain text"
          }
        },
        "security": [],
        "summary": "This API described for language models (llms.txt)",
        "tags": [
          "Meta"
        ]
      }
    },
    "/api/public/v1/openapi.json": {
      "get": {
        "callbacks": {},
        "operationId": "ClaroWeb.PublicApi.V1.DocsController.openapi",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "The OpenAPI 3 document"
          }
        },
        "security": [],
        "summary": "This API's OpenAPI document",
        "tags": [
          "Meta"
        ]
      }
    },
    "/api/public/v1/patients": {
      "get": {
        "callbacks": {},
        "description": "Active patients at the clinic, oldest change first. Needs patients:read. Never includes government identifiers.",
        "operationId": "ClaroWeb.PublicApi.V1.PatientController.index",
        "parameters": [
          {
            "description": "The clinic to read (`clinic_…` from GET /clinics). Required when the credential reaches more than one clinic; an API key reaches one and may leave it out.",
            "in": "header",
            "name": "Claro-Clinic",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Page size, 1 to 100. Default 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "`next_cursor` from the previous page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only records changed at or after this time (ISO 8601 with offset). Pages run oldest change first, so walking to the end and keeping the newest `updated_at` seen is a complete sync.",
            "in": "query",
            "name": "updated_since",
            "required": false,
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PatientList"
                }
              }
            },
            "description": "Patients"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A parameter or header is invalid"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No valid machine credential"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential may not do this"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such object, or not one this credential reaches"
          },
          "421": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API key belongs to the other region (wrong_region); param is the base URL to use"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited; see Retry-After"
          }
        },
        "summary": "List patients",
        "tags": [
          "Patients"
        ]
      }
    },
    "/api/public/v1/patients/{id}": {
      "get": {
        "callbacks": {},
        "operationId": "ClaroWeb.PublicApi.V1.PatientController.show",
        "parameters": [
          {
            "description": "The clinic to read (`clinic_…` from GET /clinics). Required when the credential reaches more than one clinic; an API key reaches one and may leave it out.",
            "in": "header",
            "name": "Claro-Clinic",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A patient id (`pat_…`).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Patient"
                }
              }
            },
            "description": "Patient"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A parameter or header is invalid"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No valid machine credential"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential may not do this"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such object, or not one this credential reaches"
          },
          "421": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API key belongs to the other region (wrong_region); param is the base URL to use"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited; see Retry-After"
          }
        },
        "summary": "Get a patient",
        "tags": [
          "Patients"
        ]
      }
    },
    "/api/public/v1/practitioners": {
      "get": {
        "callbacks": {},
        "description": "Practitioners and prescribers at the clinic, by id. Needs practitioners:read. updated_since is not supported: memberships do not record when they change.",
        "operationId": "ClaroWeb.PublicApi.V1.PractitionerController.index",
        "parameters": [
          {
            "description": "The clinic to read (`clinic_…` from GET /clinics). Required when the credential reaches more than one clinic; an API key reaches one and may leave it out.",
            "in": "header",
            "name": "Claro-Clinic",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Page size, 1 to 100. Default 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "`next_cursor` from the previous page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PractitionerList"
                }
              }
            },
            "description": "Practitioners"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A parameter or header is invalid"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No valid machine credential"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential may not do this"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such object, or not one this credential reaches"
          },
          "421": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API key belongs to the other region (wrong_region); param is the base URL to use"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited; see Retry-After"
          }
        },
        "summary": "List practitioners",
        "tags": [
          "Practitioners"
        ]
      }
    },
    "/api/public/v1/practitioners/{id}": {
      "get": {
        "callbacks": {},
        "operationId": "ClaroWeb.PublicApi.V1.PractitionerController.show",
        "parameters": [
          {
            "description": "The clinic to read (`clinic_…` from GET /clinics). Required when the credential reaches more than one clinic; an API key reaches one and may leave it out.",
            "in": "header",
            "name": "Claro-Clinic",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A practitioner id (`prac_…`).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Practitioner"
                }
              }
            },
            "description": "Practitioner"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A parameter or header is invalid"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No valid machine credential"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The credential may not do this"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such object, or not one this credential reaches"
          },
          "421": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API key belongs to the other region (wrong_region); param is the base URL to use"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited; see Retry-After"
          }
        },
        "summary": "Get a practitioner",
        "tags": [
          "Practitioners"
        ]
      }
    }
  },
  "security": [
    {
      "bearer": []
    }
  ],
  "servers": [
    {
      "description": "Australia",
      "url": "https://api-au.claro.clinic",
      "variables": {}
    },
    {
      "description": "United States",
      "url": "https://api-us.claro.clinic",
      "variables": {}
    }
  ],
  "tags": [
    {
      "description": "The clinics a credential reaches.",
      "name": "Clinics"
    },
    {
      "description": "Practitioners and prescribers at a clinic.",
      "name": "Practitioners"
    },
    {
      "description": "A clinic's patients. Clinical metadata: needs patients:read.",
      "name": "Patients"
    },
    {
      "description": "A clinic's bookings.",
      "name": "Appointments"
    },
    {
      "description": "What a webhook subscription is sent, to catch up on or replay missed deliveries.",
      "name": "Events"
    },
    {
      "description": "Documents about this API itself (the OpenAPI document and llms.txt). Not resources; no credential needed.",
      "name": "Meta"
    }
  ]
}
