HL7 is the dominant data exchange standard in healthcare. Etlworks supports both HL7 2.x (the long-standing pipe-and-hat message format) and HL7 FHIR (the modern resource-oriented standard) end to end: parse, transform, generate, send and receive over MLLP and HTTP. This article is the single reference for HL7 in Etlworks.
For the dialect-agnostic EDI umbrella, see Get started with EDI documents.
HL7 versions and what each one is
| Version family | Description |
|---|---|
| HL7 2.x | Pipe-delimited message format (MSH, PID, OBR, OBX, …). Used by virtually every hospital information system, lab, and clinical interface. Versions 2.1 through 2.8.x are supported. |
| HL7 FHIR | The modern HL7 standard. Resource-oriented, JSON / XML serialization, REST-API-friendly. Etlworks treats FHIR as a structured JSON dataset; you can read, transform, and emit FHIR resources alongside any other source / destination. |
What can you do with HL7 in Etlworks?
| Goal | Pattern | Jump to |
|---|---|---|
| Parse HL7 messages into a database or file | Read with HL7 format on the source side, optionally transform, write to destination | Read HL7 |
| Build an HL7 message from a database / API / file | Source-to-destination flow with HL7 as the destination format | Write HL7 |
| Reformat one HL7 message into another HL7 message | HL7 to HL7 flow with a mapping that restructures segments / fields | Reformat HL7 |
| Send HL7 over MLLP | HL7 MLLP sender connection as the destination | MLLP transport |
| Send / receive over HTTP | Standard HTTP connector / listener with the HL7 format | HTTP transport |
| Custom transformation in script | JavaScript / Python flow using the HL7 object model | Scripting with the HL7 object model |
The HL7 format
An HL7 format defines how Etlworks parses or builds HL7 messages. Create one in Connections → Formats and pick HL7 2.x or HL7 FHIR.
Key settings on the HL7 2.x format:
| Setting | What it does |
|---|---|
| Version | HL7 version (e.g., 2.3, 2.4, 2.5, 2.8.2). Used to pick the correct object model. |
| Message type | For incoming messages, the expected type (ORM, ORU, ADT, …). Optional — the parser reads MSH-9 from the message itself. |
| Encoding characters | Field, component, subcomponent, and repeat delimiters. The defaults match standard HL7 (|, ^, &, ~); override only when a partner uses non-standard delimiters. |
| Strict validation | Reject messages that don't conform to the schema. |
Read HL7
To parse HL7 messages and load the data into a database, file, or API, set the HL7 format on the source side.
- Create the source connection that holds (or receives) the HL7 messages — file storage, an MLLP listener, or an HTTP listener.
- Create an HL7 format (see The HL7 format above).
- Create the destination connection (database, file, API, …).
- Create the matching flow type — HL7 to database, HL7 to file, HL7 to API, HL7 to HL7.
- Add a transformation. Set FROM to the source connection / HL7 format / message file or topic.
- Click MAPPING to open the nested mapping editor. The source tree shows HL7 segments (MSH, PID, ORC, …) and fields. Drag onto the destination structure.
- Save and execute.
Nested vs. flat mapping
- Nested mapping preserves the HL7 hierarchy. Use it when the destination is JSON / XML / nested-friendly, or when you want to load multiple segments into linked tables in one pass.
- Flat mapping lets you target one segment type at a time — e.g., load every OBX observation across a batch of messages into one observations table. Set a Source query under MAPPING > Source query like SELECT * FROM OBX.
Write HL7
To generate an HL7 message from a source dataset, set the HL7 format on the destination side. The source can be a database query, a file, an API response, or another HL7 message. Etlworks emits a valid HL7 message with correctly-formed MSH, delimiters, and segment hierarchy.
- Create the source connection.
- Create an HL7 format for the target HL7 message.
- Create the destination connection — file storage, HL7 MLLP sender, or HTTP.
- Create a flow whose destination matches (e.g., database to HL7, file to HL7, HL7 to HL7).
- Add a transformation. Map source fields onto HL7 segments using the nested mapping editor — the destination tree shows MSH, PID, etc., with the correct field cardinality.
- Save and execute.
For per-record calculations, conditional segments, or HL7 logic that doesn't fit mapping, see Scripting with the HL7 object model below.
MLLP transport
MLLP (Minimal Lower Layer Protocol) is the transport HL7 systems use over plain TCP. Etlworks ships dedicated MLLP sender and listener connection types.
Send HL7 over MLLP
- Create an HL7 MLLP Sender connection. Configure the partner host / port and any TLS settings.
- Create the HL7 format you'll emit.
- Create the source connection.
- Create a flow that matches the source (e.g., file to HL7, HL7 to HL7).
- Set TO Connection to the MLLP sender. Set TO Format to the HL7 format.
- Map source to HL7 segments.
- Save and execute.
HTTP transport
Some modern HL7 deployments — especially FHIR — use HTTP rather than MLLP. The standard HTTP connector and HTTP listener work with HL7 messages: set the HL7 format on the relevant side of the flow, otherwise the configuration is the same as any HTTP flow.
Send HL7 over HTTP
- Create an HTTP API connection pointed at the receiver endpoint.
- Create the HL7 format you'll emit.
- Create the source connection.
- Create a flow that targets HTTP as the destination (e.g., file to web service).
- Set TO Connection to the HTTP connection, TO Format to HL7.
- Map source to HL7 segments.
Receive HL7 over HTTP
- Create an HTTP listener pointed at a URL path on your Etlworks instance.
- Create the HL7 format for inbound.
- Create the destination connection.
- Create a flow where the source is the HTTP listener with the HL7 format and the destination is the downstream system.
Scripting with the HL7 object model
When HL7 messages are parsed or created, Etlworks stores them as HL7 objects — instances of the version-specific classes shipped by the HAPI HL7v2 library (ca.uhn.hl7v2). From JavaScript / Python flows you can reach into the object model directly through two methods on com.toolsverse.etl.common.DataSet:
| Method | What it does |
|---|---|
| getActualData | Returns the underlying HAPI message object (a version-specific message tree, e.g., ORM_O01). Use it when you need to walk the parsed message in code — e.g., read OBR-22 across a batch and decide which downstream destination to route to. |
| setActualData(…) | Sets the underlying HAPI message object — replaces the parsed representation with one you built or modified in code. |
Use this hook for transformations that don't fit nested mapping: branching on field values, generating multiple output messages from one input, or reformatting deeply nested OBX repetitions in code. Day-to-day HL7 work doesn't need the object model — nested mapping covers most cases.
For the full scripting reference — the HAPI library, package layout per HL7 version, common patterns (clone, DeepCopy, iterate, insert / remove segments), and two worked examples drawn from real clinical interfaces — see Create HL7 messages using scripting.
Notes and limitations
- FHIR — treated as structured JSON. Use the JSON nested-mapping path; the HTTP listener / connector handles FHIR RESTful endpoints.
- MLLP TLS is supported on both sender and listener. The listener's port is the most common failure point; verify firewall rules on-premise or open with support on cloud.
- ACK / NACK for MLLP listeners is generated automatically on receipt of each message; configure the application acknowledgment behavior on the listener connection.
- HL7 object model versions follow the HL7 version on the format — mixing versions across a single flow is allowed (e.g., parse 2.3, emit 2.5) but the mapping must convert between the two structures explicitly.
Related articles
- Get started with EDI documents — the dialect-agnostic umbrella.
- Working with X12 — X12 and EDIFACT, the non-healthcare EDI dialects.
- Nested mapping — the mapping mechanism HL7 work uses end-to-end.
- Working with the Mapping Editor.