Resources
Filling Cancelled Appointments in Avon Health
By Federico Ruiz Cassarino, CEO and founder, Puppeteer AI · · 6 min read
Avon Health's API reads like a modern developer product rather than a healthcare system, and that isn't only cosmetic. Two of its design choices change what you can build on top of it when a slot opens up.
This is a field-level walkthrough of both, and what they mean for filling a cancelled slot.
Availability, and the words it uses
Open time comes from a slot list:
GET /v2/slots?appointment_type={id}&provider={id}&search_from={timestamp}&search_until={timestamp}
Every parameter is optional, which is more permissive than most scheduling APIs. You can ask for availability without first resolving a schedule or a location, and narrow only as much as you need.
The date bounds are search_from and search_until rather than the start / end most systems in this series use. Trivial once you know it, and a reliable source of an empty result set until you do, because omitting them isn't an error. It just changes what you're asking for.
Everything comes back in an envelope
Responses aren't bare arrays. A list looks like this:
{ "object": "list", "data": [ ... ] }
The object key names the shape and data holds the payload. Familiar if you've worked with a payments API that does the same thing; less ceremony than a FHIR bundle, and no per-entry resource nesting.
Worth handling defensively too. A response where object isn't "list" isn't a list, and treating it as one produces confusing failures downstream rather than a clean error at the boundary.
Appointment types are objects you can create
This is the first of two genuinely unusual things here.
On most EHRs, appointment types are configuration. Someone sets them up in an admin screen, you look up their ids, and your integration references them. Avon exposes them as a full CRUD resource: you can list them, read one, and create new ones through the API:
POST /v2/appointment_types
with name, and optionally description, duration, group, max_participants and a settings object.
The reason this matters for cancellations: when a slot opens, the visit type that was cancelled isn't always the visit type best suited to filling it. A cancelled 60-minute intake leaves an hour that might be better used as two 30-minute follow-ups. On most systems that's a conversation with whoever administers the EHR. Here it's an API call.
That's a capability worth using carefully rather than enthusiastically. Appointment types created programmatically are still real configuration that staff will see and have to make sense of, and an integration that quietly generates types will produce a settings screen nobody can read within a few months. Create deliberately, name them for humans, and prefer reusing an existing type over minting a new one.
Group visits are first-class
The second unusual thing is on that same resource: group and max_participants.
An appointment type can be marked as a group type with a participant ceiling. The EHR understands that a single slot holds several patients, rather than you simulating it with overlapping bookings.
For cancellation work this opens a path that doesn't exist elsewhere in this series. When someone drops out of a group session, the slot isn't empty. It's under-filled. The distinction changes the outreach entirely: the session runs regardless, so there's no urgency to protect revenue, but there's still a seat and someone who'd benefit from it. Different message, different timeline, and a much lower cost of not filling it.
It also means your availability logic can't assume one slot equals one patient. A group slot with capacity remaining is available; the same slot at capacity is not; and both are the same object with a different count against it.
Practices running shared medical appointments, group therapy, or class-based programs get this modeled properly rather than approximated. Practices that don't run groups can ignore it entirely, but availability code that assumes single-patient slots will need revisiting the day one starts.
Appointments read the same way slots do
Reading existing bookings uses the same list shape as everything else:
GET /v2/appointments
with filters narrowing the set, and the response arriving in the same { "object": "list", "data": [...] } envelope.
The consistency is worth pointing out because it is not the norm. On FHIR systems, slots come back as a bundle of Slot resources and appointments as a bundle of Appointment resources, each with its own nesting and its own search-parameter conventions to learn. Here the two are shaped alike, and a client that handles one handles the other.
That shortens the path from being able to list availability to having a working cancellation workflow. Most of the integration cost on scheduling APIs isn't the logic. It's the accumulated small differences between adjacent endpoints, each one a place to get something subtly wrong. Fewer differences means fewer of those places.
It also makes the local mirror easier. Any workflow that reacts quickly to cancellations ends up keeping its own copy of upcoming appointments rather than querying the EHR on every decision, and a uniform response shape makes that copy considerably less code to maintain.
What a cancellation workflow looks like
String the pieces above together and a cancellation workflow looks like this:
- Notice the cancellation. However that reaches you today, a webhook or a poll.
- Re-query availability. Search
/v2/slotsagain for the affected provider and appointment type, bounded withsearch_fromandsearch_until. - Check what actually freed up. A whole slot, or a seat in a group session. The two warrant different outreach.
- Rank the patients who could take it. Avon knows what's free. It doesn't know who's waiting for it, so that list is built and held outside the EHR, same as everywhere else in this series.
- Book. Against the slot, or into the open seat on the group appointment type.
The check step is the one specific to Avon, and it's the one that gets skipped when the integration is ported from a system without group support. A message telling someone their appointment slot is available reads as wrong when what actually opened up is one seat in a group session.
What you need on your side
- API credentials for your Avon Health organization. Scoped per organization, the same as everywhere else in this series.
- Appointment type ids, or a plan to create them. Decide upfront whether you mint types programmatically, and if so, agree on a naming convention before the first one exists.
- A way to tell group types from single-patient types. Availability means something different for each.
- The ranked patient list. It lives outside the EHR here, as it does on every system in this series.
Honest limits
- No waitlist concept. Avon's scheduling surface covers slots, appointments and appointment types. Patients wanting an earlier visit aren't represented, so that list is yours to hold and keep clean.
- Slot availability reflects configuration. If provider availability or appointment type duration isn't set up correctly, the slots you get back won't match what staff see.
- Group capacity needs its own handling. Remaining seats is a different question from slot availability, and code that conflates them will offer seats in sessions that are already full.
- Programmatic appointment types are easy to abuse. The capability is genuinely useful, and the failure mode, a settings screen nobody owns anymore, is slow and hard to reverse.
Sources
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.