Skip to main content

HL7 Configuration

The HL7 configuration is a standard configuration object managed via the Configuration API. Within this framework, it is identified by its configuration type and consumed by the HL7 worker.

This document describes the structure and behavior of HL7 configurations and how they are used to transform incoming HL7 messages into FHIR resources at runtime.

Configuration Model Overview

An HL7 configuration is identified by a combination of tenant, and metadata. The transformation logic is defined declaratively in the content field.

Type

Identifies the configuration domain. HL7 configurations use: hl7

Scope

Identifies the configurations scope. Can be one of: global, organization, ward, role or user.

Name

Identifies the configurations name. This name is not needed for finding configurations.

TenantId

Identifies the tenant (e.g. hospital or system) this configuration belongs to. This field is mandatory and ensures proper routing and isolation of configurations. The fallback tenantId in the hl7 worker is mona-default

Meta

A flexible JSON object used for message-level matching. The HL7 worker reads the event type from the incoming message and selects the appropriate configuration based on these metadata filters.

Example:

{
"hl7_event": "ADT^A01"
}

content

Contains the ordered list of operations executed by the HL7 worker. Operations define how HL7 data is transformed into FHIR resources. See next section or click here.

Operation Model

HL7 transformations are defined as a sequence of operations. Operations are executed sequentially from top to bottom.

Each operation performs a specific task such as:

  • creating a resource
  • updating a resource
  • loading an existing resource
  • performing an upsert operation
export interface Operation {
type: OperationType;
options: OperationOptions;
storeAs?: string;
isCritical?: boolean;
hl7Segment?: {
hl7Type?: string;
iterate?: boolean;
};
}

Type

Defines the action executed by the HL7 worker. Current supported values:

createResource
updateResource
loadResource
upsertResource

Each operation type has specific option requirements. See operation-handlers for more information for each handler and examples.

Options

Operations define their configuration using the options object.

export interface OperationOptions {
fhirType: string;
mapping: MappingConfig;
createMapping: MappingConfig;
updateMapping: MappingConfig;
search: string;
}

Not every option is required for every operation. See details in the operation-handlers section.


FhirType

Specifies the FHIR resource type. Examples: Patient, Encounter, Observation.


Mapping/CreateMapping/UpdateMapping

Defines the transformation from HL7 fields to FHIR fields.

{
"gender": "{{PID-8|hl7Gender}}",
"birthDate": "{{PID-7|hl7Date}}"
}

FHIR search query used to locate existing resources. Example:

identifier={{PID-3-1}}

StoreAs (optional)

Stores the resulting resource in the execution context so it can be reused by later operations.

storeAs: "patient"

Later usage:

Patient/%patient.id%

This behaves like a runtime variable shared between operations.

IsCritical (optional)

Controls error handling behavior.

ValueBehavior
trueProcessing stops if the operation fails
falseProcessing continues

This allows distinguishing between mandatory and optional operations. If not set, processing will continue after errors.

hl7Segment (optional)

Defines the HL7 segment or group that should trigger the operation.

{
"hl7Segment": {
"hl7Type": "OBX",
"iterate": true
}
}
FieldDescription
hl7TypeHL7 segment type (e.g. PID, PV1, OBX)
iterateExecute the operation for every occurrence

If iterate is true, the worker processes all matching segments.

Operation Handler

loadResource

Loads an existing resource using a FHIR search query. Required options:

  • fhirType
  • search
{
"type": "loadResource",
"storeAs": "patient",
"options": {
"fhirType": "Patient",
"search": "identifier={{PID-3-1}}"
}
}

createResource

Creates a new FHIR resource. Required options:

  • fhirType
  • mapping

Example:

{
"type": "createResource",
"storeAs": "patient",
"options": {
"fhirType": "Patient",
"mapping": {
"identifier[0].value": "{{PID-3-1}}",
"gender": "{{PID-8|hl7Gender}}",
"birthDate": "{{PID-7|hl7Date}}"
}
}
}

updateResource

Updates an existing FHIR resource. Typically used after a loadResource operation because it uses a context id. If you want to search and update for a resource in one step use the upsert resource handler.

  • fhirType
  • mapping

Example:

{
"type": "updateResource",
"storeAs": "patient"
"options": {
"fhirType": "Patient",
"mapping": {
"address[0].city": "{{PID-11-3}}"
}
}
}

UpsertResource

Performs a conditional create or update.

Execution logic:

  1. Execute search
  2. If resource exists → update using updateMapping
  3. If no resource exists → create using createMapping

Required options:

  • fhirType
  • search
  • createMapping
  • updateMapping

Example:

{
"type": "upsertResource",
"storeAs": "patient",
"options": {
"fhirType": "Patient",
"search": "identifier={{PID-3-1}}",
"createMapping": {
"identifier[0].value": "{{PID-3-1}}",
"gender": "{{PID-8|hl7Gender}}"
},
"updateMapping": {
"gender": "{{PID-8|hl7Gender}}"
}
}
}

Execution Semantics

Operations are processed sequentially.

Important rules:

  • Later operations may reference previously stored resources
  • Template expressions are resolved at runtime
  • Failures respect the isCritical setting

Mapping Expressions

Mappings define how HL7 data is transformed into FHIR fields.

{
"gender": "{{PID-8|hl7Gender}}",
"status": "in-progress",
"subject.reference": "Patient/%patient.id%"
}
Expression TypeExample
HL7 field{{PID-3-1}}
transformer{{PID-8}}
static value"status": "final"
stored variable"Patient/%patient.id%"

Custom HL7 Transformers

Transformers convert HL7 values into valid FHIR values.

Usage

{{PID-8|hl7Gender}}
TransformerDescription
hl7GenderHL7 gender \rightarrow FHIR gender
hl7DateHL7 date \rightarrow FHIR date
hl7DateTimeHL7 timestamp \rightarrow ISO datetime
hl7PatientClassHL7 patient class \rightarrow FHIR encounter class
toBooleanConverts Y/N or 1/0 to boolean
toNumberConverts string (including , to . correction) to number.
uppercaseConverts string to uppercase.
lowercaseConverts string to lowercase.
trimRemoves spaces at the beginning and end.

Examples

Example with multiple operations

    {
"content": {
"operations": [
{
"type": "createResource",
"options": {
"mapping": {
"gender": "{{PID-8|hl7Gender}}",
"name[0].family": "{{PID-5-1}}",
"name[0].given[0]": "{{PID-5-2}}",
"identifier[0].value": "{{PID-3-1}}",
"identifier[0].system": "{{PID-3-5}}"
},
"fhirType": "Patient"
},
"storeAs": "%patient%",
"isCritical": true
},
{
"type": "createResource",
"options": {
"mapping": {
"status": "in-progress",
"class.code": "{{PV1-2|hl7PatientClass}}",
"class.system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
"period.start": "{{PV1-44|hl7DateTime}}",
"subject.reference": "Patient/%patient.id%",
"identifier[0].value": "{{PV1-19-1}}",
"identifier[0].system": "{{PV1-19-4}}"
},
"fhirType": "Encounter"
},
"storeAs": "%encounter%",
"isCritical": false
}
]
},
"meta": {
"hl7_event": "ADT^A01"
},
"id": "85e50210-c27c-4eb0-94fc-267ecc557350",
"name": "ADT^A01^Default",
"scope": "global",
"scopeId": null,
"tenantId": "mona-default",
"type": "hl7",
"createdAt": "2026-03-10T10:53:12.458Z",
"createdBy": null,
"updatedAt": "2026-03-10T10:53:12.458Z",
"updatedBy": null,
"deletedAt": null,
"deletedBy": null,
"version": 1
},

In this example:

  • First a Patient resource is created
  • HL7 fields are mapped declaratively to FHIR elements
  • The resulting resource is stored as %patient%
  • Processing stops if this operation fails
  • Second an Encounter resource is created with the reference to the new created patient in the first step

Example with iterate

    {
"content": {
"operations": [
{
"type": "loadResource",
"options": {
"search": "identifier={{PID-3-1}}",
"fhirType": "Patient"
},
"storeAs": "patient"
"isCritical": true
},
{
"type": "loadResource",
"options": {
"search": "identifier={{PV1-19}}",
"fhirType": "Encounter"
},
"storeAs": "encounter"
"isCritical": true
},
{
"type": "createResource",
"options": {
"hl7Type": "OBX",
"mapping": {
"status": "final",
"effectiveDateTime": "{{now}}",
"subject.reference": "Patient/%patient%.id",
"valueQuantity.code": "{{OBX-6-1}}",
"valueQuantity.unit": "{{OBX-6-2}}",
"code.coding[0].code": "{{OBX-3-1}}",
"encounter.reference": "Encounter/%encounter%.id",
"valueQuantity.value": "{{OBX-5|toNumber}}",
"valueQuantity.system": "http://unitsofmeasure.org",
"code.coding[0].system": "http://loinc.org",
"code.coding[0].display": "{{OBX-3-2}}"
},
"fhirType": "Observation",
"createEach": true
},
"segment": {
"hl7Type": "OBX",
"iterate": true
},
"isCritical": false
}
]
},
"meta": {
"hl7_event": "ORU^R01"
},
"id": "fd081de3-c151-49c5-98aa-09856ce379d1",
"name": "ORU^R01^Default",
"scope": "global",
"scopeId": null,
"tenantId": "mona-default",
"type": "hl7",
"createdAt": "2026-03-10T10:54:35.176Z",
"createdBy": null,
"updatedAt": "2026-03-10T10:56:54.144Z",
"updatedBy": null,
"deletedAt": null,
"deletedBy": null,
"version": 2
}

In this example:

  • The patient must be loaded
  • The encounter must be loaded
  • For every OBX Segment an observation will stored. With the loaded patientId and the encounterId