Skip to main content

HL7 Configuration

The HL7 configuration is a standard configuration object managed via the Configuration API. Within this framework, it is specifically identified by its type and consumed by the HL7 parser. This document details the internal structure and properties of the HL7 configuration content, explaining how it enables the parser to transform incoming HL7 messages into FHIR resources at runtime.

Configuration Model Overview

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

Key Fields

  • type Identifies the configuration domain. HL7 configurations use type = "hl7".

  • tenantId Identifies the tenant (e.g. hospital or system) this configuration belongs to. This field is mandatory for tenant-specific routing and isolation.

  • meta A flexible JSON object used for message-level matching, such as HL7 event types.

  • content Contains the ordered list of HL7 operations executed by the worker.

Configuration Lookup & Resolution

At runtime, the HL7 worker resolves configurations dynamically based on message context.

Lookup Criteria

Configurations are queried using the following attributes:

  • type (must be hl7)
  • tenantId (hospital identifier)
  • meta filters

Metadata-Based Matching

The meta field plays a critical role in configuration resolution.

Example:

{
"hl7_event": "ADT^A01"
}

This allows the worker to select different configurations for different HL7 events without hardcoded routing logic. The hl7 event type is inside the hl7-message.

Operation Definition Fields

This section describes the operation-level fields used inside an HL7 configuration. These fields define what the HL7 worker does, how data is transformed, and how results are shared between operations during execution.

Operations are processed sequentially, from top to bottom, and may depend on results created by previous operations.

type

The type field serves as a discriminator that defines the execution logic for the operation block. It determines the specific action the worker performs. For example, a createResource type instructs the worker to execute a FHIR POST request, while an updateResource type triggers a FHIR PUT request. Each type thus maps directly to predefined execution semantics and technical operations within the FHIR ecosystem.

Current values:

  • createResource, updateResource, loadResource

storeAs

When storeAs is defined, the created or resolved resource is placed into the execution context and can be reused by subsequent operations. Stored values can later be accessed via template references such as:

Patient/%patient.id%

Conceptually, storeAs behaves like a runtime variable shared across operations.

isCritical

Controls error-handling behavior for the operation.

  • If true, a failure in this operation will stop further processing of the HL7 message.
  • If false, the worker may continue processing remaining operations using a best-effort strategy.

This allows distinguishing between mandatory and optional processing steps.

options

The structure of options depends on the operation type. This allows the configuration to stay flexible.

options.fhirType

Specifies the FHIR resource type that will be created or manipulated. The value must match a valid FHIR resource name (e.g. Patient, Encounter).


options.createEach

Determines whether the worker should process every instance of a specific HL7 segment/group found in the message. If set to true, the worker iterates through all blocks matching the options.hl7Type (e.g., creating a separate FHIR Resource for every OBX segment) instead of only processing the first one.


options.hl7Type

Specifies the target HL7 segment or group type (e.g., 'OBX'). This field is mandatory when options.createEach is used, as it defines which repeating elements in the HL7 message should be mapped to individual FHIR resources.


options.mapping

Defines the field-level transformation from HL7 data to FHIR fields.

The mapping is a key-value structure where:

  • Keys represent FHIR element paths
  • Values are expressions derived from HL7 segments

Mapping expressions support:

  • HL7 segment and field access (e.g. PID.patientName.familyName.surname). Needs to be written inside {{}}
  • Custom parsers and transformers (e.g. |hl7Gender, |hl7DateTime) (see below)
  • Static values

This approach enables declarative, readable, and testable transformation logic. Keep in mind that only fields in the mapping will be saved/updated though the hl7 message may include more information.

Examples:

{
"gender": "{{PID.administrativeSex.identifier|hl7Gender}}",
"address[0].postalCode": "{{PID.patientAddress[0].zipOrPostalCode}}",
"status": "in-progress",
"subject.reference": "Patient/%patient.id%",
}

Execution Semantics

  • Operations are executed in order as defined in the configuration
  • Later operations may depend on resources created earlier
  • Variable references are resolved at runtime from the execution context

Custom HL7 Transformers

HL7 mappings support custom parsers and transformers that can be applied inline within mapping expressions to ensure a valid FHIR payload.

Usage

Parsers are applied using a pipe syntax:

{{PID.administrativeSex.identifier|hl7Gender}}

Current Transformers

  • hl7Gender – convert HL7 gender code to FHIR gender code
  • hl7Date – converts HL7 date fields (YYYYMMDD) to FHIR date format (YYYY-MM-DD)
  • hl7DateTime – converts HL7 timestamps to ISO date-time strings
  • hl7PatientClass – maps patient class codes to FHIR encounter classes
  • toBoolean – converts to boolean ("Y" -> true, "N" -> false, "1" -> true, "0" -> false)

New parsers can be added without changing existing configurations.

Example

[
{
"content": {
"operations": [
{
"type": "createResource",
"options": {
"mapping": {
"gender": "{{PID.administrativeSex.identifier|hl7Gender}}",
"birthDate": "{{PID.dateTimeOfBirth|hl7Date}}",
"address[0].use": "home",
"name[0].family": "{{PID.patientName.familyName.surname}}",
"address[0].city": "{{PID.patientAddress[0].city}}",
"name[0].given[0]": "{{PID.patientName.givenName}}",
"address[0].country": "{{PID.patientAddress[0].country}}",
"address[0].line[0]": "{{PID.patientAddress[0].streetAddress.streetOrMailingAddress}}",
"identifier[0].value": "{{PID.patientIdentifierList.idNumber}}",
"identifier[0].system": "{{PID.patientIdentifierList.identifierTypeCode}}",
"address[0].postalCode": "{{PID.patientAddress[0].zipOrPostalCode}}"
},
"fhirType": "Patient"
},
"storeAs": "%patient%",
"isCritical": true
},
{
"type": "createResource",
"options": {
"mapping": {
"status": "in-progress",
"class.code": "{{PV1.patientClass.identifier|hl7PatientClass}}",
"class.system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
"period.start": "{{PV1.admitDateTime|hl7DateTime}}",
"subject.reference": "Patient/%patient.id%",
"identifier[0].value": "{{PV1.visitNumber.idNumber}}",
"identifier[0].system": "{{PV1.visitNumber.assigningAuthority.nameSpaceId}}"
},
"fhirType": "Encounter"
},
"storeAs": "%encounter%",
"isCritical": false
}
]
},
"meta": {
"hl7_event": "ADT^A01"
},
"id": "2396b50b-c8ab-4531-9c9f-cb162b083508",
"name": "hl7-adt-ao1",
"scope": "global",
"scopeId": null,
"tenantId": "mona-system",
"type": "hl7",
"createdAt": "2026-01-28T12:30:31.926Z",
"createdBy": null,
"updatedAt": "2026-01-28T14:11:00.073Z",
"updatedBy": null,
"deletedAt": null,
"deletedBy": null,
"version": 5
}
]

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