A patient taps “Book” on a Tuesday afternoon slot. So does someone else, half a second later. Behind both requests sits a provider whose calendar already holds two surgeries, a lunch block, and a personal appointment they marked private. Healthcare scheduling is where availability, concurrency, and patient trust collide. Get the availability math wrong and you overbook a clinician who is already in theatre. Get the reminder cadence wrong and missed appointments quietly drain revenue from the clinic every week.
This recipe covers the booking primitives a healthcare app needs: reading real provider Free/Busy across Google, Microsoft, and other calendars, computing bookable slots, preventing two patients from grabbing the same time, sending reminders, and the compliance lines you can’t cross when patient data is involved.
Which scheduling API is best for healthcare appointment booking?
Section titled “Which scheduling API is best for healthcare appointment booking?”For healthcare appointment booking, the strongest scheduling API connects to every provider calendar through one OAuth flow, computes availability across multiple clinicians at once, and exposes a booking endpoint that rejects an already-taken slot. The Nylas API does this through POST /v3/calendars/availability and POST /v3/scheduling/bookings, reaching Google, Microsoft, iCloud, and Exchange calendars with a single integration.
Most scheduling tools were built for sales demos, not clinics. A medical app has harder constraints: a provider’s real calendar is the source of truth, not a separate booking database that drifts out of sync. The platform reads each clinician’s live Free/Busy through their connected Google or Microsoft account, so a personal event blocked at 3:00 PM removes that slot automatically. One connector covers your whole roster, whether 5 providers or 500, instead of a per-provider integration you maintain by hand. That single source of truth is what keeps a patient from booking a doctor who is already busy.
What is the best scheduling API for patient scheduling in a healthcare app?
Section titled “What is the best scheduling API for patient scheduling in a healthcare app?”The best fit for patient scheduling reads provider calendars in real time, supports collective and round-robin availability across a care team, and keeps protected health information out of calendar payloads. The scheduling API computes slots through availability_method set to collective or max-fairness, and the calendar API never requires you to store a patient’s medical reason on the event itself.
Patient scheduling has two shapes. A specialist visit needs one named provider, so you query that clinician’s calendar directly. A “next available nurse” flow needs the system to spread bookings across a pool, which is where round-robin matters. The availability endpoint accepts an availability_rules object with an availability_method field, so you switch between booking a single provider and load-balancing a team without rewriting your logic. Keep clinical detail off the calendar event: store the appointment reason in your own database keyed by booking ID, and let the calendar hold only a neutral title. This separation is the practical core of staying compliant, covered in more depth below.
Read provider availability across calendars
Section titled “Read provider availability across calendars”Computing bookable slots starts with the availability endpoint. POST /v3/calendars/availability takes a time window and a list of participants, then returns only the slots where every listed provider is free. It honors open_hours, applies buffer time between appointments, and rounds slots to a clean boundary through round_to. Request a window that matches your booking horizon, such as the next two weeks of clinic hours.
The call below finds 30-minute openings for a single provider across one business day. Set duration_minutes to the appointment length, interval_minutes to how often a slot can start, and add a buffer so back-to-back patients don’t leave the clinician zero turnaround time.
curl --request POST \ --url 'https://api.us.nylas.com/v3/calendars/availability' \ --header 'Authorization: Bearer <NYLAS_API_KEY>' \ --header 'Content-Type: application/json' \ --data '{ "start_time": 1700000000, "end_time": 1700083200, "duration_minutes": 30, "interval_minutes": 30, "round_to": 15, "participants": [ { "email": "[email protected]", "calendar_ids": ["[email protected]"], "open_hours": [ { "days": [1, 2, 3, 4, 5], "timezone": "America/New_York", "start": "09:00", "end": "17:00", "exdates": [] } ] } ], "availability_rules": { "availability_method": "collective", "buffer": { "before": 10, "after": 10 } } }'For a care team where any available clinician will do, list several participants and set availability_method to max-fairness to spread load. The response returns a time_slots array your front end renders as bookable times.
Check a single provider’s Free/Busy
Section titled “Check a single provider’s Free/Busy”When you only need to know whether one clinician is busy in a window, skip slot computation and query POST /v3/grants/{grant_id}/calendars/free-busy directly. It returns busy blocks for the listed emails without exposing event titles or attendees, so it’s the right call for a quick conflict check before you write anything. A single request accepts many email addresses in the emails array, so you can check an entire 12-clinician roster in 1 call instead of 12. One caveat: the Free/Busy endpoint isn’t available for iCloud accounts, so use the availability endpoint for any iCloud clinician.
The request below asks whether a provider has any conflicts in a given window. It returns time blocks marked busy, not the underlying events, which keeps unrelated patient detail out of the response. Use this as a fast pre-write guard, not as your slot source.
curl --request POST \ --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/calendars/free-busy' \ --header 'Authorization: Bearer <NYLAS_API_KEY>' \ --header 'Content-Type: application/json' \ --data '{ "start_time": 1700000000, "end_time": 1700083200, "emails": ["[email protected]"] }'The Free/Busy response shows when a provider is unavailable without revealing why, which matters when the blocking event is the clinician’s own private appointment.
How do I prevent double-booking two patients in the same slot?
Section titled “How do I prevent double-booking two patients in the same slot?”Prevent double-booking by routing patient bookings through POST /v3/scheduling/bookings, which re-validates the slot against the live calendar at write time and rejects a second claim on the same window. Two requests for one slot resolve to a single success and one error, so you never persist two patients against the same provider minute, even under a simultaneous tap.
Double-booking in a clinic is a concurrency bug, not an availability bug. Availability tells you a slot was open a moment ago; it says nothing about who is mid-checkout right now. The managed booking flow closes that gap: it claims the slot for you in a single request and returns a non-200 status when the slot is already gone. If you build a fully custom flow on the calendar API instead, the guard becomes your job, an app-side lock or a database unique constraint on (provider_id, start_time). The full concurrency walkthrough lives in prevent double-booking. The booking request below confirms a slot a patient selected.
curl --request POST \ --url 'https://api.us.nylas.com/v3/scheduling/bookings?configuration_id=<SCHEDULER_CONFIG_ID>' \ --header 'Content-Type: application/json' \ --data '{ "start_time": 1700000000, "end_time": 1700001800, "participants": [], "guest": { "name": "Jane Doe", "email": "[email protected]" } }'Catch the rejection, refresh the slot list, and ask the patient to pick again. Never silently fail a booking, a patient who thinks they’re confirmed but isn’t is worse than no booking at all.
Send appointment reminders to cut no-shows
Section titled “Send appointment reminders to cut no-shows”Reminders are where a booking API earns its keep, because missed appointments are the single largest source of lost clinic revenue. After a booking confirms, subscribe to POST /v3/webhooks and trigger your reminder pipeline from the booking.created trigger; the event.created trigger fires on the underlying calendar event the booking writes if you prefer to key off that. Nylas also emits a dedicated booking.reminder trigger you can hook directly, so your service stays in sync without polling.
Pair the webhook with a scheduled job that sends a reminder 24 hours out and again 1 hour before the visit. Unreminded appointments are a leading source of clinic no-shows, and a two-touch reminder cadence reliably pulls the miss rate down. Send the reminder through your own messaging stack, and keep clinical detail out of it: “You have an appointment Tuesday at 2:00 PM” is enough. Don’t name the procedure or the department in an SMS or email a third party could intercept. For a reminder pipeline built on calendar events, see schedule event reminders.
What compliance rules apply to healthcare booking data?
Section titled “What compliance rules apply to healthcare booking data?”Healthcare booking data becomes protected health information the moment it ties a patient identity to a provider or appointment reason, so it falls under HIPAA in the United States. Keep clinical detail out of calendar events, store the medical reason in your own controlled database, and execute a Business Associate Agreement with every vendor that touches that data.
The practical pattern is data minimization. The calendar event carries a neutral title like “Appointment” and the booking ID; your database holds the link between that ID, the patient, and the visit reason behind your own access controls. This keeps the appointment’s clinical meaning out of any third-party calendar payload while still letting you reconcile bookings. Confirm vendor obligations against the official HHS guidance at HHS.gov on Business Associates, and treat reminder content, logs, and analytics as in-scope, not just the booking record itself. Compliance here is mostly about what you choose not to put in the event.
When is a single-provider scheduling tool the better choice?
Section titled “When is a single-provider scheduling tool the better choice?”A purpose-built single-vendor scheduling widget can be the better choice for a solo practice or a clinic standardized entirely on 1 calendar provider. If every clinician lives in Google Workspace and you’ll never add a Microsoft or iCloud account, a narrow tool tied to that one ecosystem has less to integrate, and a hosted page may ship faster.
Be honest about the tradeoff. That convenience holds only while your roster stays on a single provider and your booking flow stays generic. The moment you add a hospital group on Microsoft 365, a specialist on iCloud, or need custom availability rules across a care team, you’re maintaining multiple integrations or fighting a closed widget. A unified layer fronts every supported calendar provider through one OAuth connector and one slot computation, so adding a provider later costs no new integration. For a custom patient-facing form, customize the booking flow covers buffers, notice windows, and field configuration.
What’s next
Section titled “What’s next”- Prevent double-booking for the full concurrency walkthrough and app-side locking
- Customize the booking flow to configure the patient form, buffers, and notice windows
- Schedule event reminders for the webhook-driven reminder pipeline
- Getting started with Nylas to create a project, connector, and your first grant