openapi: 3.1.0 info: title: Professional Platform Healthcare API version: 0.2.0-openemr-informed summary: Clean-room healthcare identity and encounter API. description: | A proprietary healthcare API informed by established EHR workflows and public interoperability standards. This contract does not copy OpenEMR source code, database structures, or API routes. This foundation intentionally covers patients, practitioners, and encounters only. Clinical records, diagnoses, allergies, medications, prescriptions, appointments, insurance, claims, and billing require separate threat models and domain contracts. Every operation is tenant scoped. Cross-tenant identifiers return 404. Mutable resources use ETags and require If-Match. Creation and commands use Idempotency-Key. Responses containing patient data must not be cached. contact: name: Healthcare API Team servers: - url: https://api.example.com/api/v1 description: Production - url: https://sandbox-api.example.com/api/v1 description: Sandbox tags: - name: Healthcare Patients - name: Healthcare Practitioners - name: Healthcare Encounters - name: Healthcare Locations - name: Healthcare Appointments - name: Healthcare Allergies - name: Healthcare Conditions - name: Healthcare Medications - name: Healthcare Clinical Records security: - bearerAuth: [] paths: /healthcare/patients: get: tags: [Healthcare Patients] operationId: listHealthcarePatients summary: List patients using minimum-necessary projections description: | Search results are protected health information. By default, this operation returns only the summary projection. Access is audited. Free-text searching across clinical content is prohibited. x-permission: healthcare.patients.read x-audit-event: healthcare.patient.listed parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/Cursor' - $ref: '#/components/parameters/PageSize' - name: patientNumber in: query schema: {type: string, maxLength: 64} - name: familyName in: query schema: {type: string, maxLength: 120} - name: birthDate in: query schema: {type: string, format: date} - name: status in: query schema: {$ref: '#/components/schemas/PatientStatus'} responses: '200': description: Patient summaries. headers: Cache-Control: {$ref: '#/components/headers/NoStore'} X-Request-Id: {$ref: '#/components/headers/RequestId'} content: application/json: schema: {$ref: '#/components/schemas/PatientListResponse'} '401': {$ref: '#/components/responses/Unauthorized'} '403': {$ref: '#/components/responses/Forbidden'} '422': {$ref: '#/components/responses/ValidationError'} post: tags: [Healthcare Patients] operationId: createHealthcarePatient summary: Create a patient description: | The service performs deterministic duplicate screening within the tenant. A suspected match returns PATIENT_POSSIBLE_DUPLICATE and requires an authorized human to resolve it. Names alone never trigger automatic merging. x-permission: healthcare.patients.create x-audit-event: healthcare.patient.created parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/PatientCreate'} responses: '201': description: Patient created. headers: Location: {$ref: '#/components/headers/Location'} ETag: {$ref: '#/components/headers/ETag'} Cache-Control: {$ref: '#/components/headers/NoStore'} X-Request-Id: {$ref: '#/components/headers/RequestId'} content: application/json: schema: {$ref: '#/components/schemas/PatientResponse'} '401': {$ref: '#/components/responses/Unauthorized'} '403': {$ref: '#/components/responses/Forbidden'} '409': {$ref: '#/components/responses/Conflict'} '422': {$ref: '#/components/responses/ValidationError'} /healthcare/patients/{patientId}: parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/PatientId' get: tags: [Healthcare Patients] operationId: getHealthcarePatient summary: Retrieve a patient x-permission: healthcare.patients.read x-audit-event: healthcare.patient.read responses: '200': description: Patient record. headers: ETag: {$ref: '#/components/headers/ETag'} Cache-Control: {$ref: '#/components/headers/NoStore'} X-Request-Id: {$ref: '#/components/headers/RequestId'} content: application/json: schema: {$ref: '#/components/schemas/PatientResponse'} '401': {$ref: '#/components/responses/Unauthorized'} '403': {$ref: '#/components/responses/Forbidden'} '404': {$ref: '#/components/responses/NotFound'} patch: tags: [Healthcare Patients] operationId: updateHealthcarePatient summary: Update patient demographics description: Patient number, organization, status, and archival fields are not patchable. x-permission: healthcare.patients.update x-audit-event: healthcare.patient.updated parameters: - $ref: '#/components/parameters/IfMatch' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: application/merge-patch+json: schema: {$ref: '#/components/schemas/PatientPatch'} responses: '200': description: Patient updated. headers: ETag: {$ref: '#/components/headers/ETag'} Cache-Control: {$ref: '#/components/headers/NoStore'} X-Request-Id: {$ref: '#/components/headers/RequestId'} content: application/json: schema: {$ref: '#/components/schemas/PatientResponse'} '401': {$ref: '#/components/responses/Unauthorized'} '403': {$ref: '#/components/responses/Forbidden'} '404': {$ref: '#/components/responses/NotFound'} '409': {$ref: '#/components/responses/Conflict'} '412': {$ref: '#/components/responses/PreconditionFailed'} '422': {$ref: '#/components/responses/ValidationError'} /healthcare/patients/{patientId}/archive: post: tags: [Healthcare Patients] operationId: archiveHealthcarePatient summary: Archive a duplicate or erroneous patient shell description: | Archival never deletes clinical history. A patient with encounters may only be archived after an authorized reconciliation workflow confirms the target. x-permission: healthcare.patients.archive x-audit-event: healthcare.patient.archived parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/PatientId' - $ref: '#/components/parameters/IfMatch' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/ReasonCommand'} responses: '200': description: Patient archived. headers: ETag: {$ref: '#/components/headers/ETag'} Cache-Control: {$ref: '#/components/headers/NoStore'} content: application/json: schema: {$ref: '#/components/schemas/PatientResponse'} '409': {$ref: '#/components/responses/Conflict'} '412': {$ref: '#/components/responses/PreconditionFailed'} '422': {$ref: '#/components/responses/ValidationError'} /healthcare/patients/{patientId}/restore: post: tags: [Healthcare Patients] operationId: restoreHealthcarePatient summary: Restore an archived patient x-permission: healthcare.patients.archive x-audit-event: healthcare.patient.restored parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/PatientId' - $ref: '#/components/parameters/IfMatch' - $ref: '#/components/parameters/IdempotencyKey' responses: '200': description: Patient restored. headers: ETag: {$ref: '#/components/headers/ETag'} Cache-Control: {$ref: '#/components/headers/NoStore'} content: application/json: schema: {$ref: '#/components/schemas/PatientResponse'} '409': {$ref: '#/components/responses/Conflict'} '412': {$ref: '#/components/responses/PreconditionFailed'} /healthcare/practitioners: get: tags: [Healthcare Practitioners] operationId: listHealthcarePractitioners summary: List practitioners x-permission: healthcare.practitioners.read parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/Cursor' - $ref: '#/components/parameters/PageSize' - name: status in: query schema: {$ref: '#/components/schemas/PractitionerStatus'} responses: '200': description: Practitioners. content: application/json: schema: {$ref: '#/components/schemas/PractitionerListResponse'} '401': {$ref: '#/components/responses/Unauthorized'} '403': {$ref: '#/components/responses/Forbidden'} post: tags: [Healthcare Practitioners] operationId: createHealthcarePractitioner summary: Create a practitioner assignment description: | The referenced user must have an active organization membership. Credential records remain authoritative in the shared professional credential registry. x-permission: healthcare.practitioners.manage x-audit-event: healthcare.practitioner.created parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/PractitionerCreate'} responses: '201': description: Practitioner assignment created. headers: Location: {$ref: '#/components/headers/Location'} ETag: {$ref: '#/components/headers/ETag'} content: application/json: schema: {$ref: '#/components/schemas/PractitionerResponse'} '409': {$ref: '#/components/responses/Conflict'} '422': {$ref: '#/components/responses/ValidationError'} /healthcare/practitioners/{practitionerId}: parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/PractitionerId' get: tags: [Healthcare Practitioners] operationId: getHealthcarePractitioner summary: Retrieve a practitioner x-permission: healthcare.practitioners.read responses: '200': description: Practitioner. headers: {ETag: {$ref: '#/components/headers/ETag'}} content: application/json: schema: {$ref: '#/components/schemas/PractitionerResponse'} '404': {$ref: '#/components/responses/NotFound'} patch: tags: [Healthcare Practitioners] operationId: updateHealthcarePractitioner summary: Update practitioner specialty or status description: userId and professionalProfileId are immutable after creation. x-permission: healthcare.practitioners.manage x-audit-event: healthcare.practitioner.updated parameters: - $ref: '#/components/parameters/IfMatch' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: application/merge-patch+json: schema: {$ref: '#/components/schemas/PractitionerPatch'} responses: '200': description: Practitioner updated. headers: {ETag: {$ref: '#/components/headers/ETag'}} content: application/json: schema: {$ref: '#/components/schemas/PractitionerResponse'} '409': {$ref: '#/components/responses/Conflict'} '412': {$ref: '#/components/responses/PreconditionFailed'} '422': {$ref: '#/components/responses/ValidationError'} /healthcare/encounters: get: tags: [Healthcare Encounters] operationId: listHealthcareEncounters summary: List encounters x-permission: healthcare.encounters.read x-audit-event: healthcare.encounter.listed parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/Cursor' - $ref: '#/components/parameters/PageSize' - name: patientId in: query schema: {$ref: '#/components/schemas/Uuid'} - name: practitionerId in: query schema: {$ref: '#/components/schemas/Uuid'} - name: status in: query schema: {$ref: '#/components/schemas/EncounterStatus'} - name: from in: query schema: {type: string, format: date-time} - name: to in: query schema: {type: string, format: date-time} responses: '200': description: Encounter summaries. headers: {Cache-Control: {$ref: '#/components/headers/NoStore'}} content: application/json: schema: {$ref: '#/components/schemas/EncounterListResponse'} '422': {$ref: '#/components/responses/ValidationError'} post: tags: [Healthcare Encounters] operationId: createHealthcareEncounter summary: Create a planned encounter description: | Patient and practitioner must be active in the same tenant. Clinical narrative is not accepted by this endpoint. x-permission: healthcare.encounters.create x-audit-event: healthcare.encounter.created parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/EncounterCreate'} responses: '201': description: Encounter created. headers: Location: {$ref: '#/components/headers/Location'} ETag: {$ref: '#/components/headers/ETag'} Cache-Control: {$ref: '#/components/headers/NoStore'} content: application/json: schema: {$ref: '#/components/schemas/EncounterResponse'} '409': {$ref: '#/components/responses/Conflict'} '422': {$ref: '#/components/responses/ValidationError'} /healthcare/encounters/{encounterId}: parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/EncounterId' get: tags: [Healthcare Encounters] operationId: getHealthcareEncounter summary: Retrieve an encounter x-permission: healthcare.encounters.read x-audit-event: healthcare.encounter.read responses: '200': description: Encounter. headers: ETag: {$ref: '#/components/headers/ETag'} Cache-Control: {$ref: '#/components/headers/NoStore'} content: application/json: schema: {$ref: '#/components/schemas/EncounterResponse'} '404': {$ref: '#/components/responses/NotFound'} patch: tags: [Healthcare Encounters] operationId: updateHealthcareEncounter summary: Update a planned encounter description: Only planned encounters are patchable; status changes use commands. x-permission: healthcare.encounters.update x-audit-event: healthcare.encounter.updated parameters: - $ref: '#/components/parameters/IfMatch' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: application/merge-patch+json: schema: {$ref: '#/components/schemas/EncounterPatch'} responses: '200': description: Encounter updated. headers: ETag: {$ref: '#/components/headers/ETag'} Cache-Control: {$ref: '#/components/headers/NoStore'} content: application/json: schema: {$ref: '#/components/schemas/EncounterResponse'} '409': {$ref: '#/components/responses/Conflict'} '412': {$ref: '#/components/responses/PreconditionFailed'} '422': {$ref: '#/components/responses/ValidationError'} /healthcare/encounters/{encounterId}/start: post: tags: [Healthcare Encounters] operationId: startHealthcareEncounter summary: Start a planned encounter x-permission: healthcare.encounters.conduct x-audit-event: healthcare.encounter.started parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/EncounterId' - $ref: '#/components/parameters/IfMatch' - $ref: '#/components/parameters/IdempotencyKey' requestBody: content: application/json: schema: {$ref: '#/components/schemas/StartEncounterCommand'} responses: '200': description: Encounter started. headers: {ETag: {$ref: '#/components/headers/ETag'}, Cache-Control: {$ref: '#/components/headers/NoStore'}} content: application/json: schema: {$ref: '#/components/schemas/EncounterResponse'} '409': {$ref: '#/components/responses/Conflict'} '412': {$ref: '#/components/responses/PreconditionFailed'} /healthcare/encounters/{encounterId}/finish: post: tags: [Healthcare Encounters] operationId: finishHealthcareEncounter summary: Finish an in-progress encounter description: Finishing an encounter does not sign associated clinical records. x-permission: healthcare.encounters.conduct x-audit-event: healthcare.encounter.finished parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/EncounterId' - $ref: '#/components/parameters/IfMatch' - $ref: '#/components/parameters/IdempotencyKey' requestBody: content: application/json: schema: {$ref: '#/components/schemas/FinishEncounterCommand'} responses: '200': description: Encounter finished. headers: {ETag: {$ref: '#/components/headers/ETag'}, Cache-Control: {$ref: '#/components/headers/NoStore'}} content: application/json: schema: {$ref: '#/components/schemas/EncounterResponse'} '409': {$ref: '#/components/responses/Conflict'} '412': {$ref: '#/components/responses/PreconditionFailed'} '422': {$ref: '#/components/responses/ValidationError'} /healthcare/encounters/{encounterId}/cancel: post: tags: [Healthcare Encounters] operationId: cancelHealthcareEncounter summary: Cancel a planned encounter x-permission: healthcare.encounters.update x-audit-event: healthcare.encounter.cancelled parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/EncounterId' - $ref: '#/components/parameters/IfMatch' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/ReasonCommand'} responses: '200': description: Encounter cancelled. headers: {ETag: {$ref: '#/components/headers/ETag'}, Cache-Control: {$ref: '#/components/headers/NoStore'}} content: application/json: schema: {$ref: '#/components/schemas/EncounterResponse'} '409': {$ref: '#/components/responses/Conflict'} '412': {$ref: '#/components/responses/PreconditionFailed'} /healthcare/locations: get: tags: [Healthcare Locations] operationId: listHealthcareLocations summary: List care locations x-permission: healthcare.locations.read parameters: &tenantListParameters - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/Cursor' - $ref: '#/components/parameters/PageSize' responses: '200': description: Care locations. content: {application/json: {schema: {$ref: '#/components/schemas/LocationListResponse'}}} post: tags: [Healthcare Locations] operationId: createHealthcareLocation summary: Create a care location x-permission: healthcare.locations.manage x-audit-event: healthcare.location.created parameters: &tenantCreateParameters - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: {application/json: {schema: {$ref: '#/components/schemas/LocationCreate'}}} responses: '201': description: Location created. headers: {Location: {$ref: '#/components/headers/Location'}, ETag: {$ref: '#/components/headers/ETag'}} content: {application/json: {schema: {$ref: '#/components/schemas/LocationResponse'}}} '409': {$ref: '#/components/responses/Conflict'} '422': {$ref: '#/components/responses/ValidationError'} /healthcare/locations/{locationId}: parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/LocationId' get: tags: [Healthcare Locations] operationId: getHealthcareLocation summary: Retrieve a care location x-permission: healthcare.locations.read responses: '200': description: Location. headers: {ETag: {$ref: '#/components/headers/ETag'}} content: {application/json: {schema: {$ref: '#/components/schemas/LocationResponse'}}} '404': {$ref: '#/components/responses/NotFound'} patch: tags: [Healthcare Locations] operationId: updateHealthcareLocation summary: Update a care location x-permission: healthcare.locations.manage x-audit-event: healthcare.location.updated parameters: - $ref: '#/components/parameters/IfMatch' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: {application/merge-patch+json: {schema: {$ref: '#/components/schemas/LocationPatch'}}} responses: '200': description: Location updated. headers: {ETag: {$ref: '#/components/headers/ETag'}} content: {application/json: {schema: {$ref: '#/components/schemas/LocationResponse'}}} '412': {$ref: '#/components/responses/PreconditionFailed'} '422': {$ref: '#/components/responses/ValidationError'} /healthcare/appointments: get: tags: [Healthcare Appointments] operationId: listHealthcareAppointments summary: List appointments x-permission: healthcare.appointments.read x-audit-event: healthcare.appointment.listed parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/Cursor' - $ref: '#/components/parameters/PageSize' - name: patientId in: query schema: {$ref: '#/components/schemas/Uuid'} - name: practitionerId in: query schema: {$ref: '#/components/schemas/Uuid'} - name: from in: query schema: {type: string, format: date-time} - name: to in: query schema: {type: string, format: date-time} - name: status in: query schema: {$ref: '#/components/schemas/AppointmentStatus'} responses: '200': description: Appointments. headers: {Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/AppointmentListResponse'}}} post: tags: [Healthcare Appointments] operationId: createHealthcareAppointment summary: Book an appointment description: Scheduling conflicts return APPOINTMENT_CONFLICT; the server never silently double-books. x-permission: healthcare.appointments.create x-audit-event: healthcare.appointment.created parameters: *tenantCreateParameters requestBody: required: true content: {application/json: {schema: {$ref: '#/components/schemas/AppointmentCreate'}}} responses: '201': description: Appointment booked. headers: {Location: {$ref: '#/components/headers/Location'}, ETag: {$ref: '#/components/headers/ETag'}, Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/AppointmentResponse'}}} '409': {$ref: '#/components/responses/Conflict'} '422': {$ref: '#/components/responses/ValidationError'} /healthcare/appointments/{appointmentId}: parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/AppointmentId' get: tags: [Healthcare Appointments] operationId: getHealthcareAppointment summary: Retrieve an appointment x-permission: healthcare.appointments.read x-audit-event: healthcare.appointment.read responses: '200': description: Appointment. headers: {ETag: {$ref: '#/components/headers/ETag'}, Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/AppointmentResponse'}}} '404': {$ref: '#/components/responses/NotFound'} patch: tags: [Healthcare Appointments] operationId: updateHealthcareAppointment summary: Reschedule or update a booked appointment description: Status changes use commands; fulfilled appointments are immutable. x-permission: healthcare.appointments.update x-audit-event: healthcare.appointment.updated parameters: - $ref: '#/components/parameters/IfMatch' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: {application/merge-patch+json: {schema: {$ref: '#/components/schemas/AppointmentPatch'}}} responses: '200': description: Appointment updated. headers: {ETag: {$ref: '#/components/headers/ETag'}, Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/AppointmentResponse'}}} '409': {$ref: '#/components/responses/Conflict'} '412': {$ref: '#/components/responses/PreconditionFailed'} '422': {$ref: '#/components/responses/ValidationError'} /healthcare/appointments/{appointmentId}/{command}: post: tags: [Healthcare Appointments] operationId: commandHealthcareAppointment summary: Confirm, check in, fulfil, cancel, or mark an appointment as no-show description: | Allowed transitions: booked to confirmed/cancelled; confirmed to checked_in/cancelled/no_show; checked_in to fulfilled. Fulfilment requires a linked encounter. x-permission: healthcare.appointments.update x-audit-event: healthcare.appointment.commanded parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/AppointmentId' - name: command in: path required: true schema: {type: string, enum: [confirm, check-in, fulfil, cancel, no-show]} - $ref: '#/components/parameters/IfMatch' - $ref: '#/components/parameters/IdempotencyKey' requestBody: content: {application/json: {schema: {$ref: '#/components/schemas/OptionalReasonCommand'}}} responses: '200': description: Appointment transitioned. headers: {ETag: {$ref: '#/components/headers/ETag'}, Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/AppointmentResponse'}}} '409': {$ref: '#/components/responses/Conflict'} '412': {$ref: '#/components/responses/PreconditionFailed'} /healthcare/patients/{patientId}/allergies: get: tags: [Healthcare Allergies] operationId: listPatientAllergies summary: List recorded allergies and intolerances x-permission: healthcare.allergies.read x-audit-event: healthcare.allergy.listed parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/PatientId' responses: '200': description: Allergy records. headers: {Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/AllergyListResponse'}}} post: tags: [Healthcare Allergies] operationId: createPatientAllergy summary: Record an allergy or intolerance x-permission: healthcare.allergies.create x-audit-event: healthcare.allergy.created parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/PatientId' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: {application/json: {schema: {$ref: '#/components/schemas/AllergyCreate'}}} responses: '201': description: Allergy recorded. headers: {Location: {$ref: '#/components/headers/Location'}, ETag: {$ref: '#/components/headers/ETag'}, Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/AllergyResponse'}}} '422': {$ref: '#/components/responses/ValidationError'} /healthcare/allergies/{allergyId}: parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/AllergyId' get: tags: [Healthcare Allergies] operationId: getPatientAllergy summary: Retrieve an allergy x-permission: healthcare.allergies.read x-audit-event: healthcare.allergy.read responses: '200': description: Allergy. headers: {ETag: {$ref: '#/components/headers/ETag'}, Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/AllergyResponse'}}} '404': {$ref: '#/components/responses/NotFound'} patch: tags: [Healthcare Allergies] operationId: updatePatientAllergy summary: Update verification or clinical status description: Substance identity is immutable; incorrect entries become entered_in_error. x-permission: healthcare.allergies.update x-audit-event: healthcare.allergy.updated parameters: - $ref: '#/components/parameters/IfMatch' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: {application/merge-patch+json: {schema: {$ref: '#/components/schemas/AllergyPatch'}}} responses: '200': description: Allergy updated. headers: {ETag: {$ref: '#/components/headers/ETag'}, Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/AllergyResponse'}}} '412': {$ref: '#/components/responses/PreconditionFailed'} /healthcare/patients/{patientId}/conditions: get: tags: [Healthcare Conditions] operationId: listPatientConditions summary: List problems, diagnoses, and health concerns x-permission: healthcare.conditions.read x-audit-event: healthcare.condition.listed parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/PatientId' - name: category in: query schema: {$ref: '#/components/schemas/ConditionCategory'} responses: '200': description: Conditions. headers: {Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/ConditionListResponse'}}} post: tags: [Healthcare Conditions] operationId: createPatientCondition summary: Record a problem, diagnosis, or health concern x-permission: healthcare.conditions.create x-audit-event: healthcare.condition.created parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/PatientId' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: {application/json: {schema: {$ref: '#/components/schemas/ConditionCreate'}}} responses: '201': description: Condition recorded. headers: {Location: {$ref: '#/components/headers/Location'}, ETag: {$ref: '#/components/headers/ETag'}, Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/ConditionResponse'}}} '422': {$ref: '#/components/responses/ValidationError'} /healthcare/conditions/{conditionId}: parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/ConditionId' get: tags: [Healthcare Conditions] operationId: getPatientCondition summary: Retrieve a condition x-permission: healthcare.conditions.read x-audit-event: healthcare.condition.read responses: '200': description: Condition. headers: {ETag: {$ref: '#/components/headers/ETag'}, Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/ConditionResponse'}}} '404': {$ref: '#/components/responses/NotFound'} patch: tags: [Healthcare Conditions] operationId: updatePatientCondition summary: Update condition lifecycle or verification x-permission: healthcare.conditions.update x-audit-event: healthcare.condition.updated parameters: - $ref: '#/components/parameters/IfMatch' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: {application/merge-patch+json: {schema: {$ref: '#/components/schemas/ConditionPatch'}}} responses: '200': description: Condition updated. headers: {ETag: {$ref: '#/components/headers/ETag'}, Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/ConditionResponse'}}} '412': {$ref: '#/components/responses/PreconditionFailed'} /healthcare/patients/{patientId}/medications: get: tags: [Healthcare Medications] operationId: listPatientMedications summary: List medication statements and orders x-permission: healthcare.medications.read x-audit-event: healthcare.medication.listed parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/PatientId' responses: '200': description: Medications. headers: {Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/MedicationListResponse'}}} post: tags: [Healthcare Medications] operationId: createPatientMedication summary: Record a medication statement description: This operation records medication history; it does not prescribe or dispense. x-permission: healthcare.medications.create x-audit-event: healthcare.medication.created parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/PatientId' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: {application/json: {schema: {$ref: '#/components/schemas/MedicationCreate'}}} responses: '201': description: Medication statement recorded. headers: {Location: {$ref: '#/components/headers/Location'}, ETag: {$ref: '#/components/headers/ETag'}, Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/MedicationResponse'}}} '422': {$ref: '#/components/responses/ValidationError'} /healthcare/medications/{medicationId}: patch: tags: [Healthcare Medications] operationId: updatePatientMedication summary: Update a medication statement lifecycle x-permission: healthcare.medications.update x-audit-event: healthcare.medication.updated parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/MedicationId' - $ref: '#/components/parameters/IfMatch' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: {application/merge-patch+json: {schema: {$ref: '#/components/schemas/MedicationPatch'}}} responses: '200': description: Medication updated. headers: {ETag: {$ref: '#/components/headers/ETag'}, Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/MedicationResponse'}}} '412': {$ref: '#/components/responses/PreconditionFailed'} /healthcare/encounters/{encounterId}/clinical-records: get: tags: [Healthcare Clinical Records] operationId: listEncounterClinicalRecords summary: List clinical records for an encounter x-permission: healthcare.clinical_records.read x-audit-event: healthcare.clinical_record.listed parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/EncounterId' responses: '200': description: Clinical record summaries; narrative content is excluded. headers: {Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/ClinicalRecordListResponse'}}} post: tags: [Healthcare Clinical Records] operationId: createEncounterClinicalRecord summary: Create a draft clinical record x-permission: healthcare.clinical_records.create x-audit-event: healthcare.clinical_record.created parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/EncounterId' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: {application/json: {schema: {$ref: '#/components/schemas/ClinicalRecordCreate'}}} responses: '201': description: Draft record created with version 1. headers: {Location: {$ref: '#/components/headers/Location'}, ETag: {$ref: '#/components/headers/ETag'}, Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/ClinicalRecordResponse'}}} '422': {$ref: '#/components/responses/ValidationError'} /healthcare/clinical-records/{recordId}: parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/ClinicalRecordId' get: tags: [Healthcare Clinical Records] operationId: getClinicalRecord summary: Retrieve a clinical record and current content version x-permission: healthcare.clinical_records.read x-audit-event: healthcare.clinical_record.read responses: '200': description: Clinical record. headers: {ETag: {$ref: '#/components/headers/ETag'}, Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/ClinicalRecordResponse'}}} '404': {$ref: '#/components/responses/NotFound'} patch: tags: [Healthcare Clinical Records] operationId: updateDraftClinicalRecord summary: Create a new version of a draft clinical record description: Signed records reject PATCH; use the amendment command. x-permission: healthcare.clinical_records.update x-audit-event: healthcare.clinical_record.version_created parameters: - $ref: '#/components/parameters/IfMatch' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: {application/merge-patch+json: {schema: {$ref: '#/components/schemas/ClinicalRecordPatch'}}} responses: '200': description: New draft version created. headers: {ETag: {$ref: '#/components/headers/ETag'}, Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/ClinicalRecordResponse'}}} '409': {$ref: '#/components/responses/Conflict'} '412': {$ref: '#/components/responses/PreconditionFailed'} /healthcare/clinical-records/{recordId}/sign: post: tags: [Healthcare Clinical Records] operationId: signClinicalRecord summary: Sign and freeze the current clinical record version description: Revalidates active practitioner status and credential authority at execution time. x-permission: healthcare.clinical_records.sign x-audit-event: healthcare.clinical_record.signed parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/ClinicalRecordId' - $ref: '#/components/parameters/IfMatch' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: {application/json: {schema: {$ref: '#/components/schemas/SignClinicalRecordCommand'}}} responses: '200': description: Record signed and immutable. headers: {ETag: {$ref: '#/components/headers/ETag'}, Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/ClinicalRecordResponse'}}} '409': {$ref: '#/components/responses/Conflict'} '412': {$ref: '#/components/responses/PreconditionFailed'} '422': {$ref: '#/components/responses/ValidationError'} /healthcare/clinical-records/{recordId}/amend: post: tags: [Healthcare Clinical Records] operationId: amendClinicalRecord summary: Amend a signed clinical record without overwriting history x-permission: healthcare.clinical_records.amend x-audit-event: healthcare.clinical_record.amended parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/ClinicalRecordId' - $ref: '#/components/parameters/IfMatch' - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: {application/json: {schema: {$ref: '#/components/schemas/AmendClinicalRecordCommand'}}} responses: '201': description: Signed amendment version created with provenance links. headers: {Location: {$ref: '#/components/headers/Location'}, ETag: {$ref: '#/components/headers/ETag'}, Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/ClinicalRecordResponse'}}} '409': {$ref: '#/components/responses/Conflict'} '412': {$ref: '#/components/responses/PreconditionFailed'} '422': {$ref: '#/components/responses/ValidationError'} /healthcare/clinical-records/{recordId}/history: get: tags: [Healthcare Clinical Records] operationId: getClinicalRecordHistory summary: Retrieve immutable version and amendment history x-permission: healthcare.clinical_records.history x-audit-event: healthcare.clinical_record.history_read parameters: - $ref: '#/components/parameters/OrganizationId' - $ref: '#/components/parameters/RequestId' - $ref: '#/components/parameters/ClinicalRecordId' responses: '200': description: Version history. headers: {Cache-Control: {$ref: '#/components/headers/NoStore'}} content: {application/json: {schema: {$ref: '#/components/schemas/ClinicalRecordHistoryResponse'}}} '404': {$ref: '#/components/responses/NotFound'} components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT parameters: OrganizationId: name: X-Organization-Id in: header required: true schema: {$ref: '#/components/schemas/Uuid'} RequestId: name: X-Request-Id in: header required: false schema: {type: string, maxLength: 128} IdempotencyKey: name: Idempotency-Key in: header required: true schema: {type: string, minLength: 16, maxLength: 128} IfMatch: name: If-Match in: header required: true schema: {type: string, pattern: '^"[1-9][0-9]*"$'} Cursor: name: cursor in: query schema: {type: string, maxLength: 512} PageSize: name: pageSize in: query schema: {type: integer, minimum: 1, maximum: 100, default: 25} PatientId: name: patientId in: path required: true schema: {$ref: '#/components/schemas/Uuid'} PractitionerId: name: practitionerId in: path required: true schema: {$ref: '#/components/schemas/Uuid'} EncounterId: name: encounterId in: path required: true schema: {$ref: '#/components/schemas/Uuid'} LocationId: name: locationId in: path required: true schema: {$ref: '#/components/schemas/Uuid'} AppointmentId: name: appointmentId in: path required: true schema: {$ref: '#/components/schemas/Uuid'} AllergyId: name: allergyId in: path required: true schema: {$ref: '#/components/schemas/Uuid'} ConditionId: name: conditionId in: path required: true schema: {$ref: '#/components/schemas/Uuid'} MedicationId: name: medicationId in: path required: true schema: {$ref: '#/components/schemas/Uuid'} ClinicalRecordId: name: recordId in: path required: true schema: {$ref: '#/components/schemas/Uuid'} headers: ETag: schema: {type: string, pattern: '^"[1-9][0-9]*"$'} Location: schema: {type: string, format: uri-reference} RequestId: schema: {type: string} NoStore: schema: {type: string, const: 'private, no-store'} responses: Unauthorized: description: Authentication is missing or invalid. content: {application/problem+json: {schema: {$ref: '#/components/schemas/Problem'}}} Forbidden: description: The caller lacks permission or professional authority. content: {application/problem+json: {schema: {$ref: '#/components/schemas/Problem'}}} NotFound: description: Resource not found in the active tenant. content: {application/problem+json: {schema: {$ref: '#/components/schemas/Problem'}}} Conflict: description: State conflict, uniqueness conflict, or possible duplicate. content: {application/problem+json: {schema: {$ref: '#/components/schemas/Problem'}}} PreconditionFailed: description: If-Match does not match the current version. content: {application/problem+json: {schema: {$ref: '#/components/schemas/Problem'}}} ValidationError: description: Request validation failed. content: {application/problem+json: {schema: {$ref: '#/components/schemas/Problem'}}} schemas: Uuid: type: string format: uuid PatientStatus: type: string enum: [active, inactive, deceased, archived] PractitionerStatus: type: string enum: [active, suspended, inactive] EncounterStatus: type: string enum: [planned, in_progress, finished, cancelled, entered_in_error] AppointmentStatus: type: string enum: [booked, confirmed, checked_in, fulfilled, cancelled, no_show, entered_in_error] ClinicalStatus: type: string enum: [active, inactive, resolved, entered_in_error] VerificationStatus: type: string enum: [unconfirmed, provisional, differential, confirmed, refuted, entered_in_error] ConditionCategory: type: string enum: [problem_list, encounter_diagnosis, health_concern] CodeableConcept: type: object additionalProperties: false required: [system, code, display] properties: system: {type: string, format: uri, maxLength: 500} code: {type: string, minLength: 1, maxLength: 100} display: {type: string, minLength: 1, maxLength: 300} text: {type: [string, 'null'], maxLength: 300} AdministrativeGender: type: string enum: [female, male, other, unknown] description: Administrative classification only; not a clinical assertion. HumanName: type: object additionalProperties: false required: [given, family] properties: prefix: {type: [string, 'null'], maxLength: 40} given: type: array minItems: 1 maxItems: 5 items: {type: string, minLength: 1, maxLength: 120} family: {type: string, minLength: 1, maxLength: 120} suffix: {type: [string, 'null'], maxLength: 40} ContactPoint: type: object additionalProperties: false required: [system, value, use] properties: system: {type: string, enum: [phone, email]} value: {type: string, minLength: 3, maxLength: 254} use: {type: string, enum: [home, work, mobile, temporary]} isPrimary: {type: boolean, default: false} Address: type: object additionalProperties: false required: [use, line1, city, countryCode] properties: use: {type: string, enum: [home, work, temporary]} line1: {type: string, minLength: 1, maxLength: 200} line2: {type: [string, 'null'], maxLength: 200} city: {type: string, minLength: 1, maxLength: 120} region: {type: [string, 'null'], maxLength: 120} postalCode: {type: [string, 'null'], maxLength: 32} countryCode: {type: string, pattern: '^[A-Z]{2}$'} isPrimary: {type: boolean, default: false} PatientCreate: type: object additionalProperties: false required: [name, birthDate] properties: patientNumber: type: string maxLength: 64 description: Optional client-supplied number; generated when omitted. name: {$ref: '#/components/schemas/HumanName'} birthDate: {type: string, format: date} administrativeGender: {$ref: '#/components/schemas/AdministrativeGender'} sexAtBirth: {type: [string, 'null'], maxLength: 80} genderIdentity: {type: [string, 'null'], maxLength: 120} contacts: type: array maxItems: 10 items: {$ref: '#/components/schemas/ContactPoint'} addresses: type: array maxItems: 10 items: {$ref: '#/components/schemas/Address'} PatientPatch: type: object additionalProperties: false minProperties: 1 properties: name: {$ref: '#/components/schemas/HumanName'} birthDate: {type: string, format: date} administrativeGender: {$ref: '#/components/schemas/AdministrativeGender'} sexAtBirth: {type: [string, 'null'], maxLength: 80} genderIdentity: {type: [string, 'null'], maxLength: 120} contacts: type: array maxItems: 10 items: {$ref: '#/components/schemas/ContactPoint'} addresses: type: array maxItems: 10 items: {$ref: '#/components/schemas/Address'} Patient: allOf: - $ref: '#/components/schemas/PatientCreate' - type: object required: [id, organizationId, patientNumber, status, version, createdAt, updatedAt] properties: id: {$ref: '#/components/schemas/Uuid'} organizationId: {$ref: '#/components/schemas/Uuid'} patientNumber: {type: string} status: {$ref: '#/components/schemas/PatientStatus'} archivedAt: {type: [string, 'null'], format: date-time} version: {type: integer, minimum: 1} createdAt: {type: string, format: date-time} updatedAt: {type: string, format: date-time} PatientSummary: type: object additionalProperties: false required: [id, patientNumber, name, birthDate, status] properties: id: {$ref: '#/components/schemas/Uuid'} patientNumber: {type: string} name: {$ref: '#/components/schemas/HumanName'} birthDate: {type: string, format: date} status: {$ref: '#/components/schemas/PatientStatus'} PatientResponse: type: object additionalProperties: false required: [data] properties: {data: {$ref: '#/components/schemas/Patient'}} PatientListResponse: type: object additionalProperties: false required: [data, page] properties: data: {type: array, items: {$ref: '#/components/schemas/PatientSummary'}} page: {$ref: '#/components/schemas/CursorPage'} PractitionerCreate: type: object additionalProperties: false required: [userId, professionalProfileId, specialtyCode] properties: userId: {$ref: '#/components/schemas/Uuid'} professionalProfileId: {$ref: '#/components/schemas/Uuid'} specialtyCode: {type: string, minLength: 1, maxLength: 64} PractitionerPatch: type: object additionalProperties: false minProperties: 1 properties: specialtyCode: {type: string, minLength: 1, maxLength: 64} status: {$ref: '#/components/schemas/PractitionerStatus'} Practitioner: allOf: - $ref: '#/components/schemas/PractitionerCreate' - type: object required: [id, organizationId, status, credentialState, version, createdAt, updatedAt] properties: id: {$ref: '#/components/schemas/Uuid'} organizationId: {$ref: '#/components/schemas/Uuid'} status: {$ref: '#/components/schemas/PractitionerStatus'} credentialState: type: string enum: [verified, expiring, expired, incomplete, suspended] readOnly: true version: {type: integer, minimum: 1} createdAt: {type: string, format: date-time} updatedAt: {type: string, format: date-time} PractitionerResponse: type: object required: [data] properties: {data: {$ref: '#/components/schemas/Practitioner'}} PractitionerListResponse: type: object required: [data, page] properties: data: {type: array, items: {$ref: '#/components/schemas/Practitioner'}} page: {$ref: '#/components/schemas/CursorPage'} EncounterCreate: type: object additionalProperties: false required: [patientId, practitionerId, encounterType] properties: patientId: {$ref: '#/components/schemas/Uuid'} practitionerId: {$ref: '#/components/schemas/Uuid'} appointmentId: {oneOf: [{$ref: '#/components/schemas/Uuid'}, {type: 'null'}]} encounterType: {type: string, enum: [ambulatory, emergency, inpatient, virtual, home]} scheduledStart: {type: [string, 'null'], format: date-time} reasonForVisit: {type: [string, 'null'], maxLength: 500} EncounterPatch: type: object additionalProperties: false minProperties: 1 properties: practitionerId: {$ref: '#/components/schemas/Uuid'} appointmentId: {oneOf: [{$ref: '#/components/schemas/Uuid'}, {type: 'null'}]} encounterType: {type: string, enum: [ambulatory, emergency, inpatient, virtual, home]} scheduledStart: {type: [string, 'null'], format: date-time} reasonForVisit: {type: [string, 'null'], maxLength: 500} Encounter: allOf: - $ref: '#/components/schemas/EncounterCreate' - type: object required: [id, organizationId, status, version, createdAt, updatedAt] properties: id: {$ref: '#/components/schemas/Uuid'} organizationId: {$ref: '#/components/schemas/Uuid'} status: {$ref: '#/components/schemas/EncounterStatus'} startedAt: {type: [string, 'null'], format: date-time} endedAt: {type: [string, 'null'], format: date-time} cancellationReason: {type: [string, 'null'], maxLength: 500} version: {type: integer, minimum: 1} createdAt: {type: string, format: date-time} updatedAt: {type: string, format: date-time} EncounterResponse: type: object required: [data] properties: {data: {$ref: '#/components/schemas/Encounter'}} EncounterListResponse: type: object required: [data, page] properties: data: {type: array, items: {$ref: '#/components/schemas/Encounter'}} page: {$ref: '#/components/schemas/CursorPage'} LocationCreate: type: object additionalProperties: false required: [name, type, timezone, status] properties: name: {type: string, minLength: 1, maxLength: 160} type: {type: string, enum: [clinic, hospital, office, virtual]} timezone: {type: string, minLength: 1, maxLength: 64} status: {type: string, enum: [active, suspended, inactive]} address: {oneOf: [{$ref: '#/components/schemas/Address'}, {type: 'null'}]} LocationPatch: type: object additionalProperties: false minProperties: 1 properties: name: {type: string, minLength: 1, maxLength: 160} timezone: {type: string, minLength: 1, maxLength: 64} status: {type: string, enum: [active, suspended, inactive]} address: {oneOf: [{$ref: '#/components/schemas/Address'}, {type: 'null'}]} HealthcareLocation: allOf: - $ref: '#/components/schemas/LocationCreate' - type: object required: [id, organizationId, version, createdAt, updatedAt] properties: id: {$ref: '#/components/schemas/Uuid'} organizationId: {$ref: '#/components/schemas/Uuid'} version: {type: integer, minimum: 1} createdAt: {type: string, format: date-time} updatedAt: {type: string, format: date-time} LocationResponse: type: object required: [data] properties: {data: {$ref: '#/components/schemas/HealthcareLocation'}} LocationListResponse: type: object required: [data, page] properties: data: {type: array, items: {$ref: '#/components/schemas/HealthcareLocation'}} page: {$ref: '#/components/schemas/CursorPage'} AppointmentCreate: type: object additionalProperties: false required: [patientId, practitionerId, locationId, appointmentType, startsAt, endsAt] properties: patientId: {$ref: '#/components/schemas/Uuid'} practitionerId: {$ref: '#/components/schemas/Uuid'} locationId: {$ref: '#/components/schemas/Uuid'} appointmentType: {type: string, minLength: 1, maxLength: 64} startsAt: {type: string, format: date-time} endsAt: {type: string, format: date-time} reason: {type: [string, 'null'], maxLength: 500} AppointmentPatch: type: object additionalProperties: false minProperties: 1 properties: practitionerId: {$ref: '#/components/schemas/Uuid'} locationId: {$ref: '#/components/schemas/Uuid'} appointmentType: {type: string, minLength: 1, maxLength: 64} startsAt: {type: string, format: date-time} endsAt: {type: string, format: date-time} reason: {type: [string, 'null'], maxLength: 500} Appointment: allOf: - $ref: '#/components/schemas/AppointmentCreate' - type: object required: [id, organizationId, status, version, createdAt, updatedAt] properties: id: {$ref: '#/components/schemas/Uuid'} organizationId: {$ref: '#/components/schemas/Uuid'} status: {$ref: '#/components/schemas/AppointmentStatus'} encounterId: {oneOf: [{$ref: '#/components/schemas/Uuid'}, {type: 'null'}]} cancellationReason: {type: [string, 'null'], maxLength: 500} version: {type: integer, minimum: 1} createdAt: {type: string, format: date-time} updatedAt: {type: string, format: date-time} AppointmentResponse: type: object required: [data] properties: {data: {$ref: '#/components/schemas/Appointment'}} AppointmentListResponse: type: object required: [data, page] properties: data: {type: array, items: {$ref: '#/components/schemas/Appointment'}} page: {$ref: '#/components/schemas/CursorPage'} AllergyCreate: type: object additionalProperties: false required: [substance, category, criticality, recordedByPractitionerId] properties: substance: {$ref: '#/components/schemas/CodeableConcept'} category: {type: string, enum: [food, medication, environment, biologic]} criticality: {type: string, enum: [low, high, unable_to_assess]} verificationStatus: {$ref: '#/components/schemas/VerificationStatus'} reaction: {type: [string, 'null'], maxLength: 500} recordedByPractitionerId: {$ref: '#/components/schemas/Uuid'} AllergyPatch: type: object additionalProperties: false minProperties: 1 properties: clinicalStatus: {$ref: '#/components/schemas/ClinicalStatus'} verificationStatus: {$ref: '#/components/schemas/VerificationStatus'} criticality: {type: string, enum: [low, high, unable_to_assess]} reaction: {type: [string, 'null'], maxLength: 500} Allergy: allOf: - $ref: '#/components/schemas/AllergyCreate' - type: object required: [id, organizationId, patientId, clinicalStatus, version, recordedAt] properties: id: {$ref: '#/components/schemas/Uuid'} organizationId: {$ref: '#/components/schemas/Uuid'} patientId: {$ref: '#/components/schemas/Uuid'} clinicalStatus: {$ref: '#/components/schemas/ClinicalStatus'} version: {type: integer, minimum: 1} recordedAt: {type: string, format: date-time} AllergyResponse: type: object required: [data] properties: {data: {$ref: '#/components/schemas/Allergy'}} AllergyListResponse: type: object required: [data] properties: {data: {type: array, items: {$ref: '#/components/schemas/Allergy'}}} ConditionCreate: type: object additionalProperties: false required: [code, category, recordedByPractitionerId] properties: code: {$ref: '#/components/schemas/CodeableConcept'} category: {$ref: '#/components/schemas/ConditionCategory'} encounterId: {oneOf: [{$ref: '#/components/schemas/Uuid'}, {type: 'null'}]} onsetAt: {type: [string, 'null'], format: date-time} note: {type: [string, 'null'], maxLength: 1000} recordedByPractitionerId: {$ref: '#/components/schemas/Uuid'} ConditionPatch: type: object additionalProperties: false minProperties: 1 properties: clinicalStatus: {$ref: '#/components/schemas/ClinicalStatus'} verificationStatus: {$ref: '#/components/schemas/VerificationStatus'} abatementAt: {type: [string, 'null'], format: date-time} note: {type: [string, 'null'], maxLength: 1000} Condition: allOf: - $ref: '#/components/schemas/ConditionCreate' - type: object required: [id, organizationId, patientId, clinicalStatus, verificationStatus, version, recordedAt] properties: id: {$ref: '#/components/schemas/Uuid'} organizationId: {$ref: '#/components/schemas/Uuid'} patientId: {$ref: '#/components/schemas/Uuid'} clinicalStatus: {$ref: '#/components/schemas/ClinicalStatus'} verificationStatus: {$ref: '#/components/schemas/VerificationStatus'} abatementAt: {type: [string, 'null'], format: date-time} version: {type: integer, minimum: 1} recordedAt: {type: string, format: date-time} ConditionResponse: type: object required: [data] properties: {data: {$ref: '#/components/schemas/Condition'}} ConditionListResponse: type: object required: [data] properties: {data: {type: array, items: {$ref: '#/components/schemas/Condition'}}} MedicationCreate: type: object additionalProperties: false required: [medication, source, recordedByPractitionerId] properties: medication: {$ref: '#/components/schemas/CodeableConcept'} source: {type: string, enum: [patient_reported, external_record, clinician_recorded]} doseText: {type: [string, 'null'], maxLength: 300} route: {type: [string, 'null'], maxLength: 120} frequency: {type: [string, 'null'], maxLength: 120} startedAt: {type: [string, 'null'], format: date-time} recordedByPractitionerId: {$ref: '#/components/schemas/Uuid'} MedicationPatch: type: object additionalProperties: false minProperties: 1 properties: status: {type: string, enum: [active, completed, stopped, entered_in_error]} doseText: {type: [string, 'null'], maxLength: 300} route: {type: [string, 'null'], maxLength: 120} frequency: {type: [string, 'null'], maxLength: 120} endedAt: {type: [string, 'null'], format: date-time} Medication: allOf: - $ref: '#/components/schemas/MedicationCreate' - type: object required: [id, organizationId, patientId, status, version, recordedAt] properties: id: {$ref: '#/components/schemas/Uuid'} organizationId: {$ref: '#/components/schemas/Uuid'} patientId: {$ref: '#/components/schemas/Uuid'} status: {type: string, enum: [active, completed, stopped, entered_in_error]} endedAt: {type: [string, 'null'], format: date-time} version: {type: integer, minimum: 1} recordedAt: {type: string, format: date-time} MedicationResponse: type: object required: [data] properties: {data: {$ref: '#/components/schemas/Medication'}} MedicationListResponse: type: object required: [data] properties: {data: {type: array, items: {$ref: '#/components/schemas/Medication'}}} ClinicalRecordCreate: type: object additionalProperties: false required: [recordType, sensitivity, authorPractitionerId, content] properties: recordType: {type: string, enum: [progress_note, consultation_note, discharge_summary, procedure_note]} sensitivity: {type: string, enum: [normal, restricted, highly_restricted]} authorPractitionerId: {$ref: '#/components/schemas/Uuid'} content: {type: string, minLength: 1, maxLength: 100000} contentFormat: {type: string, enum: [text_markdown, structured_json], default: text_markdown} ClinicalRecordPatch: type: object additionalProperties: false minProperties: 1 properties: content: {type: string, minLength: 1, maxLength: 100000} sensitivity: {type: string, enum: [normal, restricted, highly_restricted]} ClinicalRecord: type: object additionalProperties: false required: [id, organizationId, patientId, encounterId, recordType, sensitivity, status, authorPractitionerId, currentVersion, version, createdAt, updatedAt] properties: id: {$ref: '#/components/schemas/Uuid'} organizationId: {$ref: '#/components/schemas/Uuid'} patientId: {$ref: '#/components/schemas/Uuid'} encounterId: {$ref: '#/components/schemas/Uuid'} recordType: {type: string} sensitivity: {type: string, enum: [normal, restricted, highly_restricted]} status: {type: string, enum: [draft, signed, amended, entered_in_error]} authorPractitionerId: {$ref: '#/components/schemas/Uuid'} signedByPractitionerId: {oneOf: [{$ref: '#/components/schemas/Uuid'}, {type: 'null'}]} signedAt: {type: [string, 'null'], format: date-time} currentVersion: {$ref: '#/components/schemas/ClinicalRecordVersion'} version: {type: integer, minimum: 1} createdAt: {type: string, format: date-time} updatedAt: {type: string, format: date-time} ClinicalRecordVersion: type: object additionalProperties: false required: [id, versionNumber, content, contentFormat, contentHash, createdByPractitionerId, createdAt] properties: id: {$ref: '#/components/schemas/Uuid'} versionNumber: {type: integer, minimum: 1} content: {type: string, maxLength: 100000} contentFormat: {type: string, enum: [text_markdown, structured_json]} contentHash: {type: string, pattern: '^[a-f0-9]{64}$'} createdByPractitionerId: {$ref: '#/components/schemas/Uuid'} createdAt: {type: string, format: date-time} ClinicalRecordResponse: type: object required: [data] properties: {data: {$ref: '#/components/schemas/ClinicalRecord'}} ClinicalRecordSummary: type: object required: [id, recordType, sensitivity, status, authorPractitionerId, version, updatedAt] properties: id: {$ref: '#/components/schemas/Uuid'} recordType: {type: string} sensitivity: {type: string} status: {type: string} authorPractitionerId: {$ref: '#/components/schemas/Uuid'} version: {type: integer} updatedAt: {type: string, format: date-time} ClinicalRecordListResponse: type: object required: [data] properties: {data: {type: array, items: {$ref: '#/components/schemas/ClinicalRecordSummary'}}} SignClinicalRecordCommand: type: object additionalProperties: false required: [practitionerId, attestation] properties: practitionerId: {$ref: '#/components/schemas/Uuid'} attestation: {type: string, minLength: 10, maxLength: 500} AmendClinicalRecordCommand: type: object additionalProperties: false required: [practitionerId, amendmentType, reason, content] properties: practitionerId: {$ref: '#/components/schemas/Uuid'} amendmentType: {type: string, enum: [correction, addendum, clarification]} reason: {type: string, minLength: 3, maxLength: 1000} content: {type: string, minLength: 1, maxLength: 100000} ClinicalRecordHistoryResponse: type: object required: [recordId, versions, amendments] properties: recordId: {$ref: '#/components/schemas/Uuid'} versions: {type: array, items: {$ref: '#/components/schemas/ClinicalRecordVersion'}} amendments: type: array items: type: object required: [id, sourceVersionId, resultVersionId, practitionerId, amendmentType, reason, createdAt] properties: id: {$ref: '#/components/schemas/Uuid'} sourceVersionId: {$ref: '#/components/schemas/Uuid'} resultVersionId: {$ref: '#/components/schemas/Uuid'} practitionerId: {$ref: '#/components/schemas/Uuid'} amendmentType: {type: string, enum: [correction, addendum, clarification]} reason: {type: string} createdAt: {type: string, format: date-time} StartEncounterCommand: type: object additionalProperties: false properties: startedAt: {type: string, format: date-time} FinishEncounterCommand: type: object additionalProperties: false properties: endedAt: {type: string, format: date-time} ReasonCommand: type: object additionalProperties: false required: [reason] properties: reason: {type: string, minLength: 3, maxLength: 500} OptionalReasonCommand: type: object additionalProperties: false properties: reason: {type: string, minLength: 3, maxLength: 500} CursorPage: type: object additionalProperties: false required: [hasMore] properties: nextCursor: {type: [string, 'null']} hasMore: {type: boolean} FieldError: type: object additionalProperties: false required: [field, code, message] properties: field: {type: string} code: {type: string} message: {type: string} Problem: type: object additionalProperties: false required: [type, title, status, code, requestId] properties: type: {type: string, format: uri-reference} title: {type: string} status: {type: integer, minimum: 400, maximum: 599} detail: {type: string} code: {type: string} requestId: {type: string} errors: {type: array, items: {$ref: '#/components/schemas/FieldError'}}