Mirth Connect eClinicalWorks Integration: HL7 Interfaces, SIU Scheduling, Labs and Billing (2026)
Digital Growth Lead
Writes about healthcare technology, interoperability, and AI-driven transformation across modern care systems.

Quick answer: A Mirth Connect eClinicalWorks integration runs the practice's HL7 v2 interfaces: SIU scheduling messages (S12 new, S13 rescheduled, S15 cancelled), ADT patient events, lab orders out as ORM or OML, results back as ORU, and charges as DFT. The SIU feed matters more than most teams expect, because the eClinicalWorks FHIR API has no Appointment resource, so HL7 is the only standard way to keep a complete, live copy of a provider's schedule.
Updated October 2026. eClinicalWorks is one of the largest ambulatory EHRs in the United States, so clinics, labs, billing services and digital health products all end up exchanging data with it. In practice that exchange is rarely pure FHIR or pure HL7. Ambulatory practices run a hybrid: FHIR APIs for apps and patient access, and HL7 v2 interfaces for scheduling, lab and billing traffic. This guide covers the HL7 side and how we run it in Mirth Connect, with message samples, the segments that matter, how a practice orders an interface, and how to keep it working after eCW upgrades. If you want it built or run for you, see our eClinicalWorks integration services.
We have built EHR integrations for healthtech companies, several of them in ambulatory settings, and our team has built more than 350 interfaces on Mirth Connect. The patterns below are the ones we deploy.
What eClinicalWorks exposes: FHIR for apps, HL7 v2 for events
eClinicalWorks has two integration surfaces. Certified FHIR R4 APIs serve apps that read clinical data. HL7 v2 interfaces carry the events a clinic runs on: appointments, registrations, lab orders and results, and charges. Mirth Connect does its work on the HL7 side.
The FHIR side is split across two portals: provider-facing and backend apps register on eClinicalWorks Connect, and patient-facing apps on the healow developer portal. Registration, scopes, sandbox limits, practice activation and the rate limit are covered in our eClinicalWorks API integration guide. One fact from that work shapes this whole article: eClinicalWorks' developer documentation lists 89 FHIR API calls, and none of them reads or writes an Appointment, Schedule or Slot, with or without a contract (checked 28 October 2026). The live capability statement agrees. If your product needs a provider's day, including patients who are booked but have not checked in, you need the HL7 SIU feed or healow's separate scheduling API, which we compare in our eClinicalWorks appointment and scheduling API guide.
Which eClinicalWorks HL7 interfaces exist, and what each one carries
Each interface is a separate feed with its own statement of work, so order them by business value, not by message type.
| Interface | Direction | Events you will see | What it carries | Typical use |
|---|---|---|---|---|
| SIU (scheduling) | eCW out | S12 new, S13 rescheduled, S15 cancelled (eCW lists these as common, "not limited to") | Visit number, start and end time, provider, resource, patient, visit type | Day lists, reminders, AI scribes and agents that need today's patients, analytics |
| ADT (patient) | eCW out | A04 register, A08 update, merges; confirm the exact list with eCW | Demographics, guarantor, insurance | Keeping a patient index in step with eCW |
| ORM or OML (orders) | eCW out | New, change and cancel orders | Ordering provider, tests, specimen, diagnosis codes | Reference and hospital labs, imaging |
| ORU (results) | Into eCW | Final, corrected and preliminary results | OBX results with codes, units, ranges, flags | Results landing in the right chart without manual entry |
| MDM (documents) | Either way, by agreement | Document notifications with content | Notes, reports, PDFs | Transcription, outside reports |
| DFT (charges) | eCW out to billing, or into eCW from a partner system | P03 post detail financial transaction | FT1 charge lines with CPT and ICD codes | Billing services, specialty systems that post procedures back |
Two sources back the scheduling and charge rows. eClinicalWorks says it "follows standard HL7 SIU messaging protocol to keep appointments in sync with other EHR and hospital systems," naming S12, S13 and S15. Open Dental, which runs a production eClinicalWorks HL7 bridge, documents ADT and SIU coming from eCW and DFT going back, in its eCW HL7 manual. Some vendor articles list S14 instead of S13; we follow eCW's own list and treat anything else as something to confirm on the statement of work.
The SIU scheduling feed: the complete appointment list for each provider
SIU is the interface teams forget to ask for, and it is the one that answers the most common product question: who is each provider seeing today? The FHIR API can only search Encounter by patient, practitioner, date and location, with no status filter, and an Encounter is the visit itself. Patients who are booked but have not arrived often do not show up in that search. An SIU feed sends a message every time an appointment is booked, moved or cancelled, so your copy of the schedule includes everyone.
A sample SIU^S12 message
This is a synthetic message shaped like an eCW scheduling event. Every name, number and ID is invented.
MSH|^~\&|ECW|DEMOCLINIC|MIRTH|APPDB|20261019091502||SIU^S12|MSG-000123|P|2.3
SCH|900001|900123||||FU^Follow-up visit|||20|MIN|^^20^20261020093000^20261020095000|||||||||||||Booked
PID|1|10045|ACC-55821||TESTPATIENT^JANE^A||19800214|F|||12 MAIN ST^^SPRINGFIELD^IL^62701
PV1|1|O|DEMOCLINIC^EXAM2||||PRV001^PROVIDER^ALEX
AIG|1||PRV001^PROVIDER^ALEX
AIL|1||DEMOCLINIC^EXAM2 The fields that carry the schedule:
- SCH.2 is eCW's visit number. Open Dental's manual uses it as the appointment key, and so should you: S13 and S15 messages for the same visit carry the same value.
- SCH.11 holds the timing: duration, start and end. Open Dental's manual numbers the start and stop components as SCH.11.3 and SCH.11.4, while the HL7 TQ data type puts start and end in components 4 and 5. Check the position against a real message from your practice before you map it.
- AIG names the provider resource. Open Dental falls back to PV1 when AIG is missing, which is a sensible rule for your channel too.
- PID.2 is eCW's internal patient number and PID.4 the account number, per the same manual. Store both.
- SCH.25 carries the filler status (Booked, Cancelled and so on) where the practice sends it.
Mirth channel design for a live appointment table
The channel has one job: keep a table that always matches the eCW schedule, one row per visit. The swimlane below is the design we use.
- Source: TCP listener with MLLP framing on a port reachable only over the practice VPN. Set the response to "Auto-generate (Destinations completed)" so eCW only gets an AA acknowledgment after the row is saved.
- Filter: accept SIU S12, S13, S14, S15, S17 and S26; log and acknowledge anything else so eCW does not retry it forever.
- Transformer: pull the visit number, timing, provider, patient and event into channel variables.
- Destination: a database writer that upserts on the visit number and refuses to overwrite a newer row with an older message.
- Errors: a failed write returns AE, keeps the message in the queue, and raises an alert. Fix the cause, then replay. Our guide to Mirth message replay and dead-letter queues covers the replay side.
The transformer step, in Mirth's JavaScript:
// Source transformer: SIU from eClinicalWorks
var evt = msg['MSH']['MSH.9']['MSH.9.2'].toString(); // S12, S13, S15
var sentAt = msg['MSH']['MSH.7']['MSH.7.1'].toString(); // used to ignore stale messages
var visitId = msg['SCH']['SCH.2']['SCH.2.1'].toString(); // eCW visit number
var startsAt = msg['SCH']['SCH.11']['SCH.11.4'].toString(); // confirm position on a real sample
var endsAt = msg['SCH']['SCH.11']['SCH.11.5'].toString();
var provider = msg['AIG'].length() > 0
? msg['AIG'][0]['AIG.3']['AIG.3.1'].toString()
: msg['PV1']['PV1.7']['PV1.7.1'].toString(); // fall back to PV1
var patient = msg['PID']['PID.2']['PID.2.1'].toString();
var status = (evt == 'S15') ? 'cancelled' : 'booked';
channelMap.put('evt', evt); channelMap.put('sentAt', sentAt);
channelMap.put('visitId', visitId); channelMap.put('startsAt', startsAt);
channelMap.put('endsAt', endsAt); channelMap.put('provider', provider);
channelMap.put('patient', patient); channelMap.put('status', status); And the table it writes to, with the upsert and the day-list query your app runs:
CREATE TABLE ecw_appointment (
practice text NOT NULL,
visit_id text NOT NULL, -- SCH.2
provider_id text NOT NULL, -- AIG.3 or PV1.7
patient_id text NOT NULL, -- PID.2
starts_at timestamptz NOT NULL,
ends_at timestamptz,
status text NOT NULL, -- booked, cancelled, arrived (from ADT or check-in, if sent)
last_event text NOT NULL, -- S12, S13, S15
msg_time timestamptz NOT NULL, -- MSH.7
PRIMARY KEY (practice, visit_id)
);
INSERT INTO ecw_appointment AS a
(practice, visit_id, provider_id, patient_id, starts_at, ends_at, status, last_event, msg_time)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
ON CONFLICT (practice, visit_id) DO UPDATE
SET provider_id = EXCLUDED.provider_id, patient_id = EXCLUDED.patient_id,
starts_at = EXCLUDED.starts_at, ends_at = EXCLUDED.ends_at,
status = EXCLUDED.status, last_event = EXCLUDED.last_event, msg_time = EXCLUDED.msg_time
WHERE a.msg_time <= EXCLUDED.msg_time; -- an older message never wins
-- Today's list for one provider, including patients not yet checked in
SELECT visit_id, patient_id, starts_at, status
FROM ecw_appointment
WHERE practice = 'DEMOCLINIC' AND provider_id = 'PRV001'
AND starts_at >= date_trunc('day', now()) AND starts_at < date_trunc('day', now()) + interval '1 day'
AND status <> 'cancelled'
ORDER BY starts_at; Two things trip up first builds. The feed only sends changes, so on day one you need a starting copy of future appointments; ask eCW whether the practice can trigger a resend for a date range, or load a schedule report once. And keep the visit number, not the time slot, as the key, because a rescheduled visit keeps its number while its slot changes. If the data needs to reach a FHIR app, map each row to a FHIR Appointment in the same channel, as we describe in our FHIR scheduling API guide.
The eClinicalWorks HL7 segments that matter
Across all the feeds, a handful of segments carry most of the data. The positions below come from HL7 v2 and, where marked, from Open Dental's eCW manual.
| Segment | Appears in | What to read |
|---|---|---|
| MSH | All | MSH.9 message type and event, MSH.7 time, MSH.10 control ID for the ACK |
| PID | ADT, SIU, ORM, ORU, DFT | PID.2 eCW internal patient number, PID.4 account number (Open Dental manual), name, birth date, sex, address |
| PV1 | ADT, SIU, ORM, DFT | Patient class, location, attending provider; PV1.19 carries the visit number on DFT (Open Dental manual) |
| SCH, AIG, AIL | SIU | Visit number, timing, visit type, provider and location resources |
| IN1, IN2, GT1 | ADT, sometimes DFT | Payer, plan, subscriber, guarantor |
| ORC, OBR, OBX | ORM, ORU | Order control, test codes, results with units and flags |
| FT1 | DFT | One charge line per procedure with CPT, ICD, units and service date |
| Z-segments | Any, by agreement | Custom fields. Open Dental's eCW bridge uses ZX1.5 for a base64 PDF on DFT |
Treat Z-segments as a contract item. Ask eCW for a sample of every message type with the practice's real configuration (masked), list each Z-segment you will parse, and ignore the rest so an unexpected new segment does not break the channel.
Transport: MLLP, acknowledgments, retries and the dead-letter queue
Most eCW interfaces run HL7 over TCP with MLLP framing: each message starts with a vertical tab (0x0B) and ends with a file separator and carriage return (0x1C 0x0D). Open Dental's manual also documents a shared-folder option for its eCW bridge, so ask which transport your practice's interface uses before you open firewall ports.
- ACK only after the write. An AA sent before the row is saved means a crash loses the appointment for good. Use original-mode ACKs and echo MSH.10 in MSA.2.
- AE versus AR. Return AE for a problem you can fix and replay (a database outage), and AR for a message you will never accept (wrong message type). Agree with eCW how each is handled on their side.
- Retries and ordering. Senders retry when they do not get an ACK, so the same message can arrive twice. The upsert above makes duplicates harmless, and the message-time check stops an old S13 overwriting a newer one.
- Dead-letter queue. Messages that fail after retries go to a queue with the error and the raw message, and someone is alerted. Replays run through the same channel so the logic stays in one place.
Lab integration: orders out, results back
Labs are still the most valuable eClinicalWorks integration for most practices. Orders go out from eCW as HL7 v2 ORM or OML messages over MLLP to the reference lab. Results return as ORU messages; Mirth validates them, maps local lab codes to LOINC, and posts them back so they land in the correct patient chart. Without LOINC mapping, results arrive with local codes that eCW and downstream registries cannot use properly.
Mirth sits in both directions, validating and routing the order, then taking the inbound result, mapping its codes and posting it back so the clinician sees it without manual entry. A useful refinement: as ORU results arrive, a channel can store a clean results summary for fast display, while FHIR is used for drill-down. Our lab integration guide covers the full lab pattern, including mapping ORM and ORU to FHIR DiagnosticReport.
Billing and revenue feeds over DFT
After labs, billing is the feed most ambulatory practices care about, because cash flow depends on it. eClinicalWorks charge detail reaches billing services as HL7 v2 DFT messages, with one FT1 segment per procedure. The flow can also run the other way: Open Dental's eCW bridge sends DFT messages into eCW for procedures done in the dental system, and eCW rejects them if the visit number it originally sent is missing. Mirth picks up charges as visits close, reshapes them for the billing partner, and logs every message so a transient outage queues charges instead of dropping them.
Running billing through the same engine as scheduling and lab data lets you tie a charge back to its visit and the result that justified it, which makes denials easier to work and audits less painful.
How a practice orders an eClinicalWorks HL7 interface, and what it costs
The practice, not your company, owns the eClinicalWorks relationship, so the practice requests the interface. eClinicalWorks scopes it, and its ONC cost disclosure says of its lab interface that "there may be costs associated with the interface. A statement of work is required" (eClinicalWorks cost disclosure, February 2026). eCW publishes no price, so budget for a fee per interface per practice until the statement of work says otherwise.
- Write down the feeds you need (SIU, ADT, ORM/ORU, DFT) and the events in each.
- The practice administrator requests them from eClinicalWorks and signs the statement of work.
- Agree the connection: VPN or site-to-site link, MLLP host and port or file drop, and who monitors it.
- Get masked sample messages for every type and build the Mirth mappings against them.
- Test the ACK flow, duplicates, cancellations and reschedules, not only new bookings.
- Go live in parallel: compare the appointment table to the eCW Resource Schedule for a week before anyone relies on it.
Most delays sit in steps 2 and 3, which depend on the practice and eCW rather than on your engineers. Start them first.
eClinicalWorks upgrade checklist for HL7 interfaces
eCW releases cumulative updates for version 12, and an update can change message content even when the interface itself is untouched. Run this before and after every practice upgrade:
- Capture a week of real messages from each feed before the upgrade and keep them, masked, as a regression set.
- After the upgrade, compare new messages with the set field by field: segment order, new or removed Z-segments, timestamp formats, code values.
- Replay the set through a copy of each channel and diff the output tables.
- Check ACK behavior: who retries, how fast, and whether eCW now expects a different acknowledgment mode.
- Recheck lookup tables (providers, locations, visit types, lab codes) for new values.
- Keep the previous channel version exported so you can roll back in minutes.
Monitoring after go-live
An interface that stops quietly is worse than one that fails loudly, because a missing appointment looks like a quiet day. We watch four signals on every eCW feed:
- Silence. No SIU message for a set time during clinic hours means something is wrong upstream. Thirty minutes is our usual starting threshold; tune it to the practice's volume.
- Errors. Any AE or AR, and any message in the dead-letter queue, alerts the on-call engineer.
- Queue depth. A growing queue in Mirth means the destination is slow or down.
- Daily reconciliation. Count tomorrow's appointments per provider in your table and compare with the eCW schedule report. A mismatch finds missed cancellations that no error ever raised.
Our article on what reliable Mirth Connect monitoring looks like in production covers dashboards and alert rules in more depth.
FHIR and HL7 v2 side by side in an eCW practice
eCW's certified FHIR R4 API exposes US Core resources such as Patient, Encounter, Observation, Condition, MedicationRequest, AllergyIntolerance and DocumentReference, and suits app-facing data access. It has no FHIR Appointment resource; scheduling runs through healow's separate scheduling API, which is FHIR DSTU2 and needs a signed contract, or through the SIU feed. eCW HL7 v2 covers scheduling (SIU), registrations (ADT), lab orders (ORM/OML), results (ORU) and charges (DFT), and suits real-time operational events. The hybrid pattern runs both in Mirth: FHIR for what the app reads, HL7 v2 for what happens in real time.
| FHIR R4 API | HL7 v2 interfaces | |
|---|---|---|
| Best for | Apps reading clinical data, patient access, bulk export | Scheduling, registration, lab and billing events |
| Appointments | Not available (no Appointment, Schedule or Slot) | SIU S12, S13, S15 |
| Delivery | You poll, within eCW's per-practice rate limit | eCW pushes each event as it happens |
| Access | App registration plus practice activation | Statement of work per interface, per practice |
| Writes | Contracted write APIs only | ORU, DFT and MDM into eCW, by agreement |
Supporting US Core is not the same as delivering every USCDI element with complete search behavior and consistent coding, so verify coverage for your use case against the live API before you design around it.
Patient access through healow
healow is eClinicalWorks' patient portal and app. Patient-facing apps that read eCW records use the healow FHIR R4 API with OAuth 2.0 and SMART on FHIR, not the provider-facing eCW API, and the credentials and scopes differ. The healow patient APIs are read-only. Booking appointments uses the separate healow scheduling API, which needs a scheduling app registration and a signed agreement with fees. Mirth can sit behind a patient app to cache and reshape what healow returns so screens stay fast. You can see a healow patient launch end to end in our eClinicalWorks SMART on FHIR walkthrough, recorded against the healow sandbox with a synthetic patient.
Security and compliance
Every eCW interface carries Protected Health Information, so a Business Associate Agreement is required. The FHIR path uses OAuth 2.0 and SMART on FHIR scopes. HL7 v2 interfaces rely on network-level trust arranged with the practice or its hosting, usually a VPN, so keep MLLP ports off the public internet and log access. We sign BAAs with US health systems and digital health companies, build to HIPAA requirements on a FHIR R4 native architecture, and are ISO 27001:2022 certified. All examples in this article are synthetic.
How Nirmitee approaches eClinicalWorks work
Healthcare is the only industry we serve, and ambulatory integration is a regular part of it. We treat the SIU, lab and billing feeds as the clinic's daily reliability layer and the FHIR APIs as the app layer, and run both deliberately in one engine. For the FHIR side, including the sandbox and write-back, read our eClinicalWorks API guide. For Mirth itself, see our Mirth Connect integration services and the complete guide to Mirth Connect.
If you are connecting an eClinicalWorks practice to scheduling, labs, billing or an AI product and want the design checked or built, tell us about your use case and we will tell you what we have shipped for similar ambulatory work.
Ready to scale?
Talk to our healthcare engineering team about building, integrating, and shipping faster.
Frequently Asked Questions
Does eClinicalWorks support HL7 SIU scheduling messages?
Can I get a provider's daily appointment list from the eClinicalWorks FHIR API?
Which HL7 messages does eClinicalWorks support?
How much does an eClinicalWorks HL7 interface cost?
Does eClinicalWorks use MLLP for HL7?
Why use Mirth Connect for an eClinicalWorks integration?
Does eClinicalWorks have a FHIR API?
Is a BAA required to integrate with eClinicalWorks?


