EHDS Sandbox

Health Tech Companies · healthtech-interoperability

Interoperability requirements — the round trip, live

Each step below ran just now against the sandbox. Links open the real resources.

  1. done Form, response and patient in the exchange layer in hapi-fhir

    A blood-pressure Questionnaire (as the Form Builder would publish it) and a completed QuestionnaireResponse (as LForms would submit it), for a synthetic patient.

    Open in the sandbox →

  2. done Observation extracted from the response in hapi-fhir

    SDC extraction: the two answers become one Observation with systolic and diastolic components (LOINC 8480-6 / 8462-4). Done server-side here; LForms can do it in the browser.

    Open in the sandbox →

    Show payload
    {
      "resourceType": "Observation",
      "id": "ehds-uc08-bp",
      "status": "final",
      "code": {
        "coding": [
          {
            "system": "http://loinc.org",
            "code": "85354-9",
            "display": "Blood pressure panel"
          }
        ]
      },
      "subject": {
        "reference": "Patient/ehds-uc08-patient"
      },
      "effectiveDateTime": "2026-09-18T09:00:00Z",
      "derivedFrom": [
        {
          "reference": "QuestionnaireResponse/ehds-uc08-bp-response"
        }
      ],
      "component": [
        {
          "code": {
            "coding": [
              {
                "system": "http://loinc.org",
                "code": "8480-6",
                "display": "Systolic blood pressure"
              }
            ]
          },
          "valueQuantity": {
            "value": 128,
            "unit": "mm[Hg]",
            "system": "http://unitsofmeasure.org",
            "code": "mm[Hg]"
          }
        },
        {
          "code": {
            "coding": [
              {
                "system": "http://loinc.org",
                "code": "8462-4",
                "display": "Diastolic blood pressure"
              }
            ]
          },
          "valueQuantity": {
            "value": 82,
            "unit": "mm[Hg]",
            "system": "http://unitsofmeasure.org",
            "code": "mm[Hg]"
          }
        }
      ]
    }
  3. done Mapping definition loaded in openfhir

    The openEHR template plus a declarative FHIR Connect model and context mapping (shown in full below). Nothing is hand-coded per field.

    Open in the sandbox →

  4. done FHIR → openEHR in openfhir

    The Observation mapped into a FLAT openEHR composition of the Blood Pressure template.

    Show payload
    {
      "blood_pressure/blood_pressure/any_event:0/systolic|magnitude": 128.0,
      "blood_pressure/blood_pressure/any_event:0/systolic|unit": "mm[Hg]",
      "blood_pressure/blood_pressure/any_event:0/diastolic|magnitude": 82.0,
      "blood_pressure/blood_pressure/any_event:0/diastolic|unit": "mm[Hg]",
      "blood_pressure/blood_pressure/a24_hour_average/position|code": "at1000",
      "blood_pressure/blood_pressure/a24_hour_average/confounding_factors": "confounding factor",
      "ctx/language": "en",
      "ctx/territory": "DE",
      "ctx/composer_name": "EHDS Sandbox seeder",
      "ctx/time": "2026-09-18T09:00:00Z",
      "blood_pressure/blood_pressure/any_event:0/time": "2026-09-18T09:00:00Z"
    }
  5. failed Stored in the openEHR CDR in ehrbase

    422 Client Error: Unprocessable Entity for url: https://cdr.sandbox.ehds.technicise.eu/ehrbase/rest/openehr/v1/ehr/3240c9d5-ce9b-414e-aa06-ec0c8ffbe96b/composition?templateId=Blood+Pressure

The mapping definition

FHIR Connect — declarative and reviewable. This is the whole bridge between the two standards for this template.

context + model mapping (YAML)
engine: FHIRConnect/v0.0.1
type: context
metadata:
  name:  "Blood Pressure"
  version: 0.0.1a # version of this particular mapping
spec: # schema specific to the FHIRConnect v0.0.1 engine
  system: FHIR
  version: R4

context:
  profileUrl: "Observation"
  templateId: "Blood Pressure"
  archetypes:
    - "openEHR-EHR-OBSERVATION.blood_pressure.v2"
  start: "openEHR-EHR-OBSERVATION.blood_pressure.v2"


# ---- model mapping ----
#  Copyright 2022 Better Ltd (www.better.care)
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at

engine: FHIRConnect/v0.0.1
type: model
metadata:
  name:  openEHR-EHR-OBSERVATION.blood_pressure.v2
  version: 0.0.1a # version of this particular mapping
spec: # schema specific to the FHIRConnect v0.0.1 engine
  system: FHIR
  version: R4
  openEhrConfig:
    archetype: openEHR-EHR-OBSERVATION.blood_pressure.v2
  fhirConfig:
    structureDefinition: http://hl7.org/fhir/StructureDefinition/Observation

# Actual mapping points:
mappings:
  # Each mapping has a unique (self documenting) name.
  - name: "patient"
    # A simple mapping, which maps one attribute to another.
    with:
      # Access the FHIR resource, either in input or output direction.
      fhir: "$resource.subject.reference"
      # Some context variable are necessary to be accessible from the mapping.
      openehr: "$archetype.$ehr"

  # Another mapping which maps on a met condition. This condition is used to identify
  # the correct "component" in the FHIR resource (array).
  - name: "systolic"
    with:
      fhir: "$resource.component.value"
      openehr: "$archetype/data[at0001]/events[at0006]/data[at0003]/items[at0004]"
      type: "QUANTITY"
    fhirCondition:
      # One of the codings has to be the matching LOINC or SNOMED code.
      # incl. implicit handling of arrays, as ".coding" is a set of codings.
      # -> Here the backwards direction is ambiguous. The program will interpret "one of"
      # as "put those in the target resource" if the direction is openEHR->FHIR.
      targetRoot: "$resource.component"                       # Scope of object for 'condition'
      targetAttribute: "code.coding.code" # Actual attribute to check for 'condition'
      operator: "one of"
      criteria: "[$loinc.8480-6, $snomed.271649006]"
      identifying: true                                           # The *one* condition able to identify FHIR input to match this mapping
    # The next step allows a mapping to have a list of succeeding mappings, which
    # are executed in the same scope of the parent mapping.

  - name: "diastolic"
    with:
      fhir: "$resource.component.value"
      openehr: "$archetype/data[at0001]/events[at0006]/data[at0003]/items[at0005]"
      type: "QUANTITY"
    fhirCondition:
      targetRoot: "$resource.component"                       # Scope of object for 'condition'
      targetAttribute: "code.coding.code" # Actual attribute to check for 'condition'
      operator: "one of"
      criteria: "[$loinc.8462-4]"

  - name: "clinical interpretation"
    with:
      fhir: "$resource.component.interpretation.text"
      openehr: "$archetype/data[at0001]/events[at0006]/data[at0003]/items[at1059]"
      type: "STRING"

  - name: "description"
    with:
      fhir: "$resource.code.text"
      openehr: "$archetype/data[at0001]/events[at0006]/data[at0003]/items[at0033]"
      type: "STRING"

  - name: "position hardcoded to openehr"
    with:
      openehr: "$archetype/data[at0001]/events[at1042]/state[at0007]/items[at0008]|code"
      value: "at1000"
      type: "STRING"

  - name: "confounding_factors hardcoded to openehr"
    with:
      openehr: "$archetype/data[at0001]/events[at1042]/state[at0007]/items[at1052]"
      value: "confounding factor"
      type: "STRING"

  - name: "performer hardcoded in fhir"
    with:
      fhir: "$resource.performer.as(Reference).display"
      value: "John Doe"
      type: "STRING"

  - name: "location"
    with:
      fhir: "$resource.bodySite.coding"
      openehr: "$archetype/protocol[at0011]/items[at0014]"
      type: "CODING"
    fhirCondition:
      targetRoot: "$resource.bodySite"
      targetAttribute: "text"
      operator: "one of"
      criteria: "[THIS IS LOCATION OF MEASUREMENT]"

Staged records: Patient/ehds-uc08-patient, Questionnaire/ehds-uc08-bp, QuestionnaireResponse/ehds-uc08-bp-response, Observation/ehds-uc08-bp, openFHIR mapping openEHR-EHR-OBSERVATION.blood_pressure.v2

← Back to Interoperability requirements Run it again