HL7 v2 and FHIR for clinical dashboards
From an HL7 v2 ORU^R01 lab message to a dashboard tile: FHIR Observations with ranges and flags, signed webhooks, no duplicates — and why this is not bedside monitoring.
A clinical dashboard needs results as structured, coded data the moment they are reported — test, value, unit, reference range and flag — not PDFs it has to read. Laboratories still send most results as HL7 v2 ORU^R01 messages, while dashboards are easiest to build on FHIR R4 Observations. Anpheros sits between the two: a laboratory system posts the HL7 v2 message (or a CSV or JSON report) over HTTPS, each result becomes a FHIR Observation with its code (LOINC when the lab sends it), value and reference range, and a signed webhook tells your dashboard that new results arrived.
- Laboratory systemSends an HL7 v2 ORU^R01 message or a CSV report
- Lab connectorPOST /v1/patients/{id}/labs/import over HTTPS
- FHIR ObservationsLOINC code, value, unit, reference range, H/L flag
- Signed webhookresource.created reaches your server, retried on failure
- Your dashboardReads the new results and updates the tile
What the dashboard receives
Each OBX segment of the message becomes one laboratory Observation:
| HL7 v2 OBX field | FHIR R4 Observation | On the dashboard |
|---|---|---|
| OBX-3 test code | code (LOINC when the lab sends it; a local code is kept as the lab's code) |
Test name; LOINC makes it comparable across labs |
| OBX-5 value, OBX-6 unit | valueQuantity (UCUM unit) |
The number and its unit |
| OBX-7 reference range | referenceRange |
The normal band |
| OBX-8 abnormal flag | interpretation (H, L, …) |
The red or blue flag |
| OBX-14 time | effectiveDateTime |
When the sample was taken |
Import a message and react to it
Send the message for a patient you created (or one you hold a grant for):
import { readFile } from 'node:fs/promises';
import { Anpheros, apiKey } from '@anpheros/sdk';
const anpheros = new Anpheros({ auth: apiKey(process.env.ANPHEROS_KEY!) }); // a sandbox key, sk_test_…
const message = await readFile('oru_r01.hl7', 'utf8');
const result = await anpheros.labs.importHl7(patientId, message, { sourceSystem: 'lab-lis' });
console.log(result); // created, skipped and unmapped counts
Then let the platform call your dashboard backend instead of polling it:
await anpheros.webhooks.create('https://dashboard.example.org/anpheros/hook', { events: ['resource.created'] });
Each delivery is signed (verify it with verifyWebhookSignature from the SDK) and retried if your server does not answer. The event carries the resource type, id and patient; read the new Observations and refresh the tile. Resent reports are skipped, so a laboratory that retransmits on a timeout does not create duplicate rows on the screen.
Choosing HL7 v2 or FHIR for each link
| Link | Use | Why |
|---|---|---|
| Laboratory → data layer | HL7 v2 ORU^R01 (or CSV/JSON) | What laboratory systems already emit; no change on their side |
| Data layer → dashboard | FHIR R4 Observation + webhooks | Coded, versioned JSON your front end can read directly |
| Dashboard → other apps | FHIR R4, under the patient's consent | One standard for every consumer |
What this is not
- Not a bedside monitor feed. Anpheros accepts laboratory reports over HTTPS. It does not receive continuous waveforms or device streams from intensive care monitors, and it is not an alarm system: alerts that affect care need a certified clinical system.
- Not an MLLP interface engine. Messages arrive over HTTPS; if your laboratory only speaks MLLP over TCP, an interface engine in front forwards them.
- One HL7 v2 message type. ORU^R01 laboratory results are accepted; orders (ORM/OML) and ADT messages are not.
Frequently asked questions
Can a dashboard read HL7 v2 lab results directly?
It can, but every dashboard then needs its own HL7 v2 parser, code mapping and de-duplication. Converting once into FHIR R4 Observations with LOINC codes gives every screen the same clean data.
How fast do imported results reach the dashboard?
The import request returns when the Observations are stored, and a resource.created webhook is queued for each of them at the same time. Delivery is retried if your endpoint is unavailable.
How are abnormal results flagged?
OBX-8 becomes the Observation's interpretation (for example H or L) and OBX-7 its referenceRange, so the dashboard can show both the flag and the normal band.
Does Anpheros support ICU monitoring?
No. It stores laboratory and clinical results and notifies your systems about new data; continuous bedside monitoring and clinical alarms stay with certified medical devices.