Files
professional_management/healthcare-api-foundation_4.yaml
2026-08-27 21:52:21 -04:00

1779 lines
75 KiB
YAML

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'}}