T2med FHIR-APIT2med FHIR-API
Start
Funktionsumfang
Leitfaden
API-Referenz
Roadmap
Demo-Anwendung
FAQs
Kontakt
Start
Funktionsumfang
Leitfaden
API-Referenz
Roadmap
Demo-Anwendung
FAQs
Kontakt
  • Leitfaden

Leitfaden

Dieser Leitfaden beschreibt den praktischen Integrationsablauf für Drittanbieter gegen die T2med FHIR-API.

Version des zugrunde liegenden Integrationsleitfadens: 1.2 · Stand: 2026-10-29

VersionStandÄnderung
1.02026-06-15Aktueller Stand des Integrationsleitfadens
1.12026-10-28Ergänzt: Kontext per API anlegen (POST /Encounter, ab Version 26.10) und lesender Zugriff auf die eAkte ($eakte, ab Version 26.11). Interne Verweise korrigiert.
1.22026-10-29Abgleich mit APS 26.11: einheitliche Schreibweise der Pfade, Profil-, Extension- und Identifier-URLs; Diagnose-Relevanz korrekt als Extension dokumentiert.

Zielbild und Grundprinzip

Die Integration ist kontextbasiert:

  1. Die Drittanbieter-Software wird durch Nutzerinteraktion aus dem APS-Client heraus per Deep Link aufgerufen. Dafür wird im APS ein temporärer Kontext erstellt.
  2. Der Drittanbieter ruft die FHIR-API mit X-API-Key auf.
  3. Der Drittanbieter übergibt die kontextId als FHIR-Identifier oder als Encounter-Referenz in kontextgebundenen Ressourcen.
  4. APS ordnet die Daten dem Kontext zu und schreibt sie in die Fachdomäne.
ThemaVorgabe
Kontext-Identifiersystem=https://fhir.t2med.de/identifier/kontext, value=<kontextId>
Encounter-ReferenzEncounter/<kontextId>
KontextdauerKontexte werden bis zu 4 Stunden vorgehalten und stündlich bereinigt.
KontextpflichtKontextgebundene create-Operationen und GET /Patient?identifier=... benötigen einen gültigen Kontext.

Neben diesem klassischen Deep-Link-Pfad gibt es einen zweiten Einstieg über den OAuth Device Flow, wenn der Drittanbieter-Client ohne vorherigen Deep-Link-Aufruf ein Access-Token benötigt.

Voraussetzungen

Serverseitig (APS)

VoraussetzungWert
FHIR-Servletunter /aps/fhir/api/r4 erreichbar
Drittanbieterin APS aktiviert

Drittanbieter-seitig

VoraussetzungErwartung
FHIR-ClientHTTPS-Client für FHIR R4
Lokale HTTPS-Endpunktelokale APS-Server-URLs werden unterstützt
Lokale Zertifikateinstallationsspezifische APS-Server-Zertifikate werden unterstützt
Pflichtheader serverseitigX-API-Key
Optionale ServerheaderX-TreatWarningAsError, X-FHIR-Profile
Optionale Client-HeaderAuthorization, Prefer, X-TreatWarningAsError, Content-Type
Deep-Link-ParameterkontextId, FHIRBasisUrl, oAuthToken
OAuth Client IDaus der APS-Drittanbieter-Definition (ClientId)
OAuth Scopeaktuell in APS festgelegt: t2med/aps/FHIR
FehlerformatOperationOutcome auswerten

Authentifizierung und Header

Serverseitig zwingend:

HeaderPflichtBedeutung
X-API-Key: <API_KEY>jaAPI-Key des aktivierten Drittanbieters.

Optionale, üblicherweise zusätzlich gesendete Header:

HeaderPflicht aus ServersichtBedeutung
Authorization: Bearer <oAuthToken>neinWird aus dem Deep-Link-Parameter oAuthToken (bzw. dem per Device Flow erhaltenen Access-Token) gebildet.
Prefer: return=OperationOutcomeneinSignalisiert, dass ein OperationOutcome als Create-Ergebnis erwartet wird.
X-TreatWarningAsError: trueneinWarnungen werden als Fehler behandelt.
Content-Type: application/fhir+xml; charset=UTF-8neinSetzt das Anfrageformat. Für JSON application/fhir+json verwenden.

Optionale FHIR-API-Header:

HeaderVerhalten
X-TreatWarningAsError: true|falsefehlt oder true ⇒ Warnungen werden als Fehler behandelt; false ⇒ Warnungen bleiben Warnungen.
X-FHIR-Profile: <profil-url>|1.0.0wird nur für Patient-Read und Patient-Search ausgewertet; ohne Header wird FhirApiPatient verwendet.
Accept: application/fhir+jsonsinnvoll für JSON-Antworten.

Wichtig

  • loginToken: wird von /aps/rest/FHIR/api/kontext/anlegen geliefert, wenn das aktivierte Produkt eine clientId hat.
  • oAuthToken: Parametername im Deep Link; enthält das loginToken aus der Kontext-Boundary.
  • Leerer Token: Wenn kein loginToken erzeugt wird, ersetzt der APS-Client ${oAuthToken} durch einen leeren Wert.
  • FHIRBasisUrl: Muss unverändert als Basis-URL des FHIR-Clients verwendet werden.

Typische Fehler bei der Authentifizierung:

HTTPBedeutung
403 ForbiddenAPI-Key fehlt oder ist ungültig.
503 Service UnavailableFHIR-API ist per Feature-Flag nicht freigeschaltet.

Hinweise aus der Kontext-Anlage:

FallVerhalten
Unbekanntes ProduktKontext-Anlage liefert Validierungsfehler.
Nicht aktiviertes ProduktKontext-Anlage liefert Validierungsfehler.
Aktiviertes Produkt ohne Auth-RegistrierungKontext wird angelegt, loginToken bleibt leer, es wird ein Info-Hinweis zurückgegeben.

OAuth Device Flow (RFC 8628)

Neben dem klassischen Deep-Link-Start mit fertigem Bearer-Token kann sich ein Drittanbieter auch eigenständig per OAuth 2.0 Device Flow am APS-Auth-Server authentifizieren. Dieser Pfad ist relevant, wenn der Drittanbieter-Client ohne vorherigen Deep-Link-Aufruf aus dem APS-Client heraus ein Access-Token benötigt.

Ablauf

Drittanbieter-Client                   Auth-Server                          Browser (Nutzer)
        |                                   |                                       |
        |-- POST /device_authorization ----->|                                       |
        |  Authorization: Basic             |                                       |
        |<-- device_code, user_code, -------|                                       |
        |  verification_uri_complete,       |                                       |
        |  expires_in, interval             |                                       |
        |                                   |                                       |
        |  zeigt user_code + URI -------------------------------------------------->| Nutzer öffnet URI
        |                                   |<-- Nutzer gibt user_code ein ---------|
        |                                   |                                       |
        |-- POST /token (polling) --------->|                                       |
        |  Authorization: Basic,            |                                       |
        |  grant_type=device_code           |                                       |
        |<-- authorization_pending ---------|                                       |
        |  (warten, erneut pollen)          |                                       |
        |-- POST /token (polling) --------->|                                       |
        |<-- access_token, token_type ------|                                       |
        |                                   |                                       |
        |  FHIR-Client initialisiert        |                                       |

Konfigurationsparameter

ParameterBeschreibung
deviceAuthUrlURL des Device Authorization Endpoint des APS-Auth-Servers. Standard: gleicher Host wie FHIRBasisUrl, Port 16596, Pfad /oauth2/device_authorization.
tokenUrlURL des Token Endpoint. Standard: gleicher Host wie FHIRBasisUrl, Port 16596, Pfad /oauth2/token.
clientIdOAuth Client ID aus der APS-Drittanbieter-Definition (ClientId).
clientSecretClient-Secret aus der APS-Drittanbieter-Einrichtung.
scopeOAuth Scope — aktuell in APS festgelegt: t2med/aps/FHIR.

Das Client-Secret wird im APS-Einrichtungsprozess für den Drittanbieter-Zugriff bereitgestellt. Der Drittanbieter-Client muss es vertraulich behandeln: nicht protokollieren und nur in einem sicheren Schlüsselspeicher vorhalten (siehe Sicherheit, Betrieb und Go-Live).

Client-Secret gehört in den Header, nicht in den Body

Die Client-Authentifizierung erfolgt bei allen Aufrufen (device_authorization, Token-Polling und Refresh) über den Header Authorization: Basic base64(client_id:client_secret). Das Client-Secret gehört nicht in den Request-Body — dieser enthält nur client_id und scope (bzw. beim Token-Aufruf grant_type und device_code). Wird das Secret im Body mitgesendet, lehnt der Auth-Server den Aufruf mit {"error":"invalid_client"} ab.

Polling-Verhalten

Server-AntwortBedeutungEmpfohlenes Verhalten des Clients
200 OK mit access_tokenAutorisierung erfolgreichAccess-Token übernehmen und FHIR-Client initialisieren
authorization_pendingNutzer hat noch nicht autorisiertWarten, erneut pollen
slow_downPolling zu häufigPolling-Intervall um mindestens 5 Sekunden erhöhen
expired_tokenDevice Code abgelaufenFehler anzeigen, Device Flow neu starten
access_deniedNutzer hat abgelehntFehler anzeigen

Ergebnis nach erfolgreichem Device Flow

Nach erfolgreichem Token-Erhalt kann der Client die FHIR-API mit dem erhaltenen Access-Token (Authorization: Bearer <access_token>) identisch zum klassischen Deep-Link-Pfad nutzen. Alle FHIR-Operationen stehen unverändert zur Verfügung.

Optional: Automatische Wiederverbindung per Refresh-Token

Liefert der Token-Endpoint einen refresh_token, kann ein Drittanbieter-Client diesen nutzen, um nach einem Neustart ohne erneute Browser-Autorisierung ein neues Access-Token zu beziehen (grant_type=refresh_token, Authorization: Basic aus Client ID und Client-Secret). Das Access-Token selbst ist kurzlebig und sollte nicht dauerhaft gespeichert werden. Ist der Refresh-Token abgelaufen oder ungültig, muss der Device Flow erneut durchlaufen werden.

Sicherheitshinweis

Wenn der Client Refresh-Token und Client-Secret für eine spätere Wiederverbindung vorhält, gehören diese Geheimnisse in einen sicheren Schlüsselspeicher (z. B. OS-Keychain), nicht in eine Klartext-Datei.

Minimalfluss (Variante B)

  1. POST <deviceAuthUrl> mit Header Authorization: Basic base64(client_id:client_secret); im Body (Form-Encoded) nur client_id und scope.
  2. device_code, user_code, verification_uri_complete (Fallback: verification_uri), expires_in und interval aus der Response lesen.
  3. user_code und verification_uri_complete dem Nutzer anzeigen.
  4. Polling: POST <tokenUrl> mit demselben Authorization: Basic-Header; im Body grant_type=urn:ietf:params:oauth:grant-type:device_code, device_code und client_id — alle interval Sekunden.
  5. Bei authorization_pending: warten und erneut pollen. Bei slow_down: Intervall um 5 Sekunden erhöhen.
  6. Bei 200 OK mit access_token: Token übernehmen, FHIR-Client wie im Deep-Link-Pfad initialisieren.
  7. Ab hier identisch zum Deep-Link-Pfad: FHIR-Operationen mit Authorization: Bearer <access_token> ausführen.

Eine lauffähige Referenzimplementierung dieses Flows (inklusive Persistenz und automatischer Wiederverbindung) zeigt die Demo-Anwendung.

Endpunkte und Integrationsablauf

Endpunktübersicht (Drittanbietersicht)

Externe FHIR-API:

ThemaWert
Basis/aps/fhir/api/r4
Format in BeispielenFHIR JSON
Unterstützte Content-Typesapplication/fhir+json, application/fhir+xml

Ressourcen:

HTTPPfadUnterstützte Operation
POST/PatientPatient anlegen
GET/Patient?identifier=<system>|<value>Patient per Kontext-Identifier suchen
GET/Patient?family=...&given=...&birthdate=...Patient per Name/Geburtsdatum suchen
GET/Patient/{id}Patient lesen
PUT/Patient/{id}Patient aktualisieren
GET/Patient/{id}/$eakteeAkte des Patienten lesen, optional eingegrenzt auf einen Zeitraum (ab 26.11), siehe eAkte lesen
POST/Patient/{id}/$eaktewie GET, Parameter im Body als Parameters-Ressource (ab 26.11)
GET/Encounter/{id}Encounter aus Kontext lesen
POST/EncounterKontext anlegen (Device Flow, ab 26.10), siehe Kontext per API anlegen
GET/Organization/{id}Organisation lesen
GET/Organization?name=...&identifier=...Organisation nach Name/BSNR suchen
GET/Organization?practitioner=...Organisationen zu Practitioner suchen
GET/Practitioner/{id}Practitioner lesen
GET/Practitioner?name=...&identifier=...Practitioner nach Name/LANR suchen
GET/Organization/{id}/PractitionerImplementierungsnaher Compartment-Sonderfall — siehe Hinweis unten
POST/ObservationObservation anlegen
POST/ConditionDiagnose anlegen
POST/ProcedureTherapie oder Prozedere anlegen
POST/DocumentReferenceFreitext oder Anhang anlegen
GET/DocumentReference/{id}Referenz auf ein Dokument oder Bild aus der eAkte lesen (ab 26.11)
POST/FHIR-Transaction-Bundle

Sonderfall GET /Organization/{id}/Practitioner

Der Endpoint ist registriert, der aktuelle Handler interpretiert {id} aber als Practitioner-/Arztrollen-ID und gibt Organization-Ressourcen zurück. Für Drittanbieter ist GET /Organization?practitioner=<id> die fachlich klarere Variante.

Kontext-Management und Drittanbieter-Freischaltung erfolgen APS-intern unter /aps/rest/FHIR/api/... und sind nicht Teil der externen Drittanbieter-API.

Empfohlener Integrationsablauf (End-to-End)

Schritt 1: Kontext bereitstellen lassen

SchrittBeschreibung
KontextanlageAPS ruft intern /aps/rest/FHIR/api/kontext/anlegen auf.
Pflichtfelderhersteller, produkt, patientId, arztrolleId, behandlungsortId
Optionales FeldbehandlungsfallId
Responsekontext, aufrufUrlTemplate, FHIRApiBase, abhängig vom Produkt loginToken
Deep LinkAPS-Client ersetzt ${kontextId}, ${FHIRBasisUrl}, ${oAuthToken} im aufrufUrlTemplate.
oAuthTokenDer APS-Client befüllt den Parameter aus dem loginToken.
FHIRBasisUrlZusammengesetzt aus APS-Basis-URL und FHIRApiBase; unverändert im Drittanbieter-Client verwenden.

Beispiel für ein Template:

t2demo://?kontextId=${kontextId}&FHIRBasisUrl=${FHIRBasisUrl}&oAuthToken=${oAuthToken}

Schritt 2: Optional Patient laden oder validieren

ZweckRequest
KontextvalidierungGET /aps/fhir/api/r4/Patient?identifier=https://fhir.t2med.de/identifier/kontext|<KONTEXT_ID>
Header-ProfilX-FHIR-Profile: https://fhir.t2med.de/StructureDefinition/FhirApiPatient|1.0.0

Schritt 3: Fachdaten schreiben

Je nach Anwendungsfall:

RessourceAnwendungsfall
ObservationAnamnese, Befund oder Freitext
ConditionDiagnosen
ProcedureTherapie oder Prozedere
DocumentReferenceFreitext oder eingebetteter Anhang/Datei-Upload
PatientPatient anlegen oder aktualisieren

Für kontextgebundene Ressourcen gilt:

VarianteFHIR-Element
Kontext-Identifieridentifier.system = https://fhir.t2med.de/identifier/kontext, identifier.value = <KONTEXT_ID>
Encounter-Referenzencounter.reference = Encounter/<KONTEXT_ID>
Profilmeta.profile[0] muss ein unterstütztes Profil enthalten

Für eine enthaltene Encounter-Ressource gelten diese Referenz-Prefixe:

KontextbestandteilReferenz
PatientPatient/<patientObjectId>
BehandlungsfallEpisodeOfCare/<behandlungsfallObjectId>
ArztrollePractitioner/<arztrolleObjectId>
Behandlungsortaktueller Implementierungsstand: Organisation/<behandlungsortObjectId>

Für DocumentReference mit Profil FhirApiDocumentReferenceAnhang|1.0.0 gilt zusätzlich:

ElementVorgabe
descriptionPflicht
content[0].attachment.dataPflicht, Base64-kodierter Anhang
content[0].attachment.contentTypePflicht
content[0].attachment.titleoptional
Zeitpunktbevorzugt content[0].attachment.creation, ersatzweise DocumentReference.date
Kürzeloptional über https://fhir.t2med.de/StructureDefinition/FhirApiAnhangKuerzel

Schritt 4: Optional als Transaction bündeln

ThemaVorgabe
EndpointPOST /aps/fhir/api/r4
BundleBundle.type = transaction
Entry-Methodenur request.method = POST implementiert
Entry-URLrelative Resource-Namen wie Observation oder Condition
RollbackBei error oder fatal in einem Entry-OperationOutcome wird die Gesamttransaktion auf Rollback markiert.

Schritt 5: Kontextabschluss

SchrittBeschreibung
EntfernenKontext kann über /aps/rest/FHIR/api/kontext/entfernen entfernt werden.
WiederverwendungKontext-IDs nicht wiederverwenden.

Schnellstart (Minimalfluss, Deep-Link-Pfad)

  1. Deep Link auswerten und kontextId, FHIRBasisUrl, oAuthToken übernehmen.
  2. HTTPS-Client für FHIRBasisUrl mit passender SSL-Konfiguration initialisieren.
  3. X-API-Key bei jedem FHIR-Aufruf mitsenden.
  4. Optional Authorization: Bearer <oAuthToken>, Prefer: return=OperationOutcome und X-TreatWarningAsError: true mitsenden.
  5. GET /Patient?identifier=https://fhir.t2med.de/identifier/kontext|<KONTEXT_ID> ausführen.
  6. Gewünschte Ressource mit gültigem meta.profile und Kontext-Identifier oder Encounter-Referenz anlegen.
  7. OperationOutcome und HTTP-Status auswerten.
  8. Kontext bei Bedarf entfernen und nicht wiederverwenden.

Für den Device-Flow-Minimalfluss siehe OAuth Device Flow.

Kontext per API anlegen

Beim klassischen Deep-Link-Start legt der T2med-Client den Kontext an und übergibt ihn an die Drittanbieter-Anwendung. Beim OAuth Device Flow gibt es keinen Deep Link. Hier legt die Drittanbieter-Anwendung den Kontext selbst an, per POST /Encounter (ab Version 26.10). Damit ist innerhalb einer Sitzung auch ein Patientenwechsel möglich: Patient suchen oder anlegen, Kontext anlegen, in die eAkte schreiben.

Element im EncounterReferenzPflicht
subjectPatient/<patientId>ja
participant.individualPractitioner/<arztrolleId>ja
serviceProviderOrganization/<behandlungsortId>ja
episodeOfCareEpisodeOfCare/<behandlungsfallId>nein
ThemaVorgabe
Profilmeta.profile[0] = https://fhir.t2med.de/StructureDefinition/FhirApiEncounter|1.0.0
Patient-IDaus der Patientensuche oder -anlage
Arztrolle-IDaus der Practitioner-Suche
Behandlungsort-IDaus der Organization-Suche, z. B. GET /Organization?practitioner=<arztrolleId>
Antwort201 Created; die Kontext-ID steht im Header Location (.../Encounter/<kontextId>/_history/0)
Fehler400, wenn subject, participant oder serviceProvider fehlt; 422, wenn die Verarbeitung fehlschlägt
WeiterverwendungDie kontextId wird wie im Deep-Link-Pfad als Kontext-Identifier oder Encounter-Referenz verwendet. Kontexte werden bis zu 4 Stunden vorgehalten.

Ein vollständiges Beispiel steht in der API-Referenz.

eAkte lesen

Ab Version 26.11 kann die eAkte eines Patienten gelesen werden, etwa um die Historie in einer KI-Anwendung zu nutzen. Der Zugriff erfolgt über die Operation $eakte am Patienten.

ThemaVorgabe
AufrufGET /Patient/{id}/$eakte oder POST /Patient/{id}/$eakte mit einer Parameters-Ressource im Body
{id}Patienten-ID (Patient.id)
startoptional, Beginn des Zeitraums (einschließlich): 2026, 2026-01 oder 2026-01-01
endoptional, Ende des Zeitraums (einschließlich): 2026, 2026-12 oder 2026-12-31
embedEncounteroptional, true oder false (Standard false); bettet den Encounter in jeden Eintrag ein
ErgebnisBundle vom Typ searchset mit dem Profil https://fhir.t2med.de/StructureDefinition/FhirApiBundleEAkte|1.0.0
Einträgeje eAkten-Eintrag eine Composition mit dem Profil https://fhir.t2med.de/StructureDefinition/FhirApiCompositionEAkte|1.0.0
Inhalt einer CompositionTitel, Zeitpunkt, Text, Patient (subject), Arztrolle (author) und Behandlungsort (custodian)
Umfangeine generische eAkte, die der Ansicht der eAkte im T2med-Client entspricht; es werden die Sichtbarkeiten des aktuellen T2med-Benutzers beachtet
Dokumente und Bildersind als Referenz (DocumentReference) enthalten; die Datei selbst wird in einem zweiten Schritt über eine vom Server mitgelieferte Download-URL abgerufen

Hinweise

  • Bei umfangreichen Akten empfiehlt es sich, den Zeitraum mit start und end einzugrenzen.
  • Weitere Filter (Eintragstyp, Behandlungsfall, Arztrolle, Behandlungsort, Quelle) sind geplant und noch nicht verfügbar.
  • Eintragsarten wie Diagnosen oder Befunde werden derzeit als Text in der Composition geliefert. Eigene Profile je Eintragsart sind noch nicht verfügbar.

Ein Beispiel steht in der API-Referenz.

Profile und Code-Systeme

Unterstützte Profile

RessourceProfilUnterstützte Operationen
Patienthttps://fhir.t2med.de/StructureDefinition/FhirApiPatient|1.0.0create, read, update, search(identifier), search(family/given/birthdate)
Encounterhttps://fhir.t2med.de/StructureDefinition/FhirApiEncounter|1.0.0create (Kontext anlegen, ab 26.10), read
Compositionhttps://fhir.t2med.de/StructureDefinition/FhirApiCompositionEAkte|1.0.0Ergebnis von $eakte (ab 26.11, nur lesend)
Bundlehttps://fhir.t2med.de/StructureDefinition/FhirApiBundleEAkte|1.0.0Ergebnis von $eakte (ab 26.11, nur lesend)
Organizationhttps://fhir.t2med.de/StructureDefinition/FhirApiOrganization|1.0.0read, search(name/identifier), search(practitioner)
Practitionerhttps://fhir.t2med.de/StructureDefinition/FhirApiPractitioner|1.0.0read, search(name/identifier), registrierter Organization-Compartment-Sonderfall
Observationhttps://fhir.t2med.de/StructureDefinition/FhirApiObservationAnamnese|1.0.0create
Observationhttps://fhir.t2med.de/StructureDefinition/FhirApiObservationBefund|1.0.0create
Observationhttps://fhir.t2med.de/StructureDefinition/FhirApiObservationFreitext|1.0.0create
Conditionhttps://fhir.t2med.de/StructureDefinition/FhirApiConditionDiagnose|1.0.0create
Procedurehttps://fhir.t2med.de/StructureDefinition/FhirApiProcedureTherapie|1.0.0create
Procedurehttps://fhir.t2med.de/StructureDefinition/FhirApiProcedureProcedere|1.0.0create
DocumentReferencehttps://fhir.t2med.de/StructureDefinition/FhirApiDocumentReferenceFreitext|1.0.0create
DocumentReferencehttps://fhir.t2med.de/StructureDefinition/FhirApiDocumentReferenceAnhang|1.0.0create

Tips

X-FHIR-Profile ist bei create-Operationen nicht erforderlich; maßgeblich ist dort das im Payload gesetzte meta.profile. Der Header wird nur für Patient-Read und Patient-Search ausgewertet. Profil-URLs werden ohne Beachtung der Groß-/Kleinschreibung verglichen; empfohlen ist die hier dokumentierte Schreibweise.

Verwendete Code-Systeme (insbesondere Condition)

AnwendungsfallSystem-URLCodes
ICD-Diagnose in Condition.code.codinghttp://fhir.de/CodeSystem/bfarm/icd-10-gmICD-10-GM-Code in coding.code, Version optional in coding.version
Diagnosesicherheithttps://fhir.kbv.de/CodeSystem/KBV_CS_SFHIR_ICD_DIAGNOSESICHERHEITV, G, A, Z
Seitenlokalisationhttps://fhir.kbv.de/CodeSystem/KBV_CS_SFHIR_ICD_SEITENLOKALISATIONL, R, B

Diagnosesicherheit und Seitenlokalisation werden als Extensions am ICD-Coding übergeben (http://fhir.de/StructureDefinition/icd-10-gm-diagnosesicherheit bzw. http://fhir.de/StructureDefinition/seitenlokalisation). Die Diagnose-Relevanz (akut, dauerhaft, anamnestisch) ist kein Code-System, sondern eine eigene Extension, siehe unten.

Weitere fachliche Extensions

Ressource / KontextExtension-URLVerwendung
Observation Freitexthttps://fhir.t2med.de/StructureDefinition/FhirApiFreitextKuerzelKürzel als valueString
Condition Diagnosehttps://fhir.t2med.de/StructureDefinition/FhirApiDiagnoseRelevanzRelevanz als valueCode: akut, dauerhaft, anamnestisch
Procedure Therapiehttps://fhir.t2med.de/StructureDefinition/FhirApiFeststellungszeitpunktZeitpunkt, ausgewertet vor FhirApiProcedureOccurrence und performedDateTime
Procedure Therapiehttps://fhir.t2med.de/StructureDefinition/FhirApiProcedureOccurrenceZeitpunkt, zweite Priorität in der Auswertungsreihenfolge
DocumentReference Anhanghttps://fhir.t2med.de/StructureDefinition/FhirApiAnhangKuerzeloptionales Kürzel als valueString
Patient telecom (Telefon)https://fhir.t2med.de/StructureDefinition/FhirApiTelefonnummerKategorieKategorie-Code als valueCode
Patient telecom (Telefon/E-Mail)https://fhir.t2med.de/StructureDefinition/FhirApiKontaktinformationKommentarFreitext-Kommentar als valueString

Details zur Zeitpunkt-Auswertungsreihenfolge bei Procedure (Therapie und Prozedere): zuerst FhirApiFeststellungszeitpunkt, dann FhirApiProcedureOccurrence, zuletzt performedDateTime.

Fehlerbehandlung und Robustheit

Empfehlungen

EmpfehlungBegründung
OperationOutcome immer auswertenFachliche Fehler und Warnungen werden darüber transportiert.
4xx nicht automatisch wiederholenMeist fachliche oder formale Fehler.
Transiente technische Fehler gezielt wiederholenDafür X-Request-Id stabil halten, wenn verwendet.

Statuscodes

HTTPBedeutung
400Request formal ungültig, z. B. Profil fehlt oder Kontext-Identifier ist ungültig
403API-Key fehlt oder ist ungültig; bei Verwendung des Test-/Demo-API-Keys zusätzlich: serverseitiges Limit von 100 Aufrufen pro Serverprozess überschritten
404Resource bei read, search(identifier) oder update nicht gefunden
409Versionskonflikt bei Patient-Update
422fachliche oder technische Verarbeitung fehlgeschlagen
501Profil nicht unterstützt
503FHIR-API per Feature-Flag deaktiviert

Implementierungsnahe Besonderheiten

FallVerhalten
GET /Patient?family=...&given=...&birthdate=... ohne ParameterSuchservice wird mit leeren Spezifikationen aufgerufen; die Antwort ist eine Suchmenge.
DocumentReference mit Profil FhirApiDocumentReferenceAnhang|1.0.0Validierungsfehler, wenn description, attachment.data oder attachment.contentType fehlen.
GET /Organization/{id}/PractitionerEndpoint ist registriert, der aktuelle Handler interpretiert {id} aber als Practitioner-/Arztrollen-ID und gibt Organization-Ressourcen zurück. Für Drittanbieter ist GET /Organization?practitioner=<id> die fachlich klarere Variante.
PUT /Patient/{id} — Optimistic Locking mit If-MatchDer Versionskonflikt-Check (→ 409) wird ausgelöst, wenn der If-Match: W/"<version>"-Header mitgesendet wird. HAPI-FHIR-Clients setzen diesen automatisch, wenn die Versionsnummer im idElement gesetzt ist. Ohne If-Match-Header überspringt der Server den Versionscheck — empfohlen wird, den Header immer mitzusenden, um unbeabsichtigte Überschreibungen zu verhindern.
meta.versionId im Patient-ResponseDer Server liefert meta.versionId als vollen Pfad ({id}/_history/{version}), nicht als kurze Versionsnummer. Die kurze Versionsnummer für den If-Match-Header lässt sich daraus per IdType(meta.versionId).versionIdPart extrahieren (ergibt z. B. "4" aus "abc123/_history/4").
WarnungenOhne X-TreatWarningAsError: false werden Warnungen als Fehler behandelt.
Content-TypeDie API akzeptiert application/fhir+json und application/fhir+xml; Content-Type und Accept entsprechend dem gewünschten Format setzen.

Konkrete Beispiel-Payloads für Fehlerfälle finden sich unter API-Referenz → Typische Fehlerbeispiele.

Kontaktdaten und Geschlecht im Patient-Profil

Die Patient-Ressource enthält Kontaktdaten (Telefonnummern und E-Mail-Adressen) als FHIR telecom-Einträge.

Telefonnummer

FeldFHIR-MappingMögliche Werte
Nummertelecom.valuebeliebige Zeichenkette
Typtelecom.systemphone (Telefon), fax (Fax)
Verwendungtelecom.usehome, work, mobile (nur bei system=phone)
KategorieExtension https://fhir.t2med.de/StructureDefinition/FhirApiTelefonnummerKategorieCode-Wert als valueCode
KommentarExtension https://fhir.t2med.de/StructureDefinition/FhirApiKontaktinformationKommentarFreitext als valueString

Beispiel:

{
  "system": "phone",
  "value": "089 123456",
  "use": "home",
  "extension": [
    {
      "url": "https://fhir.t2med.de/StructureDefinition/FhirApiTelefonnummerKategorie",
      "valueCode": "privat"
    },
    {
      "url": "https://fhir.t2med.de/StructureDefinition/FhirApiKontaktinformationKommentar",
      "valueString": "nur vormittags erreichbar"
    }
  ]
}

E-Mail-Adresse

FeldFHIR-MappingMögliche Werte
Adressetelecom.valueE-Mail-Adresse
Typtelecom.systemimmer email
Verwendungtelecom.usehome, work
KommentarExtension https://fhir.t2med.de/StructureDefinition/FhirApiKontaktinformationKommentarFreitext als valueString

Beispiel:

{
  "system": "email",
  "value": "max.mustermann@example.de",
  "use": "home",
  "extension": [
    {
      "url": "https://fhir.t2med.de/StructureDefinition/FhirApiKontaktinformationKommentar",
      "valueString": "bevorzugte Kontaktmethode"
    }
  ]
}

Verhalten bei leeren Kontaktdaten

Sind keine Telefonnummern oder E-Mail-Adressen hinterlegt, enthält die Patient-Ressource kein telecom-Array.

Geschlecht (gender)

Einfache FHIR-Werte (male, female, unknown) werden direkt in Patient.gender übertragen. Die deutschen Werte divers und unbestimmt erfordern zusätzlich die Extension gender-amtlich-de auf dem gender-Element:

APS-WertgenderExtension Code
männlichmale—
weiblichfemale—
diversotherD
unbestimmtotherX
unbekanntunknown—

Die Extension wird als valueCoding auf dem primitiven gender-Element kodiert (nicht auf der Patient-Ressource selbst):

{
  "resourceType": "Patient",
  "gender": "other",
  "_gender": {
    "extension": [
      {
        "url": "http://fhir.de/StructureDefinition/gender-amtlich-de",
        "valueCoding": {
          "system": "http://fhir.de/CodeSystem/gender-amtlich-de",
          "code": "D"
        }
      }
    ]
  }
}

Warnung

Ohne die Extension wird other serverseitig als unbekannt interpretiert.

Sicherheit, Betrieb und Go-Live

Sicherheits- und Betriebsaspekte

ThemaVorgabe
API-Keynie im Klartext loggen
TransportFHIR-Aufrufe über TLS durchführen
Lokaler APS-ServerFHIR-API wird lokal über https:// bereitgestellt
ZertifikatAPS-Server-Zertifikat wird installationsspezifisch erzeugt
Öffentliche CADrittanbieter dürfen keine öffentliche CA-signierte Zertifikatskette voraussetzen
HTTPS-ClientBei FHIRBasisUrl mit https:// eigenen SSL-Kontext bzw. HTTP-Client konfigurieren
Lokale Hostslocalhost, 127.0.0.1 und lokal konfigurierte Hostnamen unterstützen
ZertifikatsprüfungInstallationsspezifische lokale Zertifikate akzeptieren; produktiv den Trust-Store kontrolliert verwalten, statt die Zertifikatsprüfung pauschal zu deaktivieren
GeheimnisseClient-Secret und Refresh-Token nicht im Klartext ablegen, sondern in einem sicheren Schlüsselspeicher; nicht protokollieren
Kontext-IDals kurzlebiges technisches Token behandeln
WarnungenX-TreatWarningAsError bewusst setzen
Test-/Demo-API-Key-LimitBei Verwendung des Test-/Demo-API-Keys begrenzt der Server auf maximal 100 Aufrufe pro Serverprozess. Nach Erreichen des Limits liefert jeder weitere Aufruf 403 Forbidden. Der Zähler wird nicht zurückgesetzt — für weitere Tests den APS-Server neu starten.

Go-Live-Checkliste

Klassischer Deep-Link-Pfad

  • [ ] Drittanbieter in APS aktiviert
  • [ ] API-Key vorhanden und sicher hinterlegt
  • [ ] drittanbieterKey bzw. Hersteller/Produkt korrekt konfiguriert
  • [ ] Verarbeitung der Deep-Link-Parameter kontextId, FHIRBasisUrl, oAuthToken implementiert
  • [ ] FHIRBasisUrl unverändert als FHIR-Client-Basis-URL verwendet
  • [ ] Eigener SSL-Kontext/HTTP-Client für lokale https://-APS-Server eingerichtet
  • [ ] Test mit installationsspezifischem lokalem APS-Zertifikat durchgeführt
  • [ ] Test mit localhost, 127.0.0.1 oder lokal konfiguriertem Hostnamen durchgeführt
  • [ ] Test: Aufruf durch T2med-Client über Deep Link
  • [ ] Test: GET /Patient?identifier=https://fhir.t2med.de/identifier/kontext|<KONTEXT_ID>
  • [ ] Test: gewünschte POST-Ressourcentypen mit korrektem meta.profile
  • [ ] Test: DocumentReference mit Profil FhirApiDocumentReferenceAnhang|1.0.0
  • [ ] Test: Fehlerfall ohne oder mit falschem Profil
  • [ ] Optional: Transaction-Verhalten mit Rollback geprüft
  • [ ] Monitoring für HTTP-Status und OperationOutcome vorhanden

Zusätzlich bei OAuth Device Flow (Variante B)

  • [ ] OAuth Device Authorization Endpoint und Token Endpoint bekannt und erreichbar
  • [ ] Client Secret aus APS-Drittanbieter-Einrichtung bereitgestellt
  • [ ] Client Secret und Refresh-Token nur im sicheren Schlüsselspeicher abgelegt, nicht im Klartext
  • [ ] Client Secret wird nicht geloggt
  • [ ] Polling-Verhalten für authorization_pending, slow_down, expired_token und access_denied implementiert
  • [ ] Polling-Intervall bei slow_down korrekt erhöht (mindestens +5 Sekunden)
  • [ ] Device Code Expiry korrekt behandelt (Neustart erforderlich)
  • [ ] Automatische Wiederverbindung per Refresh-Token (grant_type=refresh_token) geprüft
  • [ ] Test: kompletter Device Flow mit Autorisierung im Browser
  • [ ] Test: Abbruch und erneuter Start des Device Flow
Impressum·Datenschutz