Resources

Using Healthie Patient Tags to Drive Recall

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

Every practice running recall on Healthie ends up using tags for it, because tags are the only thing in the product shaped anything like a list. It works, up to a point, and the point where it stops working is predictable.

Here is what tags actually are in the API, and what they can't do.

Tags live on the patient, not the appointment

A Healthie tag is applied to a user. The mutation is bulkApply, and it takes exactly two things: a list of tag ids in ids, and taggable_user_id. The reverse is removeAppliedTag, taking a single tag id and the same taggable_user_id.

Two ids and a user. That is the whole surface.

Notice what isn't in it. No date. No note. No expiry. No ordering. The tag is a flag on a person, and the API gives you no way to say when it was applied, why, or how it ranks against the same tag on somebody else.

That constraint is where everything else follows from. A tag set answers who belongs to a group; recall needs to know who to call first.

What that means when you actually run recall

Say you tag two hundred patients as due for a follow-up. Now a slot opens on Thursday. Which of the two hundred do you call?

The API can tell you all two hundred carry the tag. It cannot tell you:

  • Who has been waiting longest, because there is no applied-at date.
  • Who was already contacted about a different slot last week.
  • Who is already booked for Friday and has no use for Thursday.
  • Which of them the slot is even clinically appropriate for.

All four are ordering questions, and none of them are answerable from tag data. So a tag-driven recall list is really a filter: it narrows two thousand patients to two hundred. Turning two hundred into a ranked call list is work that happens outside Healthie.

Building the ordering layer

The useful ranking signals are all derived rather than stored, and in practice they come from appointment history rather than from tags.

  • Time since last visit. Read the patient's appointment history and take the most recent completed visit. How overdue they are against the expected cadence is the strongest ordering signal there is, and it is the one tags most obviously lack.
  • Whether they are already booked. Someone holding a Friday visit should not be offered Thursday. It looks like service and it isn't: you have moved them by a day, spent a contact, and freed nothing. Ranking has to weigh the open slot against the appointment the patient already holds, not only against their last one.
  • Contact recency. Nothing in Healthie records that you called someone. If you don't keep that yourself, the same handful of responsive patients get contacted every time a slot opens, and the rest of the list is never touched.

Each of those means reading appointments per patient, which is a separate API call per person. At two hundred tagged patients that is two hundred lookups to rank a single slot. Caching appointment history locally, refreshed by webhook, is what makes this practical rather than theoretical.

“Bulk” doesn't mean what you'd expect

The mutation is called bulkApply, and the natural reading is that it tags many patients at once. It doesn't. Look at the shape again: ids is a list, taggable_user_id is singular. The bulk is in the tags, not in the people.

So applying one tag to two hundred patients is two hundred mutations. Applying five tags to one patient is a single call.

This lands the first time someone tries to tag a cohort: a segment export, a campaign list, everyone who missed a visit last quarter. The operation you want is a loop, it is rate-limited like any other loop, and a partial failure halfway through leaves the cohort half-tagged with no transaction to roll back.

Build it as a resumable job with per-patient results rather than a single fire-and-forget pass. When it fails at patient 140 of 200, and eventually it will, you want to know which 140, not to start over and double-apply.

Tag hygiene is the whole system

Tags don't expire. Nothing removes them when a patient books. If your workflow adds a tag when someone becomes due and never calls removeAppliedTag once they are seen, the tag stops meaning “due” within a couple of months and starts meaning “was due at some point”.

That decay is quiet. The list keeps returning results, the results are just increasingly wrong, and nobody notices until a patient is called about a follow-up they already had in March.

Two things prevent it. Remove the tag inside the booking flow, not as a separate cleanup task, because a separate task will not happen. And treat a tag older than some threshold as suspect rather than authoritative, checking it against appointment history before acting on it.

The uncomfortable version: automation built on tags is only as good as the tagging discipline underneath it, and no amount of ranking logic repairs a list that is wrong at the source.

What you need on your side

  • API access. An Enterprise add-on, per Healthie's pricing page, at a price that isn't published.
  • The tag ids you intend to use. Tags are referenced by id, never by name, so the mapping between “due for follow-up” and its numeric id has to be configured somewhere and kept in sync.
  • A store for everything tags can't hold. Applied-at dates, contact history, and the ranking that comes out of them.
  • Webhooks. So appointment changes update your ranking inputs instead of forcing a full re-read.

Honest limits

  • There is no applied-at timestamp. If you need to know how long someone has been waiting, record it when your integration applies the tag, and accept that you have no history for tags applied before that.
  • Tags are practice-wide and flat. No hierarchy, no grouping, no per-provider scoping, so a large practice accumulates near-duplicate tags that mean the same thing to different teams.
  • Renaming a tag in the UI doesn't change its id, which is good. Deleting and recreating one does, and an integration keyed on ids then stops matching without raising anything.
  • Tags say nothing about clinical appropriateness. A ranked list still needs a human decision before anyone is offered a specific slot with a specific provider.

Sources

  1. Healthie API Docs (bulkApply, removeAppliedTag, appointment queries)
  2. Healthie API Explorer: tag mutation shapes
  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

Can I see when a tag was applied to a patient?

No. bulkApply takes only tag ids and a patient id, and there is no applied-at field to read back. Record it yourself at the moment you apply the tag.

Can a tag be applied to an appointment instead of a patient?

No. The mutation's parameter is taggable_user_id, so tags attach to people. An appointment-level marker has to live in your own system or in the appointment's notes field.

How do I remove a tag once a patient is seen?

With removeAppliedTag, passing the tag id and taggable_user_id. Do it as part of the booking flow rather than as periodic cleanup, or the list degrades.

Is a tag list enough to run recall on its own?

It is enough to narrow the population. It is not enough to order it, and ordering is what decides whether recall recovers revenue or just burns contacts.

Turn the tag list into a call list.

Connect Healthie and Recupra ranks who is actually overdue, then calls them when a slot opens.