eClinicalWorks
Access
Section titled “Access”- No self-service portal: API access is arranged through eClinicalWorks support.
- SMART Backend Services with a JWT. Each practice has an endpoint code in the FHIR base URL; the token server is shared. A staging host exists for testing.
- Bulk and REST are separate registrations with separate client ids, sharing your JWKS. A bulk client id gets 401 on every REST endpoint even with the right scopes, and a REST registration has no group id.
- Request every scope you need; the server grants the intersection with what was provisioned.
- The practice list is available from eClinicalWorks’ public developer organisation bundle.
Bulk export
Section titled “Bulk export”Group/<groupId>/$export?_type=<one type>&_since=<date>
- One resource type per job, run sequentially. A typical order: Practitioner, Patient, Encounter, Condition, Observation, DocumentReference, MedicationRequest, DiagnosticReport, Procedure, QuestionnaireResponse.
- Send only
Accept,Prefer: respond-asyncandAuthorizationon kickoff. AContent-Typeheader gets the kickoff rejected. - Always export Practitioner in full. With
_since, older but still-active providers are dropped — in one case about 1 in 5 attending NPIs went blank. - Poll the
X-Progressheader;FAILEDis terminal. Polling more often than every few minutes gains nothing. - A “duplicate” or “already in progress” response means a job is already running for that group.
- A 401/403, or an OperationOutcome mentioning scope, means that one type is not granted — skip it rather than failing the whole run.
- Re-mint the token periodically during long downloads (every 25 files works).
- An OperationOutcome with severity
informationand no data means “nothing to export” — success. - Many empty NDJSON files in one export usually means the export is broken; restart that type.
Recovering stuck jobs
Section titled “Recovering stuck jobs”| Symptom | Action |
|---|---|
| Unexpected response from the server | Reset; if it persists for two days, delete the job and start again |
| Status cannot be read and the job keeps auto-resetting | Wait, or delete the job — it can loop indefinitely |
| ZIP archive creation error | Delete and restart that type |
| “Ready for download” for more than 24 hours | Reset that type |
X-Progress: FAILED |
Delete and restart that type |
Cap automatic recovery — without a cap, jobs have been seen looping for months. Format errors so they can be pasted straight into an eClinicalWorks support ticket.
REST (per-patient) access
Section titled “REST (per-patient) access”Many reasonable-looking queries are rejected with 400:
| Query | Result |
|---|---|
Any search with _count |
400 — page only with link.next (a literal page=1 is also 400) |
Observation?patient=&date= |
400 |
Observation?patient= with no code or category |
400 |
Observation?patient=&category=vital-signs |
200 with 0 entries — search code=85354-9 and read the components |
Procedure?patient=&code= |
400 |
DocumentReference?patient=&date= |
400 |
Patient?birthdate= alone |
400 — family+given+birthdate+gender gives a clean single match |
Do not add vendor parameters (such as the endpoint code) to REST query strings; they break REST calls.
Known behaviour
Section titled “Known behaviour”A duplicate A1c on the glucose scale
Section titled “A duplicate A1c on the glucose scale”For each A1c order, eClinicalWorks can emit two observations: a LOINC-coded A1c, and an
uncoded duplicate (labelled like HbA1cWB) whose value is on the glucose scale in mg/dL, often with
the same timestamp. Picking the wrong one turns a 7.1% A1c into “142”.
Handle it by ranking results by day first, preferring the coded result within a day, and rejecting uncoded values above 30 as implausible for a percentage.
Data that is “granted” but empty
Section titled “Data that is “granted” but empty”Scopes being granted does not mean data is populated. In one practice, PHQ scores existed only in
HTML attachments on DocumentReference, and mammograms never appeared as DiagnosticReport.
When PHQ scores are in embedded document tables, they are laid out as columns rather than rows.
Identifiers and names
Section titled “Identifiers and names”Encounter.typeis a data-absent reason, so encounter-type value sets cannot qualify visits.identifier[0]is often the FHIR id restated; the MRN is usuallyidentifier[1].- The middle initial is the second element of
name.given.