HL7Forge logoHL7Forge / guide

The HL7Forge User Guide

01The layout

One window, five working areas. Templates live on the left. Connection settings and the activity log share the right column, so your network state and traffic sit together. Both side panels slide out of the way when you need room, and every divider drags to resize.

1 2 3 4 5
βš™ Settings⇄ Routing≋ Transforms πŸ“‚ LoadπŸ’Ύ Save⚑ CSV GenπŸ—‚ Workspace β–Ύ β”€β–’βœ•
Admit Patientlab_results.hl7
Built-In Templates
ADT A01 Admit Patient
ADT A03 Discharge Patient
ORU R01 Lab Result
SIU S12 Schedule Appointment
My Saved Templates
CUS Mercy admit test
Connection
10.10.10.10
2575
Activity Log
8:03:39β†’ OUTADT^A01
8:03:39← INACK AA
ADT^A01 readyRepeat: 1Γ—Send Current
1Titlebar: settings, routing, transforms, file open/save, CSV generator, workspaces
2Sidebar: built-in and saved message templates
3Editor: message tabs on top, view tabs (Raw / Field / Parsed / Stats / Query / Timeline / Compare) inside
4Connection panel: endpoints, transport, and the receiver
5Activity log: every send, ACK and event. Click a row for full detail

02Create a message

You rarely need to write HL7 from scratch. Pick a template from the sidebar (ADT, ORU, ORM, SIU, MDM, MFN, DFT, VXU, RDE, OML, REF and ACK are all included) and a valid message opens in a new tab, ready to edit or send. You can also save any message of your own as a reusable template.

Readyβ”€β–’βœ•
Admit Patient
Built-In Templates
ADT A01 Admit Patient
ADT A03 Discharge Patient
ORU R01 Lab Result
SIU S12 Schedule Appointment
ORM O01 Order Message
ADT^A01 ready
Templates generate fresh identifiers each time, so repeated test messages never collide. If you need to re-roll the control ID on an existing message, click New ID in the toolbar.

03Connections

The connection panel sits above the activity log. Enter a host and port, pick a transport, and you are ready to send. Save the combination as a named endpoint and it comes back on every launch, shared with everyone using the same install.

  1. Enter the Host / IP and Port of the system you are testing against.
  2. Pick a transport: MLLP for standard HL7, MLLP over TLS for encrypted links, or raw TCP.
  3. Click Test Connection. The titlebar LED turns green when the listener answers.
  4. Click Save, give it a name, and the endpoint appears in the dropdown from then on.
Not connectedβ”€β–’βœ•
Set up the connection on the right
Saved Endpoints
-- select --
Connection
 
 
MLLP (standard HL7)
Test Connection Save
Idle

TLS

Many hospitals now require encrypted HL7 links. Choose MLLP over TLS as the transport to send encrypted, with an option to accept self-signed certificates for test systems. The receiver can terminate TLS too: tick TLS listener and point it at your PEM certificate and key files.

The receiver. The panel's Receiver section starts a listener on any port, answering with the ACK code you choose (AA, AE, AR or CA). Use it to test the sending side of an interface without standing up an engine.

04Send & receive

Click Send Current and watch the round trip in the activity log: the outbound message, the returning ACK, and how long it took. Start the listener and inbound messages appear in the same log as they arrive.

Connected to 10.10.10.10:2575β”€β–’βœ•
Activity Log
ORU^R01 readyRepeat: 1Γ—Send Current
Set Repeat to 5x, 10x, 50x or 100x with a millisecond delay to fire the same message repeatedly. Handy for draining queues without setting up a full load test.

05Working with files

Load whole HL7 files and step through the messages one at a time, or send the entire batch in one pass. Large files stream in with a progress bar, and files carrying embedded documents (base64 PDFs and RTFs, even tens of megabytes) open without trouble.

lab_results.hl7β”€β–’βœ•
Activity Log
β€Ή Prev Message 1 of 250 Next β€Ί Send All (250)
250 messages loaded
Very large fields are safe. A field over 20,000 characters (usually an embedded document) is shown truncated with a marker, and the raw editor locks to read-only so nothing hidden can be lost. The full content is always kept for sending and saving, and messages with an embedded PDF or RTF get a banner with an Open / Download button.
Multi-gigabyte, document-heavy files. Opening a file large enough to strain memory shows a size warning with an Open Anyway choice. For document-heavy work, turn on Settings β†’ Editor β†’ Stream large embedded documents from disk: embedded documents (base64 PDFs, CDAs, scans) are then held on disk instead of in memory and streamed back in full only when a message is sent or saved, so files running to several gigabytes open without exhausting memory. In the field views the document shows as a compact ⧉ embedded document placeholder.

06The editing views

Raw HL7 when you want speed, Field Editor when you want precision, Parsed View when you just want to read. They stay in sync: click a field in one and the others follow.

Raw HL7

Click anywhere in the message and the status bar names the exact field under the cursor. Hold the mouse over a field and a tooltip shows its ID, name and value, with the plain meaning for coded fields.

Raw HL7Field EditorParsed ViewStatisticsQueryTimelineCompare
PID.8 β€” Sex
= "F" β†’ Female
Click anywhere in the message to identify the field

Field Editor

Every field on its own row, labelled, with a length counter that warns when a value goes past the HL7 maximum. Fields with components (a PID.5 name, for example) expand into per-component rows.

Raw HL7Field EditorParsed ViewQuery
PID: 8 of 30 fields populated

07Split screen

Split the editor into two panes and give each one its own view tab. Raw HL7 on top with the Field Editor underneath is the usual pairing. Type in either pane and the other updates as you go. Drag the divider to resize.

Admit Patient (split view)β”€β–’βœ•
Raw HL7Field EditorParsed ViewQuery
Raw HL7Field EditorParsed ViewQuery
FieldNameValue
PID.5.1 (Family Name)2 panes

08Find & replace

Press Ctrl+F or click Find in the toolbar. Matches highlight as you type, with Prev and Next to walk through them. Open the replace row to swap values in the current message, across every message in the loaded file, or only inside one segment type.

β–Ό   β—€ PrevNext β–ΆSearch File βœ•
  Replace All 250 msgs In segment
Matches highlight as you type
In segment is the surgical option: it replaces only within the segment type your cursor is on, across the whole batch. Useful when a value like a ward code appears in PV1 but you must not touch it anywhere else.

09Validate

One click checks required fields, coded values, timestamp formats, segment names and message structure. Each problem is listed and highlighted red at the spot where it lives.

Admit PatientValidate β–ΎNew IDAnonymizeExplainFHIRFind
Run Validate to check this message
βœ•PID.7 Date of Birth 20390312 is in the future
βœ•PV1.2 value "Q" is not a valid HL7 code (valid: E,I,O,P,R,B,C,N,U)
Vendor profiles. Add your own rules (mandatory fields, formats, lengths, regex patterns) under Validate, then use Export Profile to save them as a JSON rule pack. A colleague imports the same file and runs identical checks. One profile per vendor works well.
Your rules take precedence. When a custom rule covers a field that also has a built-in check, your rule wins. Set MSH.10 to a 50-character maximum, for example, and that replaces the standard 20-character check rather than both firing.

10Anonymize

Strip patient data before sharing a message with a vendor or colleague. Choose which fields to clear or randomise (names, MRNs, dates of birth, addresses, phone numbers, next of kin, doctors), give fixed values where you need them, and save the combination as a preset. Changed fields flash briefly so you can see exactly what was touched.

Admit Patientβœ“ Patient data strippedValidate β–ΎNew IDAnonymizeExplainFHIRFind
ADT^A01, 5 segments
Tick Anonymize all messages in file to process a whole loaded batch in one pass, and open results in a new tab if you want to keep the originals untouched.

11Explain & FHIR

Explain opens a plain-English window for the current message: what it is, who sent it, the patient, the visit, and the results with abnormal values flagged. Useful when you need to walk a non-HL7 person through a message.

Lab ResultValidate β–ΎNew IDAnonymizeExplainFHIRFind
Message Explanationβœ•
ORU^R01, 6 segments

FHIR view

The FHIR button next to Explain shows the same message as a FHIR R4 bundle: Patient, Encounter, Observations, DiagnosticReport, allergies and diagnoses, mapped from the v2 segments. It is read-only, with a copy button, and is meant for review and vendor conversations rather than production conversion.

12Timeline

The Timeline tab groups a loaded file by patient and lays each patient's messages out in time order: admit, transfer, results, discharge. Click any event to jump straight to that message. The search box filters by patient name or MRN, which is the quick way to find one patient in a large file. It reads PID.3 for the patient and MSH.7 for the order of events.

Raw HL7Field EditorParsed ViewStatisticsQueryTimelineCompare
Search patient name or MRN…4 patients across 250 messages Β· click an event to open that message
β–ΌEmily CarterMRN0045214 events
10/07 08:15AdmitADT^A01WARD3 301
10/07 10:30ResultORU^R01COMPLETE BLOOD COUNT
11/07 09:00TransferADT^A02WARD7 112
12/07 16:20DischargeADT^A03
β–ΆSamuel OkaforMRN0077333 events
Patients with the most activity sort first
Replay a patient's journey. Each patient group has a Send all in order button that re-sends every one of that patient's messages to your current connection in the order they were originally sent, which makes it easy to reproduce a full admit-to-discharge sequence against a downstream system.

13Compare

Put two messages side by side and see the differences field by field. Paste into slot A and B (or send messages there from the right-click menu), and the table on the right lists every segment that differs, with the A and B values in adjacent columns. The header counts the differences and a checkbox shows or hides identical fields.

Raw HL7Field EditorParsed ViewStatisticsQueryTimelineCompare
Comparing… A onlyB onlyChanged
Message AEditPaste
Message BEditPaste
FieldLabelAB

14Query

Search every loaded message by field value. Conditions can be combined with AND, and the matches land in a table you can open as a new batch or export to CSV.

QUERY
 
Run Export CSV
#MSH.9PID.5OBX.3OBX.5OBX.8
The query runs across every loaded message
Beyond a single search. Start from a ready-made query under Examples β–Ύ, and keep the ones you reuse with Saved β–Ύ. Selecting a repeating segment (OBX, NTE and the like) returns one row per occurrence, not just the first. There's no default row cap. Add LIMIT yourself when you want one; past 100,000 rows a banner reminds you it's there.

15Statistics & gap analysis

The Statistics tab profiles a whole batch: which fields carry data, what values appear, and how often. The Gap Report starts with a message-type breakdown, then walks the segments in message order showing every defined field's fill rate, including fields that never carry a value at all.

Field Gap Report: 250 messagesβœ•
Message Types (MSH.9)
ADT^A01
96
ORU^R01
87
ADT^A08
41
MSH: 250 occurrences, 0 gaps
MSH.7 Time
100%
PID: 250 occurrences, 2 gaps
PID.5 Name
100%
PID.11 Addr
74%
PID.13 Phone
41%
PID.19 SSN
0%
2 fields defined but never populatedGaps only⬇ CSVClose
Segments appear in message order (MSH first, then EVN, PID, PV1 and so on), matching how the traffic actually runs. Fields at 0% are your gaps: defined by the standard, promised by the vendor, never actually sent.
Focus the table. Tick Hide unfilled to drop fields that never carry data, and right-click the table for Expand all segments to open every field's components at once (the same right-click shortcut works in the Field Editor and Parsed View).

16Routing rules

Routing turns HL7Forge into a small interface engine. Messages are checked against your rules top to bottom, first match wins, and the matching rule forwards to an MLLP endpoint, logs, or drops the message.

Message Routing Rulesβœ•
Evaluated top-to-bottom Β· first matching rule wins
#OnNameConditionActionDestination
οΌ‹ Add RuleClose

17CSV generator

When you need a batch of realistic test messages, build them from a spreadsheet. One CSV row becomes one message: pick a base template, load the file, map each column to an HL7 field path, and generate.

A CSV for ten test admissions looks like this (the first rows shown):

PID.3.1PID.5.1PID.5.2PID.7PID.8PID.11.3PV1.2
MRN010001WALKERSOPHIE19910405FGeelongI
MRN010002PATELARJUN19780212MBallaratO
MRN010003NGUYENLINH19650830FBendigoE

Name your headers as field paths, like above, and the mapping fills itself in the moment the file loads. Any other header works too; you just type the target path yourself.

Generate Messages from CSVβœ•
ADT A01 Β· Admit Patient
πŸ“‚ Load CSV… No file loaded. First row must be headers
Generate Messages Cancel
Every generated message gets a fresh control ID and timestamp automatically, so the batch is ready to send as-is. An explicit MSH.10 or MSH.7 column still wins if you map one.

18Load testing

The Load Test window sends the current message repeatedly at a target rate, each copy with a fresh control ID, and measures the ACK round trip. You get live counts, achieved throughput, and latency percentiles as it runs.

Load Testβœ•
25
500
0 / 500 complete0.0s
ACK OK
0
NACK
0
Failed
0
Rate
0.0/s
Avg latency
0ms
p50
0ms
p95
0ms
Sends the current message repeatedly with fresh control IDs β†’ 10.10.10.10:2575 (MLLP) β–Ά StartClose
Latency is the full send-to-ACK round trip. If the achieved rate falls short of the target, the receiving system or the ACK timeout is the bottleneck, not HL7Forge.

19Transforms & auto-responder

Two quiet workhorses. Transforms rewrite fields on every outgoing message (swap the sending facility, stamp a test flag) without touching your files on disk. The auto-responder answers inbound messages with rule-based ACKs so you can simulate the system on the other end, including NACKs and slow responses.

Outgoing transformMSH.4 β†’ "TESTFAC" Β· PID.19 β†’ clear
Transforms apply on send. Files on disk are never modified

20Activity log

Everything that happens lands here with a timestamp. Click a row to see the full sent message and its ACK. The β†Ί button resends a past message through the current connection, and Export writes the whole log to a text file for a ticket or a handover.

Activity LogExportClear
TimeDirMessageACK
Click a row for full message detail

21Workspaces

A workspace file captures your whole session: every open tab with its messages, plus the connection settings. Save one at the end of a piece of testing and reopen it days later exactly where you left off, or hand the file to a colleague so they start from your setup.

  1. Click πŸ—‚ Workspace in the titlebar and choose Save Workspace. Everything open goes into one .hl7ws file.
  2. To restore, choose Open Workspace and pick the file. HL7Forge confirms before replacing your current tabs.

22Themes & text size

Nine themes from deep dark to bright light, picked from the dropdown in the titlebar and applied instantly. Settings adds an intensity slider and three text sizes. Try the dropdown here:

Theme preview Theme:
Themes apply instantly, no restart needed

23Shortcuts & tips

Ctrl+FFind and replace in the current message or batch
Ctrl+Z / Ctrl+YUndo / redo edits
Click in Raw viewIdentify the field under the cursor and highlight it in the other views
Hover in Raw viewTooltip with the field name, value, and coded-value meaning
Right-click in Raw viewCopy field or segment, send to Compare A/B, filter Statistics by this value
Drag panel edgesResize the sidebar, connection panel, log, and split panes. The β€Ήβ€Ή / β€Ίβ€Ί buttons collapse them
Timeline tabGroup a loaded file by patient and jump between their events
FHIR buttonRead the current message as a FHIR R4 bundle
Machines without internet? Enterprise licences activate fully offline. The Licence screen shows a Computer ID you send to support, and the signed key that comes back works with no network access at all.
Stuck? Email [email protected] and include the relevant Activity Log export. It usually shows exactly what happened.