HL7 v2
Send HL7 v2 to EDFlow over HTTPS: supported versions and vendors (Epic Bridges, Oracle Health Millennium, MEDITECH), triggers and the events they produce, result and order status maps, the field map, character sets and escapes, the ACK table, and a worked example stream.
EDFlow accepts HL7 v2 over HTTPS, not MLLP. Keep MLLP inside the hospital: your engine acknowledges the EHR as soon as it has persisted a message, and forwards to EDFlow from a separate, queued destination. A EDFlow slowdown can never back up your EHR's queues.
Endpoints and modes
| Mode | Endpoint | Content-Type | Response |
|---|---|---|---|
| Raw (HL7 over HTTPS), recommended | POST /v1/hl7v2 | application/hl7-v2, x-application/hl7-v2+er7, or text/plain (Mirth default), optional charset matching MSH-18 | One ACK per the table below, in the inbound message's version and character set; or 503/429 with Retry-After |
| JSON-wrapped batch | POST /v1/hl7v2 | application/json with { "messages": [{ "er7": "MSH…" }] } (up to 50) | JSON with an ACK and the derived events per message |
| Signed profile | POST /ehr/v1/hl7v2 | JSON-wrapped | As the signed ingest profile |
The site comes from ?site=, otherwise from MSH-4 through the mapping profile. Authenticate with a bearer token, an API key, or HTTP Basic with client_id:api_key.
printf '%s' 'MSH|^~\&|EPIC|KBSCS|EDFLOW|EDFLOW|20260914080214-0400||ADT^A04^ADT_A01|ADT000123|T|2.5.1||||||UNICODE UTF-8
EVN|A04|20260914080211-0400
PID|1||SYN0001^^^KB^MR||Synthetic^Pat
PV1|1|E|ED^WR^01' > body.jsoncurl -sS -X POST 'https://api.sandbox.edflow.space/v1/hl7v2' \ -H 'Content-Type: application/hl7-v2' \ -H "Authorization: Bearer $EDFLOW_ACCESS_TOKEN" \ --data-binary @body.jsonVersions and vendors
Accepted MSH-12 versions: 2.3, 2.3.1, 2.4, 2.5, 2.5.1, 2.6, 2.7 and 2.8, with vendor profiles for Epic Bridges, Oracle Health Millennium (ESO/COI), MEDITECH Expanse and a generic profile. Before v2.5 there is no TQ1 or SPM; timing falls back to OBR-27/ORC-7 and OBR-7, specimen to OBR-15.
Processing id by environment
| Environment | MSH-11 accepted |
|---|---|
| Sandbox | T or D only. P is refused with AR, ERR-3 202 |
| Customer test | T or P |
| Live | P only |
Triggers
| Message / trigger | Events produced |
|---|---|
| ADT^A04 Register (ED class and location) | encounter.arrived; plus encounter.triaged if a CTAS OBX is present, careteam.snapshot if PV1-7 or ROL is present |
| ADT^A01 Admit/visit | As A04 for sites that use A01 for ED arrival; as A06 when an ED encounter becomes inpatient |
| ADT^A08 Update | Only the mappers whose fields are present: location (PV1-3), care team (PV1-7/9/52, ROL), triage (CTAS OBX), patient updates (PID-5/7/15, PD1-12, PV2-22) |
| ADT^A02 Transfer | encounter.location_changed; to an inpatient unit: encounter.departed (admit) |
| ADT^A03 Discharge | encounter.disposition_decided (if not yet recorded) + encounter.departed |
| ADT^A06 | encounter.disposition_decided (admit) |
| ADT^A11 Cancel visit | encounter.cancelled, or left without being seen, per the profile's a11Semantics |
| ADT^A12 / A13 | Location restored / encounter.departure_cancelled |
| ADT^A14 / A27 | admission.status_changed bed requested / cancelled |
| ADT^A21 / A22 | Location out_of_department and back |
| ADT^A40 (A34/A18 in older versions) | patient.merged |
| ORM^O01, OMG^O19, OML^O21, OMI^O23 | order.placed (NW, XO), order.status_changed (SC), cancelled (CA, OC, DC, OD, CR); consult codes become consult.status_changed; NPO diet codes become a diet order |
| ORU^R01 | order.status_changed per OBR from OBR-25 and OBR-22. OBX segments are ignored and never parsed for values |
| SIU^S12/S13/S14, S15 | Scheduled with scheduledFor; schedule removed |
| MDM, DFT, BAR, VXU, others | Acknowledged AA with an "ignored" warning. Filter them at the engine |
Identifier-change triggers (A44, A45, A47, A50, A37, A35, A46, A49) are acknowledged with a warning and raise an alert so an analyst reconciles the visit.
Result status (OBR-25, table 0123)
OBR-25 | Status |
|---|---|
O | placed |
S | scheduled |
I | lab: in the lab; imaging: in progress |
R | lab: in the lab; imaging: performed |
A, P | preliminary |
F | resulted |
C | corrected |
X | cancelled |
Order status (ORC-5, table 0038, used only when OBR-25 is empty)
ORC-5 | Status |
|---|---|
SC | placed (scheduled if a time is present) |
IP | in the lab or in progress |
A | preliminary |
CM | resulted |
CA, DC | cancelled |
HD | unchanged, on hold |
Order status only moves forward, unless the message is a correction, a cancellation or an explicit reversal (ORC-1 = CR, OBR-25 = X).
Field map
| Field | Target | Handling |
|---|---|---|
MSH-3/4 | Source system, feed, site | |
MSH-7 | recordedAt fallback | No offset: the profile time zone |
MSH-10 | Message id, part of the event id | |
EVN-2 / EVN-6 | recordedAt / occurredAt | |
PID-3 (type MR) | Record number | Hashed on receipt |
PID-3 (type JHN, health card) | Dropped | |
PID-5, PID-7 | Name, birth date | Only for the sign-in match key, then discarded |
PID-11, PID-13/14, PID-19 | Dropped | Address, phones, SIN |
PID-15 | Preferred language | Mapped to BCP-47 |
PD1-12, PV2-22 | Confidential flag | |
PV1-2 | Filter | E = emergency |
PV1-3 | Location → area | Via the profile |
PV1-7/9/17/52, ROL | Care team | ROL-2 DE releases a member |
PV1-19 | Visit identifier | Hashed at rest |
PV1-36 | Disposition | Via the profile |
PV1-44 / PV1-45 | Arrived / departed | |
PV2-3 | Chief complaint | Dropped unless the site opts in |
OBX in ADT | CTAS, only for the profile's CTAS codes | Every other OBX ignored |
ORC, OBR-4/7/14/22/24/25/27/36, TQ1-9, SPM | Order code, times, category, status, priority | Order ids hashed |
OBX in ORU | Never read |
An empty field means "no change"; "" means "clear". An A08 carries only the fields present, so it never releases a care-team member that arrived through ROL.
Character sets and escapes
MSH-18:ASCII,8859/1orUNICODE UTF-8. When empty, the mapping profile's required default applies. An HTTPcharsetthat disagrees, or invalid bytes, returnAEunsupported_encoding.- Escape sequences (
\F\,\S\,\T\,\R\,\E\,\Xhh\,\.br\) are decoded and values normalized before mapping, so accented names produce the same match key in every encoding. FHS/BHSbatch files aren't supported. Send messages one by one, or up to 50 per JSON request.
Acknowledgements
Original mode only: every message gets one application ACK in the HTTP response.
| Outcome | HTTP | MSA-1 | What your engine does |
|---|---|---|---|
| All derived events accepted, duplicate, buffered or superseded | 200 | AA | Next message |
| Message type EDFlow doesn't use | 200 | AA with an "ignored" ERR | Next message; filter it at the engine |
| Data problem (unknown code, invalid value) | 200 | AA with warning ERR segments | Next message. Never hold the queue. The event goes to the dead-letter queue; the analyst fixes the mapping and replays it |
Structural error (bad MSH, encoding, missing segment, batch) | 200 | AE | Route to your error queue and alert. Don't resend unchanged |
| Environment or version mismatch (processing id, sandbox tripwire, version) | 200 | AR | Channel configuration error: stop and fix. AR means only this |
| Transient failure | 503 or 429, Retry-After, no ACK | — | Keep it queued; retry after the delay. Already-committed events return duplicate |
| Authentication | 401 / 403 | — | Fix the credential or re-authenticate |
MSH|^~\&|DEST|DEST|EHR|HOSP|20260914080215.402-0400||ACK^A08^ACK|rid_01J8…|P|2.5.1
MSA|AA|ADT000124
ERR||PV1^1^3|103^Table value not found^HL70357|W|unknown_location^Location code not in the mapping profile^99LNT||||Location ED^HALL^7 is not mapped; the location update was dead-lettered.Worked example (synthetic, sandbox)
MSH|^~\&|EHR|DEMOHOSP|DEST|DEST|20260914080214-0400||ADT^A04^ADT_A01|ADT000123|T|2.5.1|||||||UNICODE UTF-8
EVN|A04|20260914080214-0400||||20260914080211-0400
PID|1||SYN0000123^^^DEMOHOSP^MR||ZZTEST^BIRCH||19900101|U
PV1|1|E|EDWR^WR01^^DEMOHOSP|E|||||||||||||||SYN3000123^^^DEMOHOSP^VN|||||||||||||||||||||||||20260914080211-0400produces encounter.arrived (waiting room, arrival 08:02:11). Then:
MSH|^~\&|EHR|DEMOHOSP|DEST|DEST|20260914081602-0400||ADT^A08^ADT_A01|ADT000131|T|2.5.1
EVN|A08|20260914081602-0400||||20260914081530-0400
PID|1||SYN0000123^^^DEMOHOSP^MR
PV1|1|E|EDWR^WR01^^DEMOHOSP|E|||||||||||||||SYN3000123^^^DEMOHOSP^VN
OBX|1|CWE|11283-9^Acuity assessment at first encounter^LN||3^CTAS 3^L||||||F|||20260914081530-0400produces encounter.triaged (CTAS 3 at 08:15:30). An ORM^O01 for a urinalysis produces order.placed and the patient's urine-sample task; the ORU^R01 with OBR-25 = F produces order.status_changed resulted, and its OBX value is never read; the ADT^A03 produces the disposition and departure.
Try your own messages with Validate in the developer console or POST /v1/events/validate?input=hl7v2: you get the events, a field-by-field trace, the fields dropped, unmapped codes and the exact ACK.
Related
Dernière mise à jour le
Cette page vous a-t-elle été utile?
FHIR R4
Send FHIR R4 to EDFlow: batch Bundles, the $ingest operation for collection, searchset and Subscriptions Backport notifications, $process-message, how each resource maps to events, Epic and Oracle Health notes, and a worked example.
Mapping profiles
The versioned EDFlow site mapping profile: encounter filters and identifiers, locations and beds, CTAS codes, roles and practitioner ids, dispositions, order and consult codes, NPO diet codes, result thresholds, privacy options, and unmapped-code governance.