Healthcare/Kanta, Nordics
National program

Finland's Kanta and Nordic FHIR migration

The Nordics run some of the oldest national health data systems in the world, and all four are migrating them toward FHIR - each from a different starting point.

4lands covered
R4target FHIR version
2029EHDS exchange deadline
kanta_bridge.py
# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

class KantaBridge(Service):
    name = 'demo.nordics.kanta-bridge'

    def handle(self) -> 'None':

        # A FHIR R4 endpoint during the transition
        client = self.fhir['FHIR.Kanta']

        # Finnish personal identity codes are
        # identifiers in their national system
        patient = client.resources('Patient').search(
            identifier = 'urn:oid:1.2.246.21|010180-9026',
        ).first()

        self.logger.info('Found %s', patient['id'])

Where does each Nordic land stand on FHIR?

All four are moving to FHIR R4, each from a different legacy standard, and the existing systems stay in service while they do.

LandNational systemLegacy standardFHIR status
FinlandKanta - prescriptions and patient data since 2007HL7 v3, CDA R2 documentsFHIR APIs arriving alongside v3, e.g. the Kanta PHR on FHIR
DenmarkMedCom messaging between all healthcare partiesOIOXML and EDIFACT messagesMedCom FHIR messaging replacing them programme by programme
SwedenNational e-health infrastructure via IneraRIVTA service contractsSwedish base profiles on FHIR R4
NorwayHelsenettet and national e-health servicesKITH XML messagesno-basis base profiles on FHIR R4

The EHDS deadlines apply across all four - patient summaries and e-prescriptions flowing through MyHealth@EU by March 2029 - as the EHDS checklist lays out, so the national migrations and the European one both target FHIR R4.

What does the Kanta transition mean for integrations?

Kanta is one of the longest-running national systems in the world - electronic prescriptions and the patient data repository run on HL7 v3 messaging and CDA R2 documents, standards that are being phased out internationally. Kelain and the Kanta PHR introduced FHIR interfaces, and new work follows the FHIR direction while the v3 core keeps operating.

For integration teams this means a long transition with both stacks live - systems that post CDA documents to Kanta run next to systems that consume FHIR from the newer interfaces, and an integration layer converts between the two, so each application keeps using its own format.

What is MedCom's FHIR migration?

Danish healthcare messaging runs through MedCom standards connecting general practice, hospitals, municipalities and laboratories - historically OIOXML and EDIFACT messages. MedCom is replacing them with FHIR messaging standard by standard - hospital notifications, municipal care communication and onward - each migration a translation project between a legacy message format and FHIR resources.

Each such translation receives the original format, maps it and sends FHIR - the same receive, map and send steps as in the HL7 v2 to FHIR mapping, applied to a different source format.

How do I bridge legacy formats to FHIR from Python?

Every Nordic bridge works like the service below - a legacy message arrives over a channel, Python maps it and a FHIR server receives the result. Here the source is an HL7 v2 feed from a hospital system, the pattern is identical when the source is a MedCom message, and a CDA document needs no mapping at all - one call converts it to a FHIR bundle.

nordic_bridge.py
# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

# The Finnish personal identity code system
hetu_system = 'urn:oid:1.2.246.21'

class NordicBridge(Service):
    name = 'demo.nordics.bridge'

    def handle(self) -> 'None':

        # A legacy feed, parsed by its channel ..
        msg = self.request.input

        # .. the national identifier and demographics ..
        hetu = msg.pid.patient_identifier_list.id_number
        family_name = msg.pid.patient_name.family_name

        # .. become a FHIR Patient with the national identifier.
        client = self.fhir['FHIR.Kanta']

        patient = client.resource('Patient',
            identifier = [{'system': hetu_system, 'value': hetu}],
            name = [{'family': family_name}],
        )

        patient.save()

National profiles put their specifics into identifiers, extensions and slices, and path access with matchers reads them by their system rather than by their position.

Frequently asked questions

No - HL7 International's current standard is FHIR, and v3 messaging remains in use mainly inside national systems built during its era, Kanta being the prominent example. Those systems will keep running for years, and integrations have to work with them throughout the transition.

Yes - hospital-internal traffic, laboratory and imaging feeds run on HL7 v2 across the region even where national messaging uses other standards, so MLLP channels are still needed.

Iceland participates in the Nordic and European work - including MyHealth@EU - with its national system Hekla, and the same EHDS timeline applies to it as an EEA member implementing the framework.

EDIFACT yes - the platform ships a typed EDIFACT engine, described in the EDIFACT developer guides, which is directly relevant to MedCom's legacy traffic. CDA yes - a service converts a C-CDA document to a FHIR bundle with one call, and the HL7 v2 and FHIR sides are covered by the built-in support.

Ready for the Nordic FHIR transition?

Get started with Zato and bridge your first legacy feed to FHIR in minutes.

Open source In Python