Resources

How to Fill Cancelled Appointments in Healthie

By Federico Ruiz Cassarino, CEO and founder, Puppeteer AI · · 7 min read

A patient cancels Tuesday at 2pm. Someone at the front desk notices, thinks of two or three people who might take it, and starts texting. By the time anyone replies it's Tuesday afternoon, and the slot is gone.

That's not a staffing problem. It's that the open slot and the patient who wants it are never in the same place at the same time. Healthie will tell you the instant a slot frees up. What it won't tell you is who to offer it to.

This is a walkthrough of what Healthie's API actually gives you here, field by field, and where you have to build on top of it.

How Healthie models an appointment

The field names are worth knowing, because they aren't what you'd guess from the UI. A Healthie appointment carries two independent state fields.

  • pm_status. A string. A cancellation lands here, as "Cancelled".
  • confirmed. A boolean. Whether the patient confirmed.

Read the whole vocabulary before you write the matcher. Healthie's own wording is that pm_status “can be one of "Occurred", "No-Show", "Re-Scheduled", "Cancelled". If enabled, "Late Cancellation" and "Checked-In" are also valid.”

Three of those free a slot, not one. A practice with late cancellations switched on will produce "Late Cancellation" on exactly the appointments you most want to catch, the ones that fall through close to the hour, and a matcher looking only for "Cancelled" will skip every one of them. "Re-Scheduled" frees the original time too. And since the last two are conditional on a setting, a sandbox can show you a shorter vocabulary than the practice you are integrating with. Ask which are enabled.

The two fields don't reference each other. An appointment can sit at confirmed: true and pm_status: "Cancelled" simultaneously, and nothing in the API objects. If you're reading confirmation state, read both, or you'll act on a patient who confirmed a visit that no longer exists.

For openings, the relevant query is availableSlotsForRange. It takes provider_id, appt_type_id, start_date and end_date, and returns date, user_id and length.

Two things follow from that signature. First, it's scoped to one provider and one appointment type per call. There's no practice-wide “what's open this week.” A ten-provider practice offering four appointment types means forty calls to see one week. Second, it optionally accepts appointment_to_reschedule_id, which means Healthie models “slots available if I'm moving this particular appointment” as a first-class query. It understands reschedules natively. That's genuinely useful and not every EHR has it.

Then there's what isn't there.

Healthie's waitlist is not the waitlist you want

Healthie does have a waitlist. It is worth being precise about what it is, because the name promises more than it delivers for this particular job.

The feature belongs to group appointments. You enable it per appointment type, and it activates when a group session hits its capacity limit and clients can no longer book a spot. Healthie's own description of what happens next is straightforward: when a spot opens up and one client is waiting, that client is enrolled automatically; when several are waiting, the spot goes to whoever confirms first.

For a group program with a cap, that is genuinely useful and you should turn it on. For the problem this page is about, it does nothing. A cancelled 1:1 appointment is not a group session at capacity, and no amount of configuration makes the group waitlist notice it.

The API reflects that scope precisely. AppointmentType carries a boolean, is_waitlist_enabled, telling you whether waitlisting is switched on for that type. That is the entire surface. There is no waitlist object, no query that returns who is waiting, no mutation to add or remove someone, and no way to influence the order. You can read one flag and nothing behind it.

It is worth seeing how differently other systems treat this. The FHIR R4 Appointment.status valueset includes waitlist as a status, so an EHR built on FHIR can express “this patient is waiting for a slot” as appointment state, and Medplum does exactly that. Canvas Medical implements the same valueset and leaves waitlist out. Healthie, being GraphQL rather than FHIR, has a feature with the right name attached to a different problem.

So for individual cancellations, the queue is not something you read from Healthie. It is something you construct, and it lives outside the EHR.

The nearest raw material Healthie does give you is tags on the patient, applied through the bulkApply mutation, which takes a list of tag ids and a taggable_user_id. Tags are how you mark that someone wants to come in sooner.

What actually happens the moment a slot opens

Healthie supports webhooks, which is the reason this can work at all. When an appointment changes, Healthie POSTs to your endpoint, signed with HMAC-SHA256: the signature arrives in a signature header in sig1=<hash> form, and you verify it against a shared secret you configure per environment.

Webhooks matter more than they sound. The alternative is polling availableSlotsForRange on a schedule, and with a per-provider-per-type query that gets expensive fast. You'd poll on a cycle measured in hours, and a slot that opens Monday for Tuesday is already stale when you find it. With webhooks the gap between “patient cancels” and “your system knows” is seconds.

That gap is the whole product. Everything downstream is a race against the patient finding another clinic.

Building the queue Healthie doesn't have

Once you know a slot is free, you need an ordered list of who to call. Roughly what that takes:

  • Eligibility windows. A slot three hours out can't realistically be filled by phone, since the patient has to arrange transport and time off. One three weeks out isn't urgent enough for anyone to reshuffle their week. In practice the useful band is a few hours to about a week ahead, and you want a floor on how recently you contacted the same patient so nobody gets called twice in three days.
  • Ranking. Tags carry the intent, but tags alone give you an unordered set. Ranking means asking who is most overdue relative to how often they should be seen, and then the part that usually gets skipped: whether this specific slot actually gets them closer to that cadence than the appointment they already have booked. A patient with a visit on Thursday shouldn't be offered Wednesday. It's motion without benefit, and it burns the contact.
  • Rebooking. This is where it usually breaks. You can't create a Healthie appointment from just a date and a patient id. createAppointment needs the shape of the original: appointment_type_id, contact_type, appointment_location_id, location, room_id, external_videochat_url, insurance_billing_enabled, is_blocker, notes, other_party_id. Reschedules need more still, including user_id, attendees, max_attendees and providers.

Drop one of those and the booking succeeds while being quietly wrong. Miss external_videochat_url on a telehealth visit and the patient gets an appointment with no video link, which they'll discover at the appointment.

What you need on your side

Three things, and one of them is a conversation with Healthie rather than a setting.

  • API access. Per Healthie's pricing page, API access is an add-on to the Enterprise plan. Healthie doesn't publish the price, so it's negotiated on your account. Budget for it, because it isn't included by default.
  • An API key. Generated from Settings once API access is enabled.
  • A webhook and its signing secret. So slot changes arrive as events instead of being polled for.

With those in hand, connecting is same-day work. The lead time is getting the API add-on on your plan, not the integration.

Honest limits

Things worth knowing before you commit:

  • availableSlotsForRange is scoped per provider per appointment type. Availability lookups at a large practice mean a lot of calls, and rate limits are a real design constraint.
  • Because the API exposes no waitlist object beyond a single boolean, the queue for 1:1 cancellations lives in whatever system you build. It won't stay behind in your EHR if you stop using that system.
  • The whole thing runs on tag discipline. If your team doesn't tag patients who want to come in sooner, there is no queue to rank, and no amount of automation invents one.
  • Filling a slot is bounded by how many people can move their schedule on short notice. Automation removes the delay; it doesn't remove that.

Sources

  1. Healthie API Docs: Appointments (pm_status vocabulary, availableSlotsForRange, createAppointment)
  2. Healthie: 'How to use client waitlist management software' (group appointment waitlist behavior)
  3. Healthie pricing: API access as an Enterprise add-on

About the author

Federico Ruiz Cassarino is the CEO and founder of Puppeteer AI, the company behind Recupra. He works with clinic operators on the scheduling and outreach problems that decide how much of a practice's booked capacity turns into revenue. Connect on LinkedIn.

FAQ

Frequently asked questions

Does Healthie have a built-in waitlist?

Yes, but only for group appointments that have reached capacity, and it fills the next opening automatically. It does not apply to cancelled 1:1 appointments. The API exposes only is_waitlist_enabled on AppointmentType, with no query or mutation behind it, so for individual cancellations the ordered list has to be built outside the EHR.

How fast does Healthie tell you an appointment was cancelled?

Effectively immediately, if you use webhooks. Healthie POSTs to your endpoint on appointment changes, signed with HMAC-SHA256. Polling availableSlotsForRange instead means finding out on your polling cycle.

What is the difference between pm_status and confirmed in Healthie?

pm_status is the appointment's own state as a string, where "Cancelled" lives. confirmed is a separate boolean for whether the patient confirmed. They move independently, so read both.

Do I need the Enterprise plan to use the Healthie API?

For API access, yes. Healthie lists it as an Enterprise add-on and doesn't publish the price.

Fill the next cancellation before the day is out.

Connect Healthie and Recupra ranks who to offer the slot to, then calls and texts them until it's booked.