Skip to content
DWKD

Tool note

What an Epic Integration Actually Requires

The code is the small part: access, environments, approvals and elapsed calendar time are what set the date you can promise.

Ask what an Epic integration requires and you will get an answer about FHIR resources, OAuth and a JSON parser. That answer is correct, and it is about a fifth of the work.

The rest is access, environments, approvals and elapsed calendar time. None of it appears on an engineering estimate. All of it sits on the critical path.

Why this exists

The failure mode is a six-week quote whose first five weeks contain no code. You are waiting on a registration, on credentials for an environment you do not control, on a security review that meets every two weeks, on a clinical sponsor nobody has asked yet, and on a change window somebody else owns.

Writing and testing a read of a problem list is days of effort. Getting a production client identifier pointed at a live organization takes as long as that organization’s governance takes, and no amount of working the weekend compresses it. Effort and elapsed time are different quantities, and only one of them sets the date you can promise.

Here is the claim a generic checklist will not make: the artifact that unblocks the most schedule is the shortest one — the name of a person inside the health system who owns the request. Without that name you can build the entire integration and still have nothing to turn on. Get the name before you get the specification.

How to use it

Fill the ledger before you quote, not after. Every row names an owner outside your keyboard and carries two dates: when you asked, and when it landed.

  • Separate developer access from this organization’s access. Self-service registration and a sandbox prove your code works. They prove nothing about whether a live site will talk to you, and that conversation starts later than you think.
  • Register per environment and assume every identifier differs between them. Assume they can also change underneath you: a sandbox notice dated August 31, 2026 reverted the sandbox organization identifier to 0 from 529 and asked integrators who had switched to revert their identifiers. Base URLs, client identifiers and organization identifiers are configuration, never constants in code.
  • Ask for the non-production environment by name. Then ask who controls it, when it was last refreshed, and whether it is available during your build window. Environments get taken for upgrades and freezes without reference to your plan.
  • Keep effort hours and elapsed days in two separate columns, and quote from the second one. If the two columns look similar, you have not finished filling in the ledger.

Where it goes wrong

This is not an argument that the integration is hard or unwise. It is an argument for an honest date. Used as an objection, it only makes you sound reluctant.

It also cannot replace the site’s own integration analyst. The ledger tells you which questions to ask; only they know their queue depth, their freeze calendar, and which of their environments is usable this month. Ask for their intake form and map this into it rather than sending yours instead of theirs.

Skip it for a demo. If the job is one read of one resource against test data, the ledger is overhead — register, build, move on.

And it goes stale. An approval granted in spring for a read-only feed is not approval for the write you added in summer. A scope change resets queues you thought you had already cleared.

Finally, the ledger is silent on semantics. It gets you connected; it does not tell you what their active problem list means, who curates it, or whether two departments use it differently. That is a different worksheet, and it holds the second half of the surprises.

Copy and Clear become available when the worksheet is ready.

EPIC INTEGRATION READINESS LEDGER

Project: Site / organization:

Prepared by: Date:

Internal owner at the site: name, title, email, phone

HOW TO USE

Two date columns per row: "asked" and "in hand". Effort is in hours, elapsed is

in calendar days. Quote from the elapsed column.

A row with no owner outside your own keyboard is a row you have not started.

  1. ACCESS
  1. ENVIRONMENTS
  • Non-production environment named:
  • Who controls that environment:
  • Availability during the build window: upgrades/freezes: <>
  • Preconditions for production credentials:
  1. APPROVALS (each one is a queue, not a task)
  1. FIELD LIST (delete anything you cannot justify out loud)

resource or message | operation | fields | why it is needed | drop if refused?

<> | <> | <> | <> | <>

<> | <> | <> | <> | <>

  1. ELAPSED TIME LEDGER

item | effort hrs | elapsed days | blocked on

developer registration | | |

security review | | |

privacy / legal review | | |

non-production environment access | | |

build and unit test | | |

integrated test with their validator | | |

production registration | | |

go-live window | | |

TOTAL EFFORT: <> TOTAL ELAPSED: <> Quote the second number.

  1. THE THREE QUESTIONS FOR THE FIRST MEETING
  2. Who inside your organization owns this request after I hand it over?
  3. Which non-production environment will I test in, and is it free on ?
  4. What has to be true before production credentials are issued?
  1. STOP CONDITIONS
  • No named internal owner -> do not quote a date.
  • No usable non-production environment -> do not quote a date.
  • Scope includes a write and nobody has confirmed that operation exists at a

version you can use -> price the investigation, not the build.

  • Approval older than the current scope -> re-ask before you build on it.