Skip to main content

Scheduling Service — API Contracts

Status: populated Owner: TBD Last updated: 2026-04-17 Companion: Service Template · 03 platform-services · API_PATH_CONVENTIONS

Common Headers

HeaderValueRequired
AuthorizationBearer <JWT>Yes
Content-Typeapplication/jsonYes (mutations)

Module entitlement guard: ehr.scheduling.

1. Appointments

MethodPathDescriptionAuth Roles
POST/api/v1/appointmentsBook appointmentadmin, scheduler, physician, front-desk
POST/api/v1/appointments/selfPatient self-book (patientId from JWT)patient
GET/api/v1/appointments?patientId=&status=List patient appointmentsauthenticated
GET/api/v1/appointments/calendar?from=&to=&facilityId=&providerIds=Staff calendar viewadmin, scheduler, physician, front-desk, nurse
GET/api/v1/appointments/:idGet by IDauthenticated
PUT/api/v1/appointments/:id/statusUpdate statusadmin, scheduler, physician, front-desk, nurse
PUT/api/v1/appointments/:id/cancelStaff canceladmin, scheduler, physician, front-desk
PUT/api/v1/appointments/:id/cancel-selfPatient cancel ownpatient
PUT/api/v1/appointments/:id/rescheduleReschedule to new slotadmin, scheduler, physician, front-desk

POST /api/v1/appointments — Book

Request body

FieldTypeRequiredNotes
patientIdUUIDYes
slotIdUUIDYesMust be free
appointmentTypestringNoROUTINE/WALKIN/EMERGENCY etc.
providerIdUUIDNo
locationIdUUIDNo
reasonstringNo
allowDoubleBookingbooleanNoAdmin/scheduler only
versionnumberNoRequired for reschedule

Responses

HTTPCondition
201Appointment created; returns AppointmentResponseDto with id, status: booked, slotId, patientId
409 SLOT_NOT_AVAILABLESlot is not free
409 DOUBLE_BOOKING_DETECTEDOverlap and override not permitted
403 DOUBLE_BOOKING_OVERRIDE_DENIEDOverride requested but caller lacks permission

PUT /api/v1/appointments/:id/cancel

Request body: { "reason": "string", "version": number }

HTTPErrorCondition
200Updated AppointmentResponseDto (status: cancelled)
409OPTIMISTIC_LOCK_CONFLICT
409INVALID_STATUS_TRANSITION

PUT /api/v1/appointments/:id/reschedule

Request body: { "newSlotId": "uuid", "version": number, "reason?": "string" }

HTTPErrorCondition
200Updated AppointmentResponseDto
409NEW_SLOT_NOT_AVAILABLE

2. Schedules

MethodPathDescriptionAuth
POST/api/v1/schedulesCreate scheduleadmin, scheduler
GET/api/v1/schedules?actorId=List schedulesauthenticated
GET/api/v1/schedules/:idGet scheduleauthenticated
PUT/api/v1/schedules/:idUpdate scheduleadmin, scheduler
POST/api/v1/schedules/availability-previewPreview expanded windowsadmin, scheduler, physician, front-desk, nurse
POST/api/v1/schedules/:id/exceptionsAdd blocked window / holidayadmin, scheduler, physician, front-desk, nurse

Schedule create/update body (selected fields)

FieldTypeNotes
actorIdUUIDProvider, location, or device
actorTypeprovider|location|device
timezoneIANA stringe.g. Asia/Kabul (+04:30)
availabilityPatternobject{ days: [{ dow: 0-6, start: "HH:MM", end: "HH:MM" }] }

3. Slots

MethodPathDescriptionAuth
POST/api/v1/slotsCreate slotadmin, scheduler
GET/api/v1/slots?scheduleId=&from=&to=Free slots for one scheduleauthenticated
GET/api/v1/slots/availability?providerId=&locationId=&from=&to=Aggregated free slots (requires providerId and/or locationId + from/to)authenticated
GET/api/v1/slots/by-schedule/:scheduleId?status=All slots for scheduleauthenticated
GET/api/v1/slots/:idGet slotauthenticated
PUT/api/v1/slots/:idUpdate slotadmin, scheduler

Slot status values: free | busy | blocked | entered-in-error

Availability aggregation notes

  • GET /api/v1/slots/availability requires at least providerId or locationId and from + to (ISO dates).
  • Returns consolidated free slots across all matching schedules.
  • NFR-SCHED-001: p95 < 1 000 ms.

4. Waitlist

MethodPathDescriptionAuth
POST/api/v1/waitlistAdd to waitlistadmin, scheduler, clinician
GET/api/v1/waitlist?status=List entriesauthenticated
GET/api/v1/waitlist/:idGet entryauthenticated
PUT/api/v1/waitlist/:id/fulfillMark fulfilledadmin, scheduler
DELETE/api/v1/waitlist/:idSoft-deleteadmin, scheduler

Waitlist create body

FieldTypeRequiredNotes
patientIdUUIDYes
appointmentTypestringYes
scheduleIdUUIDNo
criteriaobjectNoFree form matching hints
priorityintegerNoLower = higher priority; default: FIFO
notestringNo

5. HL7 v2 SIU Integration

MethodPathDescriptionAuth
POST/api/v1/integration/hl7/siuInbound raw SIU messageadmin

Request body: { "message": "MSH|...\r..." }

Supports: S12 (create), S13 (modify), S15 (cancel).

6. FHIR R4

Base path: /fhir/R4 (same auth + ehr.scheduling).

InteractionPathNotes
ReadGET /fhir/R4/Appointment/:id
SearchGET /fhir/R4/Appointment?patient=Patient/:id&status=
ReadGET /fhir/R4/Slot?schedule=Schedule/:id&status=
ReadGET /fhir/R4/Schedule/:id

FHIR Appointment status mapping: proposed, pending, booked, arrived, fulfilled, cancelled, noshow, entered-in-error.