1779 lines
75 KiB
YAML
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'}}
|