English | Deutsch
Introduction
eauXchange is a dedicated server established for interaction with the GKVKomServer. It supports automatic and scheduled sending and receiving of data, keeps insurance company information up to date and tracks the public keys of the communication partners.
Two procedures are supported, each licensed separately:
- EAU (
/eau) -
electronic certificates of incapacity for work (elektronische Arbeitsunfähigkeitsbescheinigung).
- Vorerkrankung / LFZ (
/pre) -
preexisting condition enquiries for continued payment of wages (Entgeltersatzleistungen).
Every installation serves its own documentation: /help is the interactive API reference of the
version you are running, /changelog lists the changes of all versions. Both work without a token.
|
Licensing
The license file is created by Javiis GmbH upon request. For this, the company number (BNR) (test or production) for which a license is issued is required. All requests are then sent for these company numbers. (For test mode, the test company number is used.)
The license also decides which procedures the installation may use (EAU, Vorerkrankung or both). Calls to a procedure that is not licensed are rejected.
Running the service
eauXchange is delivered as a Docker container and uses a PostgreSQL database to store all relevant information.
config folder next to your docker-compose.yml:-
application.yml- the server configuration (see below) -
the license file provided by Javiis GmbH
-
the certificate and private key of your BNR (
<bnr>.p7c/<bnr>.pkey), from which the keystoregkv.p12is created
services:
eauxchange:
container_name: eauxchange_server
image: www.eauxchange.de/eauxchange:latest
ports:
- "8085:8085"
depends_on:
- db
environment:
- SPRING_CONFIG_LOCATION=/opt/app/config/application.yml
- DATABASE_CONNECTION=eauxchange_db
- DATABASE_PORT=5432
volumes:
- ./config:/opt/app/config
db:
container_name: eauxchange_db
image: postgres:14.12-bullseye
restart: unless-stopped
shm_size: 128mb
environment:
POSTGRES_DB: eauxchange
POSTGRES_PASSWORD: <password>
POSTGRES_USER: gkv_user
volumes:
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
- <EXTERNAL_PATH>:/var/lib/postgresql/data
The image is pulled from the registry www.eauxchange.de; the access data is provided together with the license.
The database schema is created and migrated automatically on startup.
Server configuration
The configuration lives in application.yml in the config folder. The most important settings:
spring:
datasource:
username: gkv_user
password: <password>
url: jdbc:postgresql://eauxchange_db:5432/eauxchange
server:
port: 8085
com:
javiis:
gkv:
bnrTest: <test BNR>
bnrProductive: <production BNR>
# true = nothing is transmitted to the insurance companies (test/dry run)
dryRunning: true
# false = test certificate, true = production certificate
use_production_certificate: false
product:
manufacturer: <company>
name: <product name>
version: <version>
prodID: <product number>
modID: <module number>
contact: # technical contact, sent with every request
name: Max Mustermann
gender: M
street: Musterstrasse
streetNr: 74
zip: 12345
city: Berlin
tel: 0123456789
mail: kontakt@example.com
keystore:
test:
path: /opt/app/config/test/gkv.p12
password: <password>
keyPassword: <password>
alias: <BNR>
receivePath: /opt/app/config/receive
logSentFiles: true
xmlLogPath: /opt/app/config/sent
Schedules
The background jobs run on cron expressions. The defaults are usually fine; all of them can be overridden:
| Property | Default | Task |
|---|---|---|
|
|
Sends pending requests to the insurance companies |
|
|
Asks the GKV server for new answers and downloads them |
|
|
Imports downloaded answer files |
|
|
Assigns answers that arrived without a usable reference to their request |
|
|
Checks the remaining validity of the communication certificates |
| Status requests must not run more often than every 15 minutes (restriction of the GKV communication server). |
Notifications
Set com.javiis.gkv.mailSettings (host, port, sender, username, password, defaultRecipient) and
com.javiis.gkv.sendEmailOnError: true to be informed about failures of the background jobs and about
certificates that are about to expire.
Authentication
All API calls require an API token; only the built-in help (/help, /api-docs) and the release notes
(/changelog) are open. A token is a JWT that is valid for the company numbers it was issued for and
carries an expiry date.
-
On the very first start the server creates the user
rootand writes its generated password once into the log. Note it down; it is not shown again. -
Create an API token with that user (HTTP basic authentication):
curl -u root:<password from the log> \ -X POST 'https://<host>/security/createAPIToken?expiryDate=2027-12-31T23:59:59¬e=ERP' \ -H 'Content-Type: application/json' \ -d '["<BNR>"]' -
Use the returned token for every further call:
curl -X POST 'https://<host>/eau/getOpenEauResponses' \ -H 'Authorization: Bearer <token>'
Tokens can be listed, disabled, enabled and deleted (/security/getTokens, /security/disableTokens,
/security/enableTokens, /security/deleteTokens).
| A request whose BNR is not covered by the token is rejected with HTTP 403. When you add a new company number, issue a new token for it - otherwise those requests stay unsent. |
How to use the service
For a detailed list of API calls and schemas visit the built-in help of your installation under
/help. It documents exactly the version you are running.
Creating an eAU request
In the built-in help: createEauRequests
To schedule an eAU request, an object of EauRequest type is sent. The startDate field refers to the point in time when the absence was taken.
If the field contactPerson is empty, the default contact person set at creation time will be used.
The response will be an errorCode per request sent (NONE if the request is scheduled successfully).
operation::createEauRequests[snippets='http-request,http-response']
Retrieving an eAU response
In the built-in help: getOpenEauResponses
You can retrieve open eAU responses with the method getOpenEauResponses.
All eAU responses that are not marked as checked are retrieved.
operation::getOpenEauResponses[snippets='http-request,http-response']
Marking an eAU response as finished
In the built-in help: markEauResponsesAsChecked
In order to avoid data loss, all eAU responses must be marked as completed once they are retrieved from the server. This status update is achieved by invoking the markEauResponsesAsChecked method.
operation::test-mark-eau-responses-as-checked[snippets='http-request,http-response']
Schedule eAU cancellation
In the built-in help: stornoEauRequest
You can abort an eAU request by invoking the stornoEauRequest method. eAU requests that have not yet been transmitted will be obliterated instantly, while requests that have already been dispatched will be queued for cancellation during the next synchronization process.
operation::stornoEauRequest[snippets='http-request,http-response']
Resending requests
scheduleEauRequestsForResend queues requests again, for example after an insurance company asked for a
repetition. scheduleEauRequestsForResendWithContactPerson does the same but replaces the technical
contact, which is the right call after the contact person has changed.
Searching requests and responses
getOpenEauRequests returns everything that is still waiting for an answer.
findEauRequestByCriteria and findEauResponseByCriteria search by freely combinable criteria
(name, insurance number, period, state). getEauRequest and getEauResponseFromRequestID fetch a
single record.
If a request stays open although the answer has already arrived, syncResponsesWithRequests assigns
pending answers to their requests. The same runs automatically (see the schedules above).
Execute sending/retrieving job manually
In the built-in help: manualexecuteRequestSending
You have the option to initiate a manual send or retrieve task by invoking the methods
manualExecuteRequestSending and manualExecuteStatusRequest in /common. Typically, these methods are
used for testing or when an answer is needed before the next scheduled run.
operation::manualExecuteStatusRequest[snippets='http-request']
Preexisting condition enquiries (Vorerkrankung / LFZ)
Requires the Vorerkrankung license. The flow mirrors the eAU procedure and uses the /pre endpoints.
-
createPreexistingConditionInfoRequestsschedules the enquiries. Duplicates - same person, same period - are rejected right away with an explaining error instead of being sent twice. -
getOpenPreexistingConditionInfoRequestslists everything that is still waiting for an answer. -
getOpenPreexistingConditionInfoResponsesreturns the answers that have not been marked as checked. The optional parameterlimitrestricts the number of records returned. -
markResponseAsCheckedconfirms the processing, exactly like in the eAU procedure.
getPreexistingConditionInfoRequest, getPreexistingConditionInfoResponse and
findPreexistingConditionInfoRequestsByAbAGDate fetch single records or search by the date of the
employer enquiry.
For every enquiry the data delivered by the insurance company is available in raw and in parsed form:
getRawRequest, getRawResponse, getRawResponseByRequest, getRawErrorResponse and the
corresponding getParsed… methods. This is the fastest way to clarify a rejection without a support
request - the rejection reason of the insurance company is part of the answer.
Validation service
The server provides methods for validating insurance company numbers and employee insurance numbers according to the standard validation rules (/validation/companyBnr, /validation/insuranceNr).
More information: In the built-in help: validateInsuranceNr
Insurance companies
The insurance company data is ordinarily synchronized automatically, however, you also have the opportunity to manually trigger this synchronization by calling the triggerInsuranceCompanyRefresh method in /insuranceCompany. This action updates all insurance companies and their public keys, in addition to their associations with their respective DAVs.
findInsuranceCompanyByBnr, findInsuranceCompanyByCriteria and getAllValidInsuranceCompanies read the data.
Operating notes
- Which version am I running?
-
/changelogshows the version of the installation and the changes of all versions;/changelog.jsondelivers the same information in machine-readable form. - An answer file could not be imported
-
Files that could not be processed are kept.
reimportFailedResponsesprocesses them again after the cause has been fixed;manualTriggerResponseImportstriggers the import of everything that has been downloaded. - Nothing is transmitted
-
Check
dryRunning(must befalsein production), the certificate selection (use_production_certificate) and whether the API token covers the company number of the requests. - Certificates
-
The remaining validity is checked daily. With the mail settings configured, a warning is sent early enough to exchange the certificate before the transmission stops.
- Looking at the file sequence number
-
Use
POST /dav/getCurrentDAVFileCounter- it only reads. The returned value is the number of the file that was sent last. Every DAV keeps one counter per procedure: the optional parameterprocedureselects it,EAA(default) for eAU andEELfor preexisting condition enquiries. The procedure’s module has to be licensed -EAArequires EAU,EELrequires VORERKRANKUNG - otherwise the call is answered with 403.POST /dav/drawNextDAVFileCounterdraws the next number and consumes it. The number cannot be given back, and none of your files will carry it. Use it only in recovery situations, never to look at a value. The older pathgetCurrentFileCounterForBnrdoes the same thing and still works, but is deprecated - its name reads like a query although the call changes data.