Scheduling over HL7
HL7 scheduling looks simple until you try to build a calendar from it. At first you see an SCH segment, a patient, a date, and maybe a provider. Nice. Then the real feed arrives and the appointment time is in one place, the clinic is in another, the room lives in AIL, the provider is in AIP, the procedure is in AIS, and the scanner or chair is hiding in AIG. That is when you discover that scheduling is not one field. It is a little resource model.
The main scheduling message most people meet is SIU, Scheduling Information Unsolicited. That is the notification style: a scheduling system tells another system that an appointment was booked, changed, cancelled, deleted, blocked, opened, or marked as a no-show. There are also request and query patterns, such as SRM/SRR for appointment requests and responses, and SQM/SQR for schedule queries. But in everyday interfaces, SIU is the one that keeps turning up because systems need to keep each other's appointment view in sync.
The mental model that helps is this: SCH is the appointment shell. AIS says what service is being scheduled. AIL says where. AIP says who. AIG says what general resource is needed, such as equipment. RGS groups those resources together. If you keep those roles separate, the message starts to look much less mysterious.
That example is a fairly healthy SIU S12. It gives one stable appointment ID, one appointment time, the patient, the rough visit/location context, then the detailed scheduled service, room, person, and equipment. A lot of real messages are thinner than this, and that is fine. The trick is knowing which facts are missing because the workflow does not need them, and which facts are missing because the interface is under-specified.
The appointment, the schedule, and the resources
HL7's scheduling chapter talks about schedules, appointments, services, and resources. That is not academic language; it is exactly how the feed behaves. A schedule is the diary or calendar controlled by the scheduling system. A slot is open, booked, or blocked time on that schedule. An appointment occupies one or more booked slots. A service is the thing being done, such as a clinic visit, scan, procedure, class, therapy session, or vaccination appointment. A resource is the thing or person being reserved so that service can happen.
The filler is the system that owns the schedule. In a hospital this might be the main scheduling application, a radiology scheduler, an outpatient clinic system, theatre booking, or a departmental system. The placer is the system or person requesting the appointment. This placer/filler split matters because appointment identifiers, status, and authority often follow that same split. If the filler says the appointment is cancelled, that usually means more than a downstream system deciding it does not want to display it.
Which segment owns which fact?
| Segment | What it is for | Fields I care about first |
|---|---|---|
| SCH | The appointment header: identifiers, reason, duration, timing, contacts, status, parent IDs, and linked order numbers. | SCH-1, SCH-2, SCH-6, SCH-7, SCH-8, SCH-9/10, SCH-11, SCH-16, SCH-20, SCH-25, SCH-26/27 |
| RGS | Resource group. It ties a set of AIS/AIG/AIL/AIP segments together as one resource set for the appointment. | RGS-1 set ID, RGS-2 action code, RGS-3 resource group ID |
| AIS | The scheduled service: what is being booked or performed. | AIS-1, AIS-2, AIS-3, AIS-4, AIS-7/8, AIS-10, AIS-11/12 |
| AIG | General resources that are not naturally a person or location, usually equipment or resource categories. | AIG-1, AIG-2, AIG-3, AIG-4, AIG-6/7, AIG-8, AIG-11/12, AIG-14 |
| AIL | Location resources: rooms, theatres, bays, clinics, departments, and other schedulable places. | AIL-1, AIL-2, AIL-3, AIL-4, AIL-5, AIL-6, AIL-9/10, AIL-12 |
| AIP | Personnel resources: providers, nurses, technicians, surgeons, anaesthetists, and other schedulable staff. | AIP-1, AIP-2, AIP-3, AIP-4, AIP-5, AIP-6, AIP-9/10, AIP-12 |
| TQ1 | Timing/quantity when the interface wants timing outside the old SCH-11 TQ field. | TQ1-1, TQ1-7, TQ1-8, TQ1-9, TQ1-13 |
SCH is the appointment shell
If you are building an appointment table from SIU messages, start with SCH. The two big identifiers are SCH-1 and SCH-2: placer appointment ID and filler appointment ID. The filler appointment ID is usually the one I want to use as the durable appointment key when the scheduler is sending notifications. The placer appointment ID is still useful for tying the booking back to the request that created it.
SCH-11 is often where the appointment start and end live in older and common SIU feeds. The existing SCH from experience page goes into that field in detail. The short version is: inspect the actual sender's messages and write down which timing field is authoritative. SCH-9/10 duration, SCH-11 timing, TQ1, and resource-segment timing can all appear. If they disagree, the receiver needs a rule, not a guess.
SCH-25 is the appointment status from the filler side. This is not the same thing as the trigger event in MSH-9. SIU^S15 tells you the message is a cancellation notification. SCH-25 tells you the appointment status that should probably end up in your calendar. That status map deserves proper testing: Booked, Pending, Waitlist, Overbook, Cancelled, Noshow, Started, Complete, Blocked, Deleted, and Discontinued are not cosmetic differences.
AIS says what service is being scheduled
AIS is where I look for the thing the patient is coming for. In radiology that might be the scan or modality. In clinics it may be the appointment service. In therapy it may be the treatment session. In vaccination or procedure clinics it may be the scheduled service slot. AIS-3, Universal Service Identifier, is the heart of the segment.
Do not make the appointment reason do the service's job if AIS is available. SCH-7 might say follow-up, routine, emergency, or X-ray appointment. AIS-3 can say exactly which service was booked. That difference becomes important when reporting, routing, patient instructions, resource allocation, or billing needs to know whether "Radiology" meant chest X-ray, CT abdomen, ultrasound, or a pre-procedure consult.
AIS also has its own start time, duration, and filler status. That is useful when an appointment contains more than one service, or when a service starts after the main appointment start. For a simple one-service booking, AIS timing may match SCH timing. For a complex visit, it may not, and that is not necessarily an error.
AIL says where
AIL is the location resource. This is where room, theatre, clinic, exam bay, department, or location group details belong when the location is being scheduled. The location resource ID uses PL, the same broad location shape you see elsewhere in HL7, so you can carry point of care, room, bed, facility, and related location components.
One common question is "where do I get the department or clinic?" The honest answer is: check the local feed. Sometimes it is in AIL-3 as a location resource. Sometimes AIL-5 gives a location group. Sometimes SCH-5 names the schedule, and PV1-3 gives the patient visit location. Sometimes the service code in AIS is the nearest clean value. Do not assume a label next to a provider is the location just because it looks like a department name in the sample.
For downstream systems, AIL is especially useful when rooms matter: theatres, imaging rooms, treatment chairs, endoscopy rooms, procedure rooms, and clinic rooms. If the receiver only needs "patient has an appointment at Radiology", AIL may feel optional. If the receiver has to avoid double-booking Room XR1, AIL becomes central.
AIP says who
AIP is for schedulable people. That could be the consultant, nurse, technician, anaesthetist, surgeon, interpreter, therapist, or another staff member whose time is actually being reserved. AIP-3 gives the person, AIP-4 says the resource role or type, and AIP-6 through AIP-10 can give the person's timing and duration within the appointment.
This is not the same as PV1 attending doctor, SCH entered-by, SCH filler contact, or the ordering provider. The same person can appear in several of those roles, but the meaning is different. If the question is "who will see the patient in this appointment?", AIP is often the better answer. If the question is "who entered the appointment?", SCH-20 is the answer. If the question is "who ordered the service?", look at the order context.
AIG says what else is reserved
AIG is the general resource bucket. It is where you put resources that are schedulable but are not locations and are not people. Equipment is the classic example: imaging machine, infusion chair, laser, special instrument set, trolley, vehicle, room kit, or a resource category that the filler application controls.
AIG-3 identifies the resource, AIG-4 gives the resource type, AIG-6/7 can carry quantity and units, and AIG-8 through AIG-12 can carry timing and duration. If the resource can be substituted, AIG-13 says whether that is allowed. This is where scheduling stops being just "appointment at 10:30" and becomes "appointment at 10:30 using this room, this clinician, and this equipment".
RGS quietly matters
RGS is easy to ignore because it is short, but it is the grouping segment that makes the resource set hang together. One RGS can group an AIS service, an AIL location, an AIP provider, and an AIG equipment item. If the appointment has several resource groups, the set IDs and action codes tell you which collection of resources each update is talking about.
This matters most when updates are partial. A message may add one provider, delete one room, or update one service without restating the entire appointment. In that world, the segment action codes on AIS, AIG, AIL, and AIP become very important. Table 0206 is simple enough: add, delete, update, no change. The hard part is getting both systems to agree whether each SIU message is a full snapshot or a delta.
SIU events are not all the same update
The familiar SIU events include S12 for a new appointment booking, S13 for rescheduling, S14 for modification, S15 for cancellation, S17 for deletion, S18 through S22 for adding, modifying, cancelling, discontinuing, or deleting services/resources, S23 for blocked schedule time, S24 for opened schedule time, and S26 for no-show. They share a common message shape, but they should not all be handled the same way.
A reschedule should usually update the same appointment ID with new timing. A cancellation should leave an appointment record with cancelled status if your application needs history. A deletion may mean the booking was removed from the filler system and should not appear as a normal cancelled appointment. A no-show is not a cancellation. A block or open slot message may not even have the same patient-centered meaning as a booked patient appointment.
This is one of the places where test packs need to be richer than "one S12 works". Ask for examples of new, reschedule, modify, cancel, delete, no-show, and resource-only updates. Also ask whether the sender repeats the full appointment on every update or sends only the changed pieces. If you do not know that before go-live, the first reschedule will teach you in production.
Timing is the usual trap
Scheduling messages can carry time in several places. Older feeds often use SCH-11. Some v2.5.1-oriented profiles prefer TQ1 for appointment date/time. AIS, AIG, AIL, and AIP can each carry start time, offset, duration, and duration units, because the service, room, equipment, and staff member may not all start and finish at exactly the same moment.
So the rule I like is: store the overall appointment time and the resource-specific times separately. The appointment might run from 10:30 to 11:00. The room may be blocked from 10:15 to 11:10. The technician may only be assigned from 10:30 to 10:45. Those are not contradictory facts. They are different scheduling facts.
Duration units are another small pain point. You will see min, m, hr, h, local codes, and sometimes blank units where everyone "knows" the default is minutes. Normalize internally, but keep the raw value. And if your site spans time zones or daylight-saving changes, do not wait until the clocks change to decide whether timestamps carry offsets or local wall-clock time.
Minimum useful data
For a simple appointment feed, the minimum useful payload is usually: patient identity in PID, a stable appointment identifier in SCH-1 or SCH-2, a clear appointment status in SCH-25, a start and end time in SCH-11 or TQ1, and enough reason/type/service information to display the appointment sensibly. If you only have those values, you can still maintain a basic appointment list.
For a better feed, add AIS for the service, AIL for the location, AIP for the schedulable person, and AIG for equipment or other resources. Add PV1 only if visit or encounter context matters. Add DG1 or OBX only when there is a real diagnosis or observation context. And use NTE for human comments, not for room codes, provider IDs, service IDs, or status values that a computer needs to understand.
Common pain points
The first pain point is duplicate appointments. If you key on patient plus start time, a reschedule can create a duplicate and a same-day double appointment can overwrite the wrong row. Key on appointment identifiers. Store placer and filler IDs. Treat incoming S12/S13/S14/S15 messages as changes to the same appointment when the identifier says they are the same appointment.
The second pain point is confusing location, department, service, and provider. In a sample message, "X-ray" might be a service, a schedule, a department, a location group, or a local display label. Do not guess from the word. Ask which segment and field is authoritative for department, clinic, room, and service.
The third pain point is status. A system that treats cancelled, deleted, discontinued, blocked, and no-show as the same state will work right up until someone asks why the audit trail is wrong. Store the original status code, map it deliberately, and keep event history when you can.
The fourth pain point is partial resource updates. If an S18 adds a resource and your receiver replaces the whole appointment with just that resource, the appointment loses its room, service, or provider. Decide whether resource updates are additive, destructive, or full-snapshot. Then test exactly that.
The fifth pain point is using scheduling messages as clinical orders. A scheduling message may link to a placer or filler order number in SCH-26 and SCH-27, but that does not automatically mean the appointment should create a clinical order. If your workflow does create orders from scheduling, be very explicit about ownership and cancellation behaviour. Otherwise a scheduling clerk can accidentally become an order-entry system.
How I would design the receiver
I would store appointment identity separately from patient identity. I would keep both placer and filler appointment IDs, message control ID, trigger event, appointment status, raw status, overall start/end, and the source system that owns the appointment. Then I would store service, location, personnel, and general resource assignments in child tables or child objects, keyed by their segment set IDs and resource identifiers where possible.
I would also keep an event log. Scheduling is a timeline: new, moved, modified, cancelled, no-show, rebooked. If you only store the current row, you can display today's appointment list, but you cannot explain how it got there. That may be fine for a small display feed. It is not fine for audit-heavy clinics, referrals, operating rooms, imaging, or anything where patient attendance and resource use matter.
Finally, I would build validation around contradictions. If the message says S15 but SCH-25 says Booked, log it or reject it depending on the workflow. If SCH-11 and TQ1 disagree, do not silently pick one forever. If AIP names a provider but the role is blank, decide whether your receiver can live with that. Scheduling feeds are full of local behaviour, and local behaviour is only safe when it is written down.
Related reading
- HL7 SCH scheduling activity from experience
- HL7 TQ1 timing/quantity from experience
- HL7 TQ2 timing relationship from experience
- Receive SIU S12 appointments and write them to SQL Server
- HL7 segments guide from experience