The protocol of mgate.exe
HAFAS endpoints is not openly (and freely) documented. The following documentation is based on general observations and reverse-engineering.
Note: There are also rest.exe
(a.k.a. "open API", a.k.a. "REST API") endpoints. This documentation is not about them.
Dates are encoded as YYYYMMDD
, time strings as HHMMSS
. These are in the timezone configured on the HAFAS/server side, per endpoint.
Whenever HAFAS returns a time string that exceeds the day the response describes, it will add a "day offset". As an example, when you query departures at 2019-12-12T23:50+01:00
for the next 30 minutes, it will encode the departure at 2019-12-13T00:13+01:00
as 20191212
& 01001300
.
For working code, check out parseDateTime()
.
All endpoints I've seen so far use WGS84. Values are multiplied by 10^6
though, so you would encode {latitude: 1.23, longitude: -2.34}
as {Y: 1230000: X: -2340000}
. There's an optional parameter z
with the elevation.
For working code, check out formatAddress()
.
In many aspects, the API looks and feels like RPCs. You must send queries via HTTP POST
, with the minimal JSON body looking like this:
{
"auth": {
"type": "AID",
"aid": "…" // endpoint-specific authentication token, e.g. `1Rxs112shyHLatUX4fofnmdxK`
},
"ver": "…", // endpoint-specific string, e.g. `1.15`
"ext": "…", // endpoint-specific string, e.g. `BVG.1`
"client": {
"type": "IPA", // might also be `IPH` for "iPhone" or `WEB` for "web client"
"id": "…", // endpoint-specific string, e.g. `BVG`
"name": "…", // endpoint-specific string, e.g. `FahrInfo`
"v": "…" // endpoint-specific string, e.g. `4070700`
},
"lang": "…", // language, sometimes 2-digit (e.g. `de`), sometimes 3-digit (e.g. `deu`)
"svcReqL": [
{
"meth": "…", // name of the API call, supported values depend on the endpoint
"req": {
// actual request parameters…
}
// some endpoints also require this:
"cfg": {
"cfgGrpL": [],
"cfgHash": "…" // endpoint-specific string
}
}
]
}
- The data in
client
must be correct, otherwise HAFAS will reject your request. - HAFAS will return slightly different response formats (and slightly different levels of detail) for different
ver
,ext
andclient.v
values. - All endpoints known support JSON & UTF-8, so make sure to send
Accept: application/json
&Accept-Charset: utf-8
headers. - Most endpoints support at least GZIP compression, so make sure to send a
Accept-Encoding: gzip
header.
For working code, check out request()
.
There are three known types of authentication used among mgate.exe
endpoints.
For working code, check out hafas-client
's request()
, public-transport-enabler
's Java implementation, TripKit
's Swift implementation or marudor.de
's TypeScript implementation.
You can just query these, as long as you send a formally correct request.
checksum
is a message authentication code: You can compute it by hashing the request body and a secret salt.
This secret can be read from the config file inside the accompanying client app. There is no guide for this yet, so please open an issue.
mic
is a message integrity code, the hash of the request body.
mac
is a message authentication code, the hash of mic
and a secret salt.
This secret can be read from the config file inside the accompanying client app. There is no guide for this yet, so please open an issue.
A minimal valid response looks like this:
{
"ver": "…", // endpoint-specific string, e.g. `1.15`
"lang": "…", // language
"ext": "…", // endpoint-specific string, e.g. `BVG.1`
"id": "…", // unique ID for each response?
"svcResL": [
{
"meth": "StationBoard",
"err": "OK",
"res": {
// result of the API call
}
}
]
}
For working code, check out request()
.
todo: generic server error
{
"ver": "…", // endpoint-specific string, e.g. `1.15`
"lang": "…", // language, sometimes 2-digit (e.g. `de`), sometimes 3-digit (e.g. `deu`)
"err": "PARSE", // error code
"errTxt": "…", // error message, not always present
"svcResL": []
}
{
"ver": "…", // endpoint-specific string, e.g. `1.15`
"lang": "…", // language
"ext": "…", // endpoint-specific string, e.g. `BVG.1`
"err": "AUTH", // error code
"errTxt": "…", // error message, not always present
"svcResL": []
}
{
"ver": "…", // endpoint-specific string, e.g. `1.15`
"lang": "…", // language
"ext": "…", // endpoint-specific string, e.g. `BVG.1`
"svcResL": [
{
"meth": "StationBoard",
"err": "…", // error code, e.g. `H9300`
"errTxt": "…", // error message, e.g. `Unknown arrival station`
"res": {}
}
]
}