Schedule — Calendar of a healthcare actor
The availability container. A Schedule describes the booking horizon for a practitioner, room or piece of equipment without carrying Appointment data itself — it's the envelope around the Slots.
Purpose of the resource
Schedule is a container of time intervals that may be booked as Appointments. It establishes the window in which an actor (practitioner, location, device, team) accepts being booked, while staying cleanly separate from the Appointment data — that separation is what allows exposing a doctor's availability without revealing the identity of patients already booked.
Schedule is never standalone in a booking workflow: it operates as a triptych with Slot (the unit time windows it holds) and Appointment (the bookings that consume them). Visibility policies are enforced at the Schedule level — patient apps see only public Schedules, the front desk sees every Schedule.
Key fields
The R5 StructureDefinition lists nine top-level elements. Summary of the structural fields:
| Field | Type | Cardinality | Role |
|---|---|---|---|
identifier | Identifier[] | 0..* | External identifiers (EHR business number, HRIS planning code…). |
active | boolean | 0..1 | Schedule live or archived. false = historical archive. |
serviceCategory | CodeableConcept[] | 0..* | Broad category of service offered on this calendar. |
serviceType | CodeableReference[] | 0..* | Specific service type. |
specialty | CodeableConcept[] | 0..* | Medical specialty (SNOMED CT). |
name | string | 0..1 | Human-readable label shown in UIs (often the practitioner or location name). |
actor | Reference(Patient | Practitioner | PractitionerRole | RelatedPerson | Device | HealthcareService | Location)[] | 1..* | The actor or actors whose availability this calendar describes. At least one — often a Practitioner + a Location. |
planningHorizon | Period | 0..1 | Booking horizon. Attached Slots should not fall outside this window. |
comment | markdown | 0..1 | Notes shown to schedule consumers (usage rules, special blocks…). |
JSON example
Calendar of Dr Adam Careful for the "South Wing, second floor" consultation room, open 14 May to 30 June 2026, with an editorial comment for the front desk.
{
"resourceType": "Schedule",
"id": "example",
"identifier": [{
"use": "usual",
"system": "http://example.org/scheduleid",
"value": "45"
}],
"active": true,
"serviceCategory": [{
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/service-category",
"code": "17",
"display": "General Practice"
}]
}],
"serviceType": [{
"concept": {
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/service-type",
"code": "57",
"display": "Immunization"
}]
}
}],
"specialty": [{
"coding": [{
"system": "http://snomed.info/sct",
"code": "408443003",
"display": "General medical practice"
}]
}],
"name": "Burgers UMC, South Wing, Second floor",
"actor": [
{ "reference": "Practitioner/example" },
{ "reference": "Location/1", "display": "South Wing, second floor" }
],
"planningHorizon": {
"start": "2026-05-14T09:00:00+02:00",
"end": "2026-06-30T17:00:00+02:00"
},
"comment": "Morning blocks are reserved for new patients; afternoons for follow-ups."
} Worth pointing out in this example:
actorlists two references: the practitioner and the physical location. A single Schedule may cover a person + place combination.serviceCategoryandserviceTypelet the patient app filter on "availability for vaccination".planningHorizonis bounded. Past 30 June, the front desk must extend the Schedule or create a follow-on one.commentis markdown — handy for apps that render formatted text.
Searching the associated Slots
A client app typically doesn't query /Schedule directly — it walks the
organisation's Schedules by actor or serviceType, then asks
the server for the Slots that populate them:
GET /Schedule?actor=Practitioner/example&active=true— fetch the active Schedules for the given practitioner.GET /Slot?schedule=Schedule/example&status=free&start=ge2026-05-22— fetch the attached free slots.GET /Schedule?actor:Practitioner.specialty=394814009— chained FHIR search on the practitioner-actor specialty.GET /Schedule?_include=Schedule:actor— direct inclusion ofactorreferences.
The US Core and Argonaut Scheduling profiles add a $find operation on
/Schedule/$find to automate slot discovery from criteria (specialty,
geography, time window).
Common pitfalls
- Schedule without
actor— cardinality is1..*. A Schedule with no actor is invalid and rejected by the validator. - Slot outside
planningHorizon— creating a Slot whosestartfalls outside the parent Schedule's window is technically allowed (no strict FHIR invariant) but semantically wrong — booking apps will ignore it. - Schedule / Appointment confusion — Schedule is never the right place for patient information. It describes only an actor's availability. Appointment details belong in Appointment.
- Active Schedule with no Slot attached — from the patient app's perspective, the result is identical to an inactive Schedule. Publish at least one Slot range as soon as a Schedule flips to
active=true. - Multiple Schedules for the same
actor+planningHorizon— technically allowed but confusing. Prefer a single Schedule covering the whole horizon, splitting concerns viaserviceCategory. - Mutable identifiers — the business
identifiermust not change between two versions of the Schedule or the HRIS reconciliation breaks.
Related resources
- Slot — the unit slots that the Schedule contains and that hold the
free/busystatus. - Appointment — the booking that consumes one or more Slots of the Schedule.
- Practitioner, PractitionerRole, Location, Device — typical actors whose availability the Schedule describes.
- HealthcareService — the abstract care service a Schedule may reference as actor.
See also: the FHIR R5 index.