ediverse Explore the platform

Spotlight PEPPOL BIS Billing 3.0 The EU e-invoicing mandate is here — France Sept 2026, Belgium Jan 2026, Germany 2025.

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:

FieldTypeCardinalityRole
identifierIdentifier[]0..*External identifiers (EHR business number, HRIS planning code…).
activeboolean0..1Schedule live or archived. false = historical archive.
serviceCategoryCodeableConcept[]0..*Broad category of service offered on this calendar.
serviceTypeCodeableReference[]0..*Specific service type.
specialtyCodeableConcept[]0..*Medical specialty (SNOMED CT).
namestring0..1Human-readable label shown in UIs (often the practitioner or location name).
actorReference(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.
planningHorizonPeriod0..1Booking horizon. Attached Slots should not fall outside this window.
commentmarkdown0..1Notes 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.

json schedule-example.json
{
  "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:

  • actor lists two references: the practitioner and the physical location. A single Schedule may cover a person + place combination.
  • serviceCategory and serviceType let the patient app filter on "availability for vaccination".
  • planningHorizon is bounded. Past 30 June, the front desk must extend the Schedule or create a follow-on one.
  • comment is 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 of actor references.

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 is 1..*. A Schedule with no actor is invalid and rejected by the validator.
  • Slot outside planningHorizon — creating a Slot whose start falls 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 via serviceCategory.
  • Mutable identifiers — the business identifier must not change between two versions of the Schedule or the HRIS reconciliation breaks.
  • Slot — the unit slots that the Schedule contains and that hold the free / busy status.
  • 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.