FHIR-Gateway
Version | Page Info |
|---|---|
Last update | Page Info |
Classification | public |
Responsible | Product Management |
- 1 Summary
- 2 Availability Management
- 3 Appointment Booking
- 4 Patient Management
- 5 Appointment Synchronization from FHIR Server to Platform
- 6 Questionnaire & QuestionnaireResponse
- 6.1 Questionnaire
- 6.1.1 Questionnaire Search
- 6.1.2 Questionnaire Creation
- 6.2 QuestionnaireResponse
- 6.2.1 Finds or creates the Patient resource based on the form data
- 6.2.1.1 Patient Search
- 6.2.1.2 Patient Creation
- 6.2.2 Creates or finds the corresponding Questionnaire resource
- 6.2.2.1 Questionnaire Search
- 6.2.2.2 Questionnaire Creation
- 6.2.3 Creates or updates the QuestionnaireResponse
- 6.2.3.1 QuestionnaireResponse Search
- 6.2.4 QuestionnaireResponse Creation
- 6.2.4.1 QuestionnaireResponse Updates
- 6.2.1 Finds or creates the Patient resource based on the form data
- 6.1 Questionnaire
- 7 Integration Setup
- 7.1.1 Prerequisites
- 7.1.2 Download FHIR-Gateway
- 7.1.3 Installation
- 7.1.3.1 Windows
- 7.1.3.2 Linux/macOS
- 7.2 Configuration
- 7.2.1 [samedi] section
- 7.2.1.1 token
- 7.2.1.2 endpoint
- 7.2.1.3 state_file
- 7.2.1.4 sync_interval_seconds
- 7.2.1.5 request_timeout_seconds
- 7.2.1.6 sync_forms
- 7.2.1.7 sync_form_types
- 7.2.1.8 sync_appointments
- 7.2.2 [fhir] section
- 7.2.2.1 base_url
- 7.2.2.2 system_mode
- 7.2.2.3 token
- 7.2.2.4 insecure_ssl_verify_none
- 7.2.2.5 request_timeout_seconds
- 7.2.2.6 sync_interval_seconds
- 7.2.2.7 system_namespace
- 7.2.2.8 max_concurrent_requests
- 7.2.2.9 sync_slots
- 7.2.3 [fhir.auth.oauth] section
- 7.2.3.1 endpoint
- 7.2.3.2 client_id
- 7.2.3.3 client_secret
- 7.2.3.4 scopes
- 7.2.4 [fhir.ishmed.mappings] section
- 7.2.5 [fhir.resources.change_detection] section
- 7.2.5.1 mode
- 7.2.5.2 channel_type
- 7.2.5.3 endpoint
- 7.2.5.4 listen_address
- 7.2.5.5 listen_path
- 7.2.5.6 subscription_id
- 7.2.6 Configuration examples
- 7.2.6.1 CGM Medico
- 7.2.6.2 iMedOne
- 7.2.6.3 ISHMed
- 7.2.1 [samedi] section
Summary
The samedi FHIR-Gateway is an on-premises client application that synchronizes appointments, patients, forms, and availability data between the samedi platform and hospital FHIR servers, supporting bidirectional synchronization according to ISiK standards.
The samedi FHIR-Gateway supports:
Availability Management (Slots), synchronizing free appointment slots from the FHIR server to the samedi platform for appointment booking
Terminplanung (Appointment Scheduling) according to ISiK Stufe 2/3 from the perspective of a FHIR Requestor, including bidirectional synchronization of appointments between the samedi platform and FHIR server
Patient Management, including finding or creating patients in the FHIR server, synchronizing patient data between platform and FHIR, and maintaining patient identifier mappings
Form Types Synchronization, converting and sending samedi form types to the FHIR server as Questionnaires
Forms Synchronization, converting and sending completed forms from the samedi platform to the FHIR server as QuestionnaireResponses
Change Detection, supporting webhook and websocket subscriptions to detect and synchronize appointment changes from the FHIR server back to samedi platform
Implementation modes: The FHIR-Gateway supports three integration modes, each tailored to different hospital information systems: iMedOne, CGM Medico, and ISHMed. The implementation and configuration vary depending on the selected mode.
Availability Management
FHIR-Gateway synchronizes appointment availability from the FHIR server to the samedi platform. For each appointment type with a configured FHIR service type code reference, the gateway queries the FHIR server for Slot resources using the service type code and date. It extracts slots with status "free" and sends the available times to the samedi platform. The synchronization runs periodically, processing slots for each day from the current date up to 6 months in the future. This keeps the platform's availability data current, so patients see accurate available appointment times when booking online.
Referencing service type code in platform appointment type settings
Appointment type reference can be set in the appointment type settings:
Requesting time slots from FHIR server
For all referenced appointment types FHIR-Gateway will request available slots from the FHIR server.
Example request for CGM Medio mode:
GET {BASE_URL}/Slot?service-type=allgemeine-sprechstunde&start=2024-01-15Example request for iMedOne mode:
GET {BASE_URL}/Slot?service-type=allgemeine-sprechstunde&start=ge2024-01-15T00:00:00Z&_count=100Example request for ISHMed mode:
GET {BASE_URL}/Slot?schedule=schedule-123&service-type=allgemeine-sprechstunde&start=2024-01-15Displaying available times for online appointment booking
As a result of synchronization a patient sees available time slots for the corresponding appointment type on their booking form on patient portal:
Appointment Booking
General Process:
When an appointment is created, updated or cancelled online or on the samedi platform, the fhirgateway synchronizes the change to the FHIR server:
Patient Handling: The gateway decrypts the patient data, finds or creates the patient in the FHIR server, and updates the patient identifiers on the platform with the FHIR patient ID. FHIR patient id is visible on the patient dashboard:
Slot Finding: The gateway searches for an available Slot resource matching the appointment type (service type code) and requested time.
Appointment Creation: The gateway creates a FHIR Appointment resource referencing the found slot and calls the
Appointment/$bookoperation to book the appointment on the FHIR server.Reference Update: After successful booking, the gateway updates the platform with the FHIR appointment ID (xref) to link the platform appointment with the FHIR appointment.
Error Handling: If booking fails (e.g., slot no longer available, FHIR server error), the gateway cancels the appointment on the samedi platform to keep the systems in sync.
Mode-Specific Differences
Medico
Searches for slots using service type code and date (
start=YYYY-MM-DD)Retrieves the Schedule resource to obtain the HealthcareService reference
Includes the HealthcareService as a participant in the appointment
Includes ServiceType in the appointment resource
For rescheduling: If an existing appointment has a different start time, includes the old appointment ID in the
cancelled-appt-idparameter of the booking operation
iMedOne
Searches for slots using service type code with exact timestamp match (
start=eq2024-01-15T10:00:00Z)Includes ServiceType in the appointment resource
Only includes the Patient as a participant
For rescheduling: Cancels the old appointment first, then creates a new one
ISHMed
Searches for slots across multiple configured Schedule IDs for the appointment type
Uses service type code and schedule ID in the slot search with exact timestamp match (
schedule=schedule-123&service-type=INJEKT&start=eq2024-01-15T10:00:00Z)Only includes the Patient as a participant
For rescheduling: Cancels the old appointment first, then creates a new one
All modes use the ISiK $book operation endpoint: POST /Appointment/$book with a Parameters resource containing the appointment to be booked.
Patient Management
Patient data is handled for now only as part of appointment booking. When an appointment is created or updated, the gateway finds or creates the patient in the FHIR server before booking the appointment. The patient can be searched by id or an identifier:
GET {BASE_URL}/Patient/{id}GET {BASE_URL}/Patient?identifier={system}|{value}Patient Fields Sent to FHIR Server:
When creating a new patient, the gateway sends the following fields from the samedi platform patient to the FHIR Patient resource:
Name: given name (first name), family name (last name), prefix (title)
Identifier: samedi patient ID (system:
http://samedi.de/fhir/CodeSystem/patient-id, value: samedi patient ID)Gender: administrative gender (male, female, other, unknown)
Birth Date
Address: street, city, postal code, country
Note: Contact information (phone, mobile, email, fax) is not sent to the FHIR server during appointment handling.
Appointment Synchronization from FHIR Server to Platform
The fhirgateway synchronizes appointment changes from the FHIR server to the samedi platform. The implementation differs by mode.
General Process (for all modes)
When an appointment is created, updated, or cancelled in the FHIR server, the FHIR-Gateway:
Detects the change via polling the
GET /Appointment?_lastUpdated=ge{timestamp}endpoint or webhook, or websocket request (mode-dependent)Checks the service type code of the appointment. If it is one of those that are set as a reference for samedi appointment types, it proceeds with handling the appointment. If it’s not one of those, the change is ignored.
Extracts the patient ID from the appointment participants, retrieves the full Patient resource from the FHIR server and encrypts the patient data with customer’s public key, to send it to platform.
Sends the appointment data to the platform: appointment start time, appointment type reference, and encrypted patient information.
Mode-Specific Differences
Medico
Change Detection: Polling using
GET {{BASE_URL}}/Appointment?_lastUpdated=ge{timestamp}query, with optional WebSocket subscription for real-time updatesPolling Frequency: Configurable sync interval (default: 30 seconds)
State Management: Tracks the last processed timestamp and appointment IDs to avoid duplicate processing
iMedOne
Change Detection: Webhook only
Webhook Endpoint: Receives HTTP POST requests with FHIR Bundle containing appointment changes
Real-time: Processes changes immediately when webhook is received
ISHMed
Change Detection: Webhook only
Webhook Endpoint: Receives HTTP POST requests with FHIR Bundle containing appointment changes
Real-time: Processes changes immediately when webhook is received
Resource Interactions
Appointment Updates Polling
GET {base-url}/Appointment/_history?_since={timestamp}Example:
GET <https://fhir-server.example/fhir/Appointment/_history?_since=2024-08-04T07:19:23.209+00:00>Questionnaire & QuestionnaireResponse
Questionnaire
Questionnaire Search
GET {base-url}/Questionnaire?identifier={system}|{value}Example:
GET <https://fhir-server.example/fhir/Questionnaire?identifier=https%3A%2F%2Fsamedi.de%2Ffhir%2Fforms|unique-form-id>Questionnaire Creation
POST {base-url}/Questionnaire
Content-Type: application/fhir+jsonExample:
POST <https://fhir-server.example/fhir/Questionnaire>
Content-Type: application/fhir+json
{
"resourceType": "Questionnaire",
"identifier": [{
"system": "<https://samedi.de/fhir/forms>",
"value": "unique-form-id"
}],
"name": "ANAMNESIS",
"title": "Anamnesis",
"status": "active",
"date": "2024-08-29T08:21:57+02:00",
"description": "",
"item": [
{
"linkId": "1",
"text": "Do you have any allergies?",
"type": "boolean"
}
],
}QuestionnaireResponse
When handling form submissions, our gateway performs the following steps:
Finds or creates the Patient resource based on the form data
Creates or finds the corresponding Questionnaire resource
Creates or updates the QuestionnaireResponse
Finds or creates the Patient resource based on the form data
Patient Search
GET {base-url}/Patient/{id}Example:
GET <https://fhir-server.example/fhir/Patient/123>Patient Creation
Example:
POST <https://fhir-server.example/fhir/Patient>
Content-Type: application/fhir+json
{
"resourceType": "Patient",
"meta": {
"profile": [
"<https://gematik.de/fhir/isik/v3/Basismodul/StructureDefinition/ISiKPatient>"
]
},
"identifier": [{
"type": {
"coding": [{
"system": "<https://terminology.hl7.org/CodeSystem/v2-0203>",
"code": "MR"
}]
},
"system": "<https://fhir.krankenhaus.example/NamingSystem/PID>",
"value": "TestPID"
}],
"name": [{
"use": "official",
"family": "Fürstin von Musterfrau",
"given": ["Erika"]
}],
"active": true,
"gender": "female",
"birthDate": "1964-08-12"
}Creates or finds the corresponding Questionnaire resource
Questionnaire Search
See above
Questionnaire Creation
See above
Creates or updates the QuestionnaireResponse
The gateway implements an intelligent update mechanism for QuestionnaireResponses:
It first searches for an existing QuestionnaireResponse using the identifier
If no existing response is found, it creates a new one
If an existing response is found:
The gateway compares the content (items/answers) of both responses
Only updates the response if the content has changed
Uses PUT request with the existing resource ID for updates
QuestionnaireResponse Search
GET {base-url}/QuestionnaireResponse?identifier={system}|{value}Example:
GET <https://fhir-server.example/fhir/QuestionnaireResponse?identifier=https%3A%2F%2Fsamedi.de%2Ffhir%2Fforms|unique-form-id>QuestionnaireResponse Creation
Example:
POST <https://fhir-server.example/fhir/QuestionnaireResponse>
Content-Type: application/fhir+json
{
"resourceType": "QuestionnaireResponse",
"identifier": {
"system": "<https://samedi.de/fhir/forms>",
"value": "unique-form-id"
},
"questionnaire": "Questionnaire/123",
"status": "completed",
"subject": {
"reference": "Patient/456"
},
"authored": "2024-03-14T15:30:00Z",
"item": [
{
"linkId": "1",
"text": "Do you have any allergies?",
"answer": [
{
"valueBoolean": false
}
]
}
]
}QuestionnaireResponse Updates
Example:
PUT <https://fhir-server.example/fhir/QuestionnaireResponse/123>
Content-Type: application/fhir+json
{
"resourceType": "QuestionnaireResponse",
"identifier": {
"system": "<https://samedi.de/fhir/forms>",
"value": "unique-form-id"
},
"questionnaire": "Questionnaire/123",
"status": "completed",
"subject": {
"reference": "Patient/456"
},
"authored": "2024-03-14T15:30:00Z",
"item": [
{
"linkId": "1",
"text": "Do you have any allergies?",
"answer": [
{
"valueBoolean": false
}
]
},
{
"linkId": "2",
"text": "When was your last medical checkup?",
"type": "date"
},
]
}Integration Setup
Prerequisites
A FHIR server implementing ISiK Terminbuchung Stufe 2
Support for Patient, Schedule, Slot, Appointment, and HealthcareService resources
Valid endpoint URL for the FHIR server
Authentication credentials (if required)
A defined way to receive appointment updates from the FHIR system to the samedi platform, such as supported Appointment search by
_lastUpdatedparameter:Appointment?_lastUpdated=ge{timestamp}, Webhook or WebSocket subscriptions.
Download FHIR-Gateway
Download FHIR-Gateway for your system from here: https://github.com/samedi/fhirgateway/releases
For Windows download MSI installer package
For Linux/macOS download the binary archive (.tgz)
Installation
Windows
Run the MSI installer and follow the installation wizard
Linux/macOS
Extract the binary archive to your desired location (e.g.,
/opt/fhirgatewayor~/fhirgateway)Make the binary executable:
chmod +x fhirgatewayCreate a systemd service file (Linux) or launchd plist (macOS) to run it as a service, or run it manually
Configuration
Configuration should be stored in the format toml. By default the configuration file is expected to be present in the same directory as the executable and be named fhirgateway.toml, but the executable can also take it as a parameter, and then the name or the location of the file can be different.
The installer will provide fhirgateway.example.toml with an example configuration that can be used as a starting point to configure the integration.
The configuration file is divided onto main sections:
[samedi]- samedi platform gateway API connection settings[fhir]- FHIR server connection settings and FHIR-resources-related settings
[samedi] section
This section is common and independent of the system mode. It contains settings that apply to samedi platform side of the integration.
token
Authentication token for the samedi gateway API. Used to authenticate all API requests to the samedi platform. Obtain this from the samedi support
Required: Yes
Example:
token = "abc123xyz789"
endpoint
Base URL of the samedi gateway API endpoint. Override only if using a custom endpoint (e.g., staging). For production, the default is correct.
Required: No
Default:
https://app.samedi.deExample:
endpoint = "https://staging.samedi.de"
state_file
Path to the file where synchronization state is persisted. Stores last processed timestamps and processed appointment IDs to resume after restarts and avoid repeated processing. Use an absolute path or a path relative to the working directory. Ensure the gateway has write permissions.
Required: No
Default:
fhirgateway-state.jsonExample:
state_file = "state.json"
sync_interval_seconds
Interval in seconds between synchronization cycles for polling operations. Controls how often the gateway polls the samedi platform for changes (appointments, forms, form types). Lower values increase responsiveness but also API load. Higher values reduce load but increase latency.
Required: No
Default:
30Example:
sync_interval_seconds = 60
request_timeout_seconds
HTTP request timeout in seconds for API calls to the samedi platform. Maximum time to wait for a response from the samedi API. Increase for slow networks or large payloads. If exceeded, the request fails and may be retried.
Required: No
Default:
30Example:
request_timeout_seconds = 60
sync_forms
Enable or disable synchronization of forms (QuestionnaireResponses) from the platform to the FHIR server. When enabled, completed forms are converted to FHIR QuestionnaireResponse resources and sent to the FHIR server. Disable if you don't need form synchronization.
Required: No
Default:
trueExample:
sync_forms = false
sync_form_types
Enable or disable synchronization of form types (Questionnaires) from the platform to the FHIR server. When enabled, form type definitions are converted to FHIR Questionnaire resources and sent to the FHIR server. Disable if you don't need form type synchronization.
Required: No
Default:
trueExample:
sync_form_types = false
sync_appointments
Enable or disable synchronization of appointments from the platform to the FHIR server. When enabled, appointment changes (create, update, cancel) are synchronized from the samedi platform to the FHIR server. This is the core appointment booking functionality. Disable only if you only need unidirectional sync (FHIR to platform).
Required: No
Default:
trueExample:
sync_appointments = true
[fhir] section
These settings belong to the FHIR side of the integration. They might depend on the system mode, because different system modes might support their mode-specific settings.
base_url
Base URL of the FHIR server. Must end with. Used as a base URL for all FHIR API requests.
Required: Yes
Example:
base_url = "https://fhir.example.com/fhir/"
system_mode
Integration mode. Determines adapter behavior and required configuration. Supported values: "medico", "imedone", "ishmed".
Required: Yes
Example:
system_mode = "medico"
token
Authentication token for the FHIR server. Used as a Bearer token in the Authorization header. Required if the FHIR server uses token-based authentication. Cannot be used together with OAuth authentication methods.
Required: No (required if no OAuth is configured)
Default: None
Example:
token = "your-fhir-server-token"
insecure_ssl_verify_none
Disable SSL certificate verification for the FHIR server. Set to true only for self-signed certificates or testing environment. Not recommended for production.
Required: No
Default:
falseExample:
insecure_ssl_verify_none = true
request_timeout_seconds
HTTP request timeout in seconds for FHIR server API calls. Maximum time to wait for a response. Increase for slow networks or large payloads.
Required: No
Default:
30Example:
request_timeout_seconds = 60
sync_interval_seconds
Interval in seconds between synchronization cycles for FHIR server polling operations. Used for regulating frequency of change detection polling (medico mode). Lower values increase responsiveness but also server load.
Required: No
Default:
30Example:
sync_interval_seconds = 60
system_namespace
System namespace identifier for the FHIR server. Used as the system identifier when creating patient identifiers and referencing resources. If not specified, defaults to the base_url value.
Required: No
Default: Value of
base_urlExample:
system_namespace = "https://fhir.example.com"
max_concurrent_requests
Maximum number of concurrent HTTP requests to the FHIR server. Limits parallelism to avoid overloading the server. Set based on server capacity and network conditions.
Required: No
Default: No limit (0 means unlimited)
Example:
max_concurrent_requests = 10
sync_slots
Enable or disable synchronization of appointment slots (availabilities) from the FHIR server to the samedi platform. When enabled, the gateway periodically queries Slot resources and updates platform availability data.
Required: No
Default:
trueExample:
sync_slots = false
[fhir.auth.oauth] section
Generic OAuth 2.0 authentication configuration for FHIR servers. Use this instead of the token setting when the FHIR server requires OAuth authentication. Used by iMedOne mode and can also be used by medico mode if you prefer to specify scopes explicitly. Cannot be used together with other authentication methods.
endpoint
OAuth token endpoint URL for obtaining access tokens.
Required: Yes
Example:
endpoint = "https://fhir.example.com/fhir/auth/token"
client_id
OAuth client ID for authentication.
Required: Yes (if using OAuth auth)
Example:
client_id = "oauth-client-id"
client_secret
OAuth client secret for authentication.
Required: Yes (if using OAuth auth)
Example:
client_secret = "your-secret-key"
scopes
List of OAuth scopes to request. If not specified, defaults to the required scopes for Medico integration.
Required: No
Default:
system/Patient.read, system/Patient.write, system/Appointment.read, system/Appointment.write, system/HealthcareService.read, system/Schedule.read, system/Slot.read, system/Subscription.read, system/Subscription.writeExample:
scopes = ["system/Patient.read", "system/Appointment.read"]
[fhir.ishmed.mappings] section
Configuration section specific for ISHMed. It contains appointment type mappings. It maps platform appointment type references to FHIR service type codes and schedule IDs.
Example:
[fhir.ishmed.mappings]
[fhir.ishmed.mappings.appointment_type.INJEKT-DERM]
service_type = "INJEKT"
schedules = ["DRIESCHA-000645", "DRIESCHA-000632"]
[fhir.ishmed.mappings.appointment_type.INJEKT-PED]
service_type = "INJEKT"
schedules = ["KRIEVKA-000645", "KRIEVKA-000632"][fhir.resources.change_detection] section
Change detection enables synchronization of appointments from the FHIR server to the samedi platform. Currently only Appointment resource can be synchronized. Patients will be also sent to platform, but only together with the appointment changes.
mode
Change detection mode. Determines how the gateway detects appointment changes in the FHIR server. Supported values: "query_polling" (poll Appointment resource using _lastUpdated), "subscription" (real-time via webhook or websocket), "none" (disabled).
Required: No
Default:
"none"(sync disabled)Example:
mode = "query_polling"
channel_type
Channel type for subscription mode. Only used when mode = "subscription". Supported values: "webhook" (HTTP POST notifications), "websocket" (WebSocket connection).
Required: Yes (if
mode = "subscription")Default: None
Example:
channel_type = "webhook"
endpoint
WebSocket endpoint URL (e.g., wss://fhir.example.com/websocket) to connect to for real-time notifications.
Required: Yes (if
mode = "subscription")Example:
endpoint = "wss://fhir.example.com/websocket"
listen_address
Address and port where the gateway listens for incoming webhook notifications. Required for webhook subscriptions. Format: "host:port" or just "port" (listens on all interfaces). The gateway starts an HTTP server on this address to receive webhook POST requests.
Required: Yes (if
channel_type = "webhook")Default: None
Example:
listen_address = "localhost:8080"orlisten_address = "8080"