Epic Appointment Booking, Cancellation, and Rescheduling — A Developer’s Guide
Technology Blogs

Epic Appointment Booking, Cancellation, and Rescheduling — A Developer’s Guide

Akash Varma
Software Engineer

A Bit of Context First

Scheduling an appointment doesn’t sound like a hard problem. The patient picks a time, and the doctor shows up. But once you start building with Epic, you realize pretty quickly that there’s a lot going on behind the scenes.

It’s one of the biggest EHR systems, and it’s quite particular about how things need to be done. You have to follow a certain sequence and stick to the expected formats, and even small mistakes can cause failures without clear errors.

Most of the time, you only figure this out after spending hours debugging something minor—like an extra space in an ID.

This post walks through all three flows—booking, cancelling, and rescheduling—and tries to explain not just what to call them but why things are set up the way they are. If you’re new to Epic integrations or just picking this up mid-project, hopefully it saves you some real time.

A Few Things to Understand Upfront

  1. FHIR Standards: FHIR is the standard way healthcare systems exchange data with each other. Epic supports FHIR R4 for certain APIs, enabling data exchange with other health systems. However, many Epic scheduling endpoints remain proprietary and older, requiring developers to mix both FHIR and non-FHIR calls within single workflows.
  2. Appointment Definition: A FHIR appointment is a structured record containing patient, provider, time, location, and status information (booked, cancelled, arrived). This data structure serves queries about appointment history and rescheduling details.
  3. Slot Concept: A slot represents a time block a provider designated as available. Epic enforces using pre-designated slots rather than arbitrary times. Attempting to book outside existing slots results in rejection.
  4. Authentication Methods: Epic scheduling APIs accept either username/password or OAuth tokens. Implementation teams should use whichever method their integration already supports.
  5. ID Types: Short codes indicate identifier origins, EMRN for Epic Medical Record Numbers, EXTERNAL for outside systems, EPI for enterprise indices. These vary between Epic environments, requiring confirmation with your Epic team before development begins.

Flow 1: Booking an Appointment

Step 1: Find or Create the Patient

Patient lookup begins every workflow. PatientLookup4 or PatientLookup (2012) enable searching by name, patient ID, date of birth, or the last four SSN digits, requiring only one identifier.

When patients don’t exist, PatientCreate (2019) creates records with required fields: full name, address, date of birth (YYYY-MM-DD format), gender, and registration department.

A critical limitation: PatientCreate (2019) cannot be tested through vendor service accounts. During sandbox testing, switch to “Patient.Create (Demographics) (R4),” which functions in those environments.

Step 2: Match the Reason for Visit

Determine the appropriate visit type, department, and provider based on the patient’s presenting complaint. Patients express concerns conversationally (“My knee’s been bothering me for a week”) rather than in Epic terminology.

Basic keyword matching between patient input and available visit type names handles most scenarios. Default to the most general visit type when nothing matches rather than rejecting the patient.

Step 3: Find Available Days

API: GetScheduleDaysForProvider2

Send the provider, date range, department, and visit type to Epic. The response returns days with actual openings. Present these options to the patient for selection.

Step 4: Book the Appointment

API: ScheduleAppointmentWithInsurance (2019)

Provide the patient ID, provider, department, visit type, selected date, and time to complete the booking.

A critical gotcha: Epic sometimes returns HTTP 200 OK but includes an error inside the response body. Example:

{
  "ErrorCode": "SLOT_TAKEN",
  "Errors": ["The selected slot is no longer available"]
}

Always read response bodies for ErrorCode or Errors arrays after booking calls. Successful HTTP status codes don’t guarantee successful bookings.

Talk to our Epic integration team

Flow 2: Cancelling an Appointment

Step 1: Find the Patient

Use PatientLookup4 or PatientLookup (2012), identical to the booking process.

Step 2: Pull Their Appointments

API: GetFutureAppointments (2014)

This endpoint returns upcoming appointments. Extract two values:

  • ContactID: The identifier for cancelling specific appointments
  • CancelDirectAllowed: Determines whether direct patient cancellation is permitted

Step 3: Check CancelDirectAllowed Before Anything Else

This step is the most commonly missed by developers. Each Epic appointment includes CancelDirectAllowed indicating permission for direct cancellation:

  • CancelDirectAllowed = true: Proceed with cancellation
  • CancelDirectAllowed = false: Halt the process. Inform the patient this requires clinic contact

Attempting cancellation when this flag is false causes failures or unexpected Epic behavior.

Step 4: Cancel the Appointment

API: CancelAppointment (2019)

Provide patient ID, Contact ID, Contact ID Type, and cancellation reason. Epic rejects blank reasons. If your interface doesn’t collect reasons, default to something like “Patient requested cancellation.” Trim spaces from IDs before sending, as legacy data sometimes carries formatting that causes silent failures.

Flow 3: Rescheduling an Appointment

Rescheduling involves more API calls and value propagation, requiring careful tracking of earlier responses.

Step 1: Find the Patient

Use PatientLookup4 or PatientLookup (2012).

Step 2: Get Their Appointments

API: GetFutureAppointments (2014)

Extract two specific values:

  1. CancelDirectAllowed: For validation in the next step
  2. DAT parameter: Epic’s internal numeric timestamp for the appointment. Save this value for the final rescheduling step.

Step 3: Check CancelDirectAllowed

If false, inform the patient that online rescheduling is unavailable and provide clinic contact details.

Step 4: Get the Visit Type from FHIR

API: Appointment.Search (Appointments) (R4)

Look up the appointment and retrieve the serviceType.code field. This visit type identifier differs from earlier ones and is specifically required by subsequent APIs.

Step 5: Find Open Slots for the New Time

API: GetOpenSlots (2019)

Use the provider, department, and serviceType.code retrieved above. Epic returns available slots with date, time, and duration information.

A critical requirement: when Epic returns the slot data, save the whole object exactly as-is. Don’t change anything or extract only parts of it. The full slot object must be sent unchanged in the next step, or Epic will reject the request.

Step 6: Complete the Reschedule

API: ScheduleAppointment (2019)

No separate reschedule endpoint exists. Call ScheduleAppointment (used for new bookings) with one additional field: OriginalAppointmentDAT, the DAT value from Step 2.

That single field is what tells Epic this is a reschedule, not a new booking. Epic cancels the old appointment and creates the new one atomically.

The slot structure is deeply nested: Slot → AppointmentInfo → Appointments → Pools → Options. This complexity accommodates pooled availability, split appointments, and multiple providers. While seemingly unnecessary for straightforward cases, the full structure is required. GetOpenSlots provides it ready-made, pass it through unchanged.

Authentication Quick Reference

All Epic scheduling APIs support both authentication methods: username/password and OAuth token. This applies to every API covered in this guide:

APISupported Auth
PatientLookup4Username and Password, OAuth Token
PatientLookup (2012)Username and Password, OAuth Token
PatientCreate (2019)Username and Password, OAuth Token
Patient.Create Demographics (R4)Username and Password, OAuth Token
GetScheduleDaysForProvider2Username and Password, OAuth Token
ScheduleAppointmentWithInsurance (2019)Username and Password, OAuth Token
GetFutureAppointments (2014)Username and Password, OAuth Token
CancelAppointment (2019)Username and Password, OAuth Token
Appointment.Search (R4)Username and Password, OAuth Token
GetOpenSlots (2019)Username and Password, OAuth Token
ScheduleAppointment (2019)Username and Password, OAuth Token

Common Mistakes Worth Knowing About

  • Using GetOpenSlots for initial booking: This API belongs exclusively to rescheduling. Initial bookings use GetScheduleDaysForProvider2.
  • Skipping CancelDirectAllowed: Check before both cancellation and rescheduling, without exception.
  • Trusting HTTP 200 as success: Epic returns business errors within 200 responses. Always examine response bodies.
  • Testing PatientCreate in vendor service accounts: It won’t function. Use Patient.Create (Demographics) R4 instead.
  • Modifying the slot object from GetOpenSlots: Any changes cause rejection. Pass it back exactly as received.
  • Treating DAT as regular dates: DAT is a numeric internal Epic timestamp. Fetch, store, and return it as-is. Avoid parsing or reconstruction.
  • Blank cancellation reasons: Epic rejects these. Maintain sensible defaults.
  • Timezone mismatches: Epic interprets time strings using its own configured timezone. If users occupy different zones, convert before API calls. This oversight during development becomes a production issue.

Conclusion

Effective Epic appointment scheduling depends on correct API call sequencing for each workflow. Booking, cancellation, and rescheduling all begin with patient lookup but diverge significantly in subsequent steps.

Booking requires response body validation rather than relying solely on HTTP status codes. Cancellation mandates checking CancelDirectAllowed before attempting the cancel request, as Epic may prohibit direct cancellation for certain appointments.

Rescheduling combines FHIR and non-FHIR APIs in the most complex workflow. Developers must preserve the DAT value, utilize serviceType.code, and transmit the slot object unchanged. Mastering these details enables smoother, more reliable appointment experiences for patients and care teams.

Akash Varma

Akash Varma

Software Engineer

Akash is a full-stack developer with over 3.5 years of experience working with the MERN and MEAN stacks. He is passionate about building scalable applications, improving performance, and creating smooth user experiences. His interests include problem-solving, learning new technologies, and developing solutions that make real impact.

Share This Blog

Read More Similar Blogs

Let’s #Transform Healthcare,# Together.

Partner with us to design, build, and scale digital solutions that drive better outcomes.

BOOK A QUICK CONSULTATION

Have a Healthcare Project in Mind?

Let’s discuss your goals, workflows, and next steps in a focused consultation call.

Calendar Schedule a Call

Contact form