Getting started
Create an API key in the dashboard and call the API. A secret key (rr_sk_…) goes in the
Authorization header, on servers only:
curl -H "Authorization: Bearer $RAIL_API_KEY" https://api.routing.gleisklar.de/v1/dataset{ "version": "20261104-0200", "built_at": "2026-11-04T02:41:07Z", "stale": false, "format": …, "nodes": …, "edges": …, "segments": … }(Illustrative values.) Every response names the data version that answered it in the
X-Data-Version header. Errors are problem details; the
API overview has the rules every endpoint shares, and the OpenAPI
document is served at GET /v1/openapi.json.
A first route
Section titled “A first route”Routes are POST /v1/route. Places are stations by code (DS100 AK, RINF UOPID DE000AK or UIC
8000199), coordinates or OpenStreetMap nodes; find a station’s code by name with
GET /v1/places?q=.
curl -H "Authorization: Bearer $RAIL_API_KEY" -H "Content-Type: application/json" \ https://api.routing.gleisklar.de/v1/route -d '{ "from": { "station": "AK" }, "to": { "station": "AL" }, "vehicle": { "electrification": "any" } }'{ "status": "ok", "stops": [ { "name": "Kiel Hauptbahnhof", "kind": "station", "ds100": "AK", "lon": 10.1319, "lat": 54.3146, "snapped": { "lon": 10.13201, "lat": 54.31455, "distance_m": 8.1 } }, { "name": "Lübeck Hauptbahnhof", "kind": "station", "ds100": "AL", "lon": 10.6699, "lat": 53.8676, … } ], "vehicle": { "gauge_mm": 1435, "train_type": "passenger", … }, "routes": [ { "distance_km": 80.3, "duration_min": 58.6, "reversals": 0, "legs": [{ "from": 0, "to": 1, "distance_km": 80.3, "duration_min": 58.6, "reversals": 0 }] } ], "warnings": []}(Shortened, illustrative values.) Geometry, the infrastructure along the route, a
running time estimate, borders and infrastructure
managers and track access charges
come with include, e.g. "include": ["geometry", "sections", "estimate"].
JavaScript / TypeScript
Section titled “JavaScript / TypeScript”npm install @quebi/rail-apiimport { createClient } from "@quebi/rail-api";
const api = createClient({ apiKey: process.env.RAIL_API_KEY });const { results } = await api.places({ q: "Kiel Hbf" });const answer = await api.route({ from: { station: "AK" }, to: { station: "AL" }, vehicle: { electrification: "any" },});Errors are thrown as RailApiError (with the problem’s status, type, title, detail and
errors), or one of its subclasses such as NotFoundError or RateLimitError (with
retryAfter).
For maps, railStyle() from @quebi/rail-api/maplibre builds a MapLibre style
with the railway tiles, the key handling and the required
“© OpenStreetMap contributors” attribution. Use a publishable key (rr_pk_…)
in the browser.
railStyle("speed", { key: "rr_pk_…", basemap: "light" }) adds our own
basemap under the tracks (land, water, roads and place labels, served by the
API with its fonts and icons; flavours light, dark, white, grayscale,
black). Without basemap the tracks are drawn on a plain background.