Your scheduler thinks the provider is the only resource. Your day knows better.
Most schedulers are calendar grids. We treat the practice as a graph of resources and solve the day at minute resolution — re-optimizing live.
The signature view
One morning, every resource, minute by minute.
This is what the solver actually reasons about: not a provider column, but every resource a visit touches — the doctor, the MA, two exam rooms, the telehealth bridge, the X-ray suite — allocated in parallel across a real Tuesday morning. Watch the 9:30 overrun re-flow and a 9:50 walk-in get absorbed without anyone breaching their wait-time SLA.
Each block is a visit stage holding a named resource for a fixed duration; the constraint solver places all five patients' stages on the resource graph at once and re-floats downstream stages in under 2 seconds when reality intrudes. The same morning on a calendar grid would have double-booked Room 1 at 9:45 and pushed every afternoon patient late.
The problem
One visit consumes five or six resources. Grid schedulers see one.
The real workflow — check-in → rooming → provider eval → nurse follow-up → checkout — spans the front desk, the waiting room, an MA, an exam room, the provider, and an RN. Calendar grids double-book rooms, ignore MA capacity, and when the morning runs late, nothing re-flows. Everyone after 11 am pays the price.
Visits are routes through the graph
An “Established Adult Office Visit” is a sequence of stages with named resources: Check-in (3 min, front desk) → Rooming & vitals (7 min, MA + exam room) → Provider eval (18 min, provider + same exam room) → Nurse follow-up (5 min, RN) → Checkout (4 min, front desk). Stages are first-class objects — the room is held across stages, the MA is released after rooming. Practices configure their own visit-type compositions.
The solver explains itself
Search for a 30-minute slot on Thursday afternoon and the constraint solver evaluates provider availability, room availability, MA capacity, and equipment dependencies at minute resolution — in under 250 milliseconds. It returns the three best feasible windows and explains why others were rejected: room conflict, MA overload, lunch block. Pick 2:14 pm; the visit books atomically across every resource it needs.
Key capabilities
A schedule that absorbs reality.
Resource-graph solver
Multi-resource constraint solving at minute resolution. Surfaces feasible alternatives, re-optimizes when visits run long, books atomically across resources.
Patient self-scheduling
Established patients book from the portal at 9 pm without a phone call — filtered by plan network and practice policy, with an eligibility check fired automatically and a cost estimate shown at booking.
Walk-in absorption
Triage-prioritized insertion finds the smallest feasible window in the next 90 minutes that doesn't push any booked patient past their wait-time SLA — or offers same-day telehealth with the trade-off explained.
Waitlist auto-fill
A 9:00 am no-show is detected at the 10-minute mark; the slot is released and offered by SMS to the top waitlist match with a 5-minute reply window. Rebooked, verified, done.
Reminder ladder
T-30, T-14, T-3, and T-day touches with TCPA-compliant opt-in tracking. Replies trigger self-rebook or cancellation flows automatically.
Telehealth as a real resource
Telehealth is a dedicated resource type with its own capacity, not a checkbox. Hybrid sessions cap concurrent video visits so every connection stays stable.
Recurring & group visits
A diabetes group class every Tuesday at 4 pm: one shared resource graph, eight independently tracked, waitlisted, and reminded seats.
Live status board
Who is roomed, who is waiting, who is over time — in real time, with a display mode for back-office wall screens.
FHIR Schedule/Slot export
US Core-conformant FHIR Schedule, Slot, and Appointment resources through the standard API surface. Your schedule is data, not a silo.
The data model
Seven objects, one resource graph.
The engine isn't a calendar with extra columns — it's a small set of first-class entities the solver reasons over. Every one is org-scoped, version-vectored for safe concurrent booking, and exportable as FHIR R4.
Resource
Provider, MA/RN, exam room, equipment, front-desk, telehealth bridge, waiting room — each a schedulable node with capability tags (ECG, BPCuff, Spanish) and a capacity (1 for a room, 4 for a telehealth bridge).
VisitType → VisitStage
A visit type composes ordered stages — CheckIn, Rooming, ProviderEval, NurseFollowUp, Checkout — each declaring its required resource kinds, its duration, and whether it holds the exam room from the prior stage.
Schedule & Slot
Slots are atomic to the solver: Free, Held (a transient lock during booking), Busy, or Cancelled. A ResourceVersionInt vector guarantees no double-book under concurrent load — the loser gets a retry signal, never a collision.
Appointment
The committed booking, with a status machine (Booked → Confirmed → CheckedIn → InProgress → Completed, or NoShow/Cancelled/Rescheduled) and reschedule-chain back-references.
WaitlistEntry
A standing offer to take an earlier slot, scored 0–100 on tenure and clinical need. On any release, the top match gets a 5-minute SMS offer before the slot is re-opened to the world.
The graph itself
A constraint-programming kernel (OR-Tools / Timefold) searches a free/busy mask at one-minute granularity over a 60-day-forward, 14-day-back horizon, optimizing for minimum makespan and minimum patient wait.
Constraints, explained
Hard rules it never breaks. Soft rules it optimizes against.
When the solver rejects a window, it tells you which rule fired — so “1:30 won't work” comes with “exam-room conflict with the physical next door,” not a silent gray-out.
| Rule | Type | What it enforces |
|---|---|---|
| Room capacity | Hard | An exam room can't host two appointments' stages at once; capacity is 1 unless the slot explicitly allows overbooking. |
| Provider availability | Hard | New bookings must fit the provider's computed free intervals — schedule minus blocks minus existing appointments. |
| MA / RN concurrency | Hard | An MA can't be in two rooming stages simultaneously unless configured with higher capacity (e.g. a triage RN). |
| Capability-tag match | Hard | Required stage tags (ECG, Spanish) must be a subset of the assigned resource's tags — a missing tag is infeasible, with an explanation. |
| Telehealth bridge capacity | Hard | Concurrent video visits can't exceed the bridge's configured capacity, so every connection stays stable. |
| Concurrency / version vector | Hard | A commit fails if the slot's version changed since search — the client re-fetches and retries; no double-booking under load. |
| Wait-time SLA on walk-ins | Soft | A walk-in insertion must not push any booked appointment past its committed wait-time SLA (default 12 min p95). |
| Eligibility precondition | Soft | Visit types that require it fire a 270/271 at booking; a coverage problem surfaces as a warning, configurable to block. |
| Reschedule-chain length | Soft | A reschedule chain three deep prompts a manual review — a quiet signal of an access or adherence problem. |
Workflow
A booking call, minute by minute.
Front desk searches
“30-minute established visit, Thursday afternoon, Dr. Lee.” The solver answers in under a quarter second.
Three feasible windows, with reasons
2:14 pm, 3:05 pm, 4:20 pm — and an explanation of why 1:30 pm wouldn't work (exam-room conflict with the physical next door).
Booked atomically
Provider, room, MA window, and BP equipment reserved in one transaction. An eligibility check fires in the background.
The reminder ladder takes over
T-3 SMS confirmed by the patient; the no-show model stays quiet because this patient always shows.
Thursday runs on time
The 1:45 physical runs 12 minutes long; the solver re-flows the afternoon and the wall board updates. Nobody waits past their SLA.
Who benefits
Sub-second search, one-click cancellation, a waitlist that fills itself. Walk-ins stop being emergencies.
Slot-utilization dashboards, bottleneck visibility by resource, no-show patterns, walk-in absorption rates.
The day actually runs on time. Flag a long visit and the rest of the morning re-flows instead of cascading.
A clear “next patient ready to room” queue, a five-minute vitals screen, an alert when the provider frees up.
Books at 9 pm from the couch, sees the cost up front, waits less than 12 minutes at the 95th percentile.
Performance targets
The numbers this module is built to hit.
| Metric | Target |
|---|---|
| 95th-percentile patient wait (arrival → rooming) | ≤ 12 minutes |
| Slot utilization (booked / available minutes) | ≥ 90% |
| No-show rate after waitlist auto-fill | < 6% |
| Self-scheduling share of bookings | ≥ 35% by month 6 |
| Solver runtime (30-day search, 6 providers, 12 rooms) | ≤ 250 ms p95 · ≤ 500 ms p99 |
| Single-slot conflict detection (60-day horizon) | ≤ 200 ms |
| Live status-board latency (stage transition) | ≤ 2 seconds |
| Walk-ins absorbed without SLA breach | ≥ 70% |
| Reminder dispatched within 5 min of fire-time | 99.5% monthly |
| Reminder-ladder reply rate | ≥ 60% respond at least once |
Standards & interoperability
Your schedule is data, not a silo.
Connected modules
The appointment is where everything starts.
Run a day that respects everyone's time.
Twelve-minute waits, sub-6% no-shows, and a front desk that stops apologizing.
Join the waitlist