Inera Core Implementation Guide
0.2.0 - ci-build
Sweden
Inera Core Implementation Guide - Local Development build (v0.2.0) built by the FHIR (HL7® FHIR® Standard) Build Tools. See the Directory of published versions
This page describes the overall strategy for mapping Swedish RIVTA/TKB (Tjänstekontrakt) services to FHIR REST APIs. The mapping addresses both structural transformation (document-oriented to resource-oriented) and semantic alignment (Swedish healthcare concepts to FHIR information model).
TKB services use a header/body pattern with SOAP/XML, while FHIR uses RESTful resources with distributed metadata. For architectural transition strategies and coexistence patterns, see the Migration Guide.
This page focuses on technical mapping details for transforming TKB data structures to FHIR resources.
The transformation occurs across four distinct layers:
| Aspect | TKB | FHIR |
|---|---|---|
| Protocol | SOAP 1.1/1.2 | HTTP REST |
| Data Format | XML | JSON (primary), XML (optional) |
| Service Discovery | WSDL | CapabilityStatement |
| Operations | GetX, ProcessX | read, search, create, update, delete |
| Error Handling | SOAP Fault | OperationOutcome |
Example Transformation:
<!-- TKB Request -->
<GetDiagnosisRequest>
<patientId>191212121212</patientId>
<timePeriod>
<start>2024-01-01</start>
<end>2024-12-31</end>
</timePeriod>
</GetDiagnosisRequest>
// FHIR Request
GET /Condition?patient.identifier=https://terminology.hl7.se/sid/se-personnummer|191212121212
&onset-date=ge2024-01-01
&onset-date=le2024-12-31
&_revinclude=Provenance:target
TKB uses a header/body pattern with centralized metadata. FHIR distributes metadata across resources.
| TKB Component | FHIR Mapping | Rationale |
|---|---|---|
| PatientSummaryHeader.patientId | Each resource.subject | Distributed patient reference |
| Header.accountableHealthcareProfessional | Resource.recorder + Provenance.agent | Dual representation |
| Header.careUnitHSAId | Provenance.agent.onBehalfOf | Organizational context |
| Header.sourceSystemHSAId | Resource.meta.source | System provenance |
| Header.authorTime | Resource.meta.lastUpdated + Provenance.recorded | Temporal tracking |
| Body (array of clinical data) | Individual FHIR resources | Granular resources |
ConceptMap Approach:
Each TKB service is documented with a detailed ConceptMap:
Instance: ConceptMapGetDiagnosisTKBToCondition
InstanceOf: ConceptMap
* group[0].element[0].code = #GetDiagnosisResponse.patientId
* group[0].element[0].target[0].code = #subject
* group[0].element[0].target[0].equivalence = #equivalent
* group[0].element[0].target[0].comment = "Reference to Patient resource"
Swedish healthcare concepts are mapped to FHIR terminology bindings:
| Swedish Concept | TKB Code System | FHIR Mapping | FHIR URI |
|---|---|---|---|
| Diagnoskod | ICD-10-SE (1.2.752.116.1.1.1) | Condition.code | http://terminology.hl7.se/CodeSystem/icd-10-se |
| Läkemedel | ATC (1.2.752.129.2.2.3.1.1) | Medication.code | http://www.whocc.no/atc |
| Läkemedelsprodukt | NPL (1.2.752.129.2.1.5.1) | Medication.code | https://inera.se/fhir/core/CodeSystem/npl |
| Åtgärd | KVÅ (1.2.752.129.2.2.2.1) | Procedure.code | https://inera.se/fhir/core/CodeSystem/kva |
| Analys | NPU (1.2.752.108.1.1.1) | Observation.code | http://npu-terminology.org |
OID to URI Transformation:
Many TKB services use OID-based code system identifiers. These must be converted to URIs:
OID_TO_URI_MAP = {
"1.2.752.116.1.1.1": "http://terminology.hl7.se/CodeSystem/icd-10-se",
"2.16.840.1.113883.6.1": "http://loinc.org",
"2.16.840.1.113883.6.96": "http://snomed.info/sct",
"1.2.752.129.2.2.3.1.1": "http://www.whocc.no/atc",
}
TKB service behaviors map to FHIR interaction patterns:
| TKB Operation | FHIR Interaction | Notes |
|---|---|---|
| GetX | GET /Resource?... |
Search with parameters |
| GetXById | GET /Resource/{id} |
Direct read |
| ProcessX (create) | POST /Resource |
Create new resource |
| ProcessX (update) | PUT /Resource/{id} |
Update existing |
| ProcessX (delete) | DELETE /Resource/{id} |
Soft delete (status change) |
| Subscribe | Subscription resource | Push notifications |
Example: GetDiagnosis → Condition Search
TKB: GetDiagnosis(patientId, timePeriod, careUnitHSAId)
↓
FHIR: GET /Condition?patient={ref}
&onset-date=ge{start}
&onset-date=le{end}
&recorder.identifier={hsaid}
&_revinclude=Provenance:target
A key design decision is how to handle TKB header metadata. We use a dual-track approach:
For basic use cases, essential metadata is embedded in the resource:
{
"resourceType": "Condition",
"meta": {
"lastUpdated": "2025-11-24T10:00:00+01:00",
"source": "https://hsaid.se/SE2321000016-SYS001",
"profile": ["https://inera.se/fhir/core/StructureDefinition/ConditionDiagnosisInera"]
},
"recorder": {
"identifier": {
"system": "https://hsaid.se",
"value": "SE2321000016-123456"
}
}
}
For full TKB header fidelity, create a linked Provenance resource:
{
"resourceType": "Provenance",
"target": [{"reference": "Condition/123"}],
"recorded": "2025-11-24T10:00:00+01:00",
"agent": [{
"type": {"coding": [{"code": "author"}]},
"who": {"identifier": {"value": "SE2321000016-123456"}},
"onBehalfOf": {"identifier": {"value": "SE2321000016-A001"}}
}],
"entity": [{
"role": "source",
"what": {"identifier": {"value": "SE2321000016-0000"}}
}]
}
When to use each track:
| Use Case | Resource Metadata | Provenance |
|---|---|---|
| Basic read/search | ✓ Sufficient | Optional |
| Audit trail required | ✓ Basic | ✓ Required |
| Legal signatures | ✓ Basic | ✓ Required with signature |
| Cross-organization exchange | ✓ Basic | ✓ Recommended |
| Patient-facing apps | ✓ Sufficient | Not needed |
See TKB Header Mapping for detailed guidance.
TKB service inputs (request parameters) map to FHIR search parameters:
| TKB Parameter | Type | FHIR Search Parameter | Notes |
|---|---|---|---|
| patientId | Swedish ID | patient.identifier |
Use personnummer system |
| timePeriod.start | Date | effective-date=ge |
Greater or equal |
| timePeriod.end | Date | effective-date=le |
Less or equal |
| medicationId | NPL ID | code |
NPL code system |
| status | Code | status |
Map Swedish codes |
Composite Search:
GET /MedicationStatement?patient.identifier=https://terminology.hl7.se/sid/se-personnummer|191212121212
&effective-date=ge2024-01-01
&effective-date=le2024-12-31
&status=active
&_include=MedicationStatement:medication
&_revinclude=Provenance:target
TKB uses various temporal concepts that map to different FHIR elements:
| TKB Temporal Concept | FHIR Mapping | Resource Examples |
|---|---|---|
| Diagnosis time | onsetDateTime |
Condition |
| Observation time | effectiveDateTime |
Observation |
| Treatment period | effectivePeriod.start/end |
MedicationStatement |
| Registration time | issued |
Observation, DiagnosticReport |
| Author time | meta.lastUpdated + Provenance.recorded |
All resources |
| Validity period | period |
Flag, Consent |
Example Transformation:
<!-- TKB -->
<diagnosis>
<diagnosisTime>2024-11-15</diagnosisTime>
<registeredTime>2024-11-15T14:30:00</registeredTime>
</diagnosis>
// FHIR
{
"resourceType": "Condition",
"onsetDateTime": "2024-11-15",
"recordedDate": "2024-11-15",
"meta": {
"lastUpdated": "2024-11-15T14:30:00+01:00"
}
}
Many TKB services include status fields that map to FHIR status elements:
| TKB Diagnosis Status | FHIR clinicalStatus | Comment |
|---|---|---|
| Aktiv | active | Currently relevant |
| Åtgärdad | resolved | No longer active |
| Inaktiv | inactive | Not currently active |
| Historisk | inactive | Past condition |
| TKB Result Status | FHIR status | Comment |
|---|---|---|
| Registrerad | registered | Entered but not verified |
| Preliminär | preliminary | Initial results |
| Slutgiltig | final | Verified and complete |
| Korrigerad | amended | Modified after final |
| Makulerad | cancelled | Should not have been done |
TKB uses identifiers (HSA-ID, care contact ID, etc.) that become FHIR references:
{
"subject": {
"reference": "Patient/191212121212",
"type": "Patient"
}
}
{
"recorder": {
"identifier": {
"system": "https://hsaid.se",
"value": "SE2321000016-123456"
},
"display": "Dr. Anna Andersson"
}
}
{
"resourceType": "MedicationStatement",
"contained": [{
"resourceType": "Medication",
"id": "med1",
"code": {
"coding": [{
"system": "https://inera.se/fhir/core/CodeSystem/npl",
"code": "123456"
}]
}
}],
"medicationReference": {
"reference": "#med1"
}
}
Elements marked as mustSupport in profiles must be:
All coded elements should validate against specified ValueSets:
* code from ICD10SEDiagnosisCodes (preferred)
* severity from ConditionSeverity (required)
Servers should declare support via CapabilityStatement:
{
"resourceType": "CapabilityStatement",
"rest": [{
"mode": "server",
"resource": [{
"type": "Condition",
"profile": "https://inera.se/fhir/core/StructureDefinition/ConditionDiagnosisInera",
"searchParam": [
{"name": "patient", "type": "reference"},
{"name": "onset-date", "type": "date"},
{"name": "code", "type": "token"}
]
}]
}]
}
For architectural transition patterns (Façade, Dual-Native, Mirror, FHIR-Native) and system-specific recommendations, see the Migration Guide.
The TKB to FHIR mapping strategy emphasizes:
For specific service mappings, see the ConceptMaps section.