Skip to content

Track access charges and capacity

POST /v1/route can estimate what the route’s train paths cost: the km on each infrastructure manager’s (IM’s) track times the IM’s published price per train-km for the train’s market segment. It can also report capacity indicators along the route: where it is single track, double track or more, the RINF line category and the line speed. Both are opt-in and come with the route you asked for, without searching it again. They don’t change what a request counts as (one request per leg).

Terminal window
curl -X POST -H "Authorization: Bearer $RAIL_API_KEY" -H "Content-Type: application/json" \
https://api.routing.gleisklar.de/v1/route -d '{
"from": { "station": "AH" }, "to": { "station": "8500010" },
"profile": "freight-electric-de",
"charges": { "gross_weight_t": 1800, "timetable_year": 2026 },
"include": ["capacity"]
}'

(Hamburg Hbf by its DS100 code to Basel SBB by its UIC code; find codes by name with GET /v1/places?q=.) Giving charges includes the estimate; "include": ["charges"] alone does too, with the defaults. All charges fields are optional; "charges": {} is a freight train of the vehicle’s mass_t in the timetable year covering today.

FieldMeaning
train_typefreight (default), light_engine (a locomotive without wagons; DB InfraGO Lokfahrt) or passenger
gross_weight_tTrain weight, compared to the segments’ weight limits. Default: vehicle.mass_t if the vehicle is of the same train type, else a typical value (with a warning)
segmentA segment id from the price table, instead of choosing by train type and weight, e.g. gefahrgutganzzug, gueternahverkehr, standard_schnell, standard_z_flex
timetable_year or dateThe price table’s timetable year, or a travel date (YYYY-MM-DD) whose year is used. Default: today’s
adjustmentsSurcharge or rebate ids to apply instead of the table’s defaults; [] = none

Timetable years. The working timetable changes at midnight on the second Saturday in December (Directive 2012/34/EU). Timetable year 2026 runs from 14 December 2025 to 12 December 2026, 2027 from 13 December 2026. A date of 13 December 2026 therefore uses the 2027 prices.

Each route (the best one and any alternatives) gets its own charges:

"charges": {
"estimate": true,
"disclaimer": "An estimate, not a quote: …",
"timetable_year": 2026, "timetable_year_source": "timetable_year",
"timetable_period_from": "2025-12-14", "timetable_period_to": "2026-12-12",
"train_type": "freight", "gross_weight_t": 1800, "gross_weight_source": "charges",
"total": 2602.0, "currency": "EUR",
"totals": [{ "currency": "EUR", "amount": 2602.0, "estimated_km": 747.7 }],
"distance_km": 752.4, "estimated_km": 747.7, "not_estimated_km": 4.7, "complete": false,
"stretches": [
{ "im": "DB InfraGO", "im_code": "0080", "im_source": "rinf", "from_km": 0, "to_km": 747.7,
"distance_km": 747.7, "estimated": true, "table": "0080-2026", "segment": "standard",
"segment_name": "Standard", "base_price_per_train_km": 3.48, "price_per_train_km": 3.48,
"amount": 2602.0, "currency": "EUR", "unit": "train_km", "source": { "title": "…", "url": "…" },
"needs_review": true },
{ "im": "SBB Infrastruktur", "im_code": "0085", "im_source": "rinf", "from_km": 747.7, "to_km": 752.4,
"distance_km": 4.7, "estimated": false, "reason": "no price table for SBB Infrastruktur (IM 0085)" }
],
"not_estimated": [{ "im": "SBB Infrastruktur", "im_code": "0085", "distance_km": 4.7,
"reason": "no price table for SBB Infrastruktur (IM 0085)" }],
"tables": [{ "id": "0080-2026", "status": "approved", "version": "…", "sources": [ … ], "notes": [ … ], … }],
"needs_review": true,
"warnings": []
}

(Illustrative values.)

  • stretches has one entry per stretch of infrastructure_managers (see routes across borders), in travel order. An estimated stretch costs distance_km × price_per_train_km, rounded to the cent. price_per_train_km is the segment’s price plus any adjustments.
  • Not estimated, never guessed. A stretch is left out of the total, with estimated: false, a reason and its km in not_estimated, if its IM has no price table (or none for that timetable year), if the IM is known only from an OpenStreetMap operator tag without a RINF code, or if the IM is unknown. complete is true only when every km is estimated.
  • tables lists every price table used, with its version, its status and its sources (URL, document, date retrieved) and notes. A table with status: provisional adds a warning.
  • total and currency are set when every estimated stretch has the same currency; totals has one entry per currency.
TableIMTimetable yearStatusSource
0080-2026DB InfraGO2026approvedINB 2026 Anlage 5.3a Liste der Entgelte, as of 23.07.2026 (prices re-approved by the Bundesnetzagentur on 22.07.2026)
0080-2027DB InfraGO2027provisionalINB 2027 Anlage 5.3a, as of 14.12.2025: the prices DB InfraGO applied for. Not yet approved on 4 November 2026

DB InfraGO freight segments (EUR per train-km):

Segment idSegmentChosen20262027 (requested)
standardStandardfreight, up to 3,000 t3.484.44
sehr_schwerSehr schwerfreight, over 3,000 t5.046.09
lokfahrtLokfahrtlight_engine2.072.68
gefahrgutganzzugGefahrgutganzzug (dangerous goods block train)by segment4.255.54
gueternahverkehrGüternahverkehr (≤ 75 km, ≤ 370 m, ≤ 3,000 t)by segment2.072.68

The Z-Flex, R-Flex, Express and Schnell variants of these segments (e.g. standard_schnell, gefahrgutganzzug_z_flex) can be requested by segment. Express and R-Flex no longer exist for freight in 2027. DB InfraGO’s weight limit is the weight of the wagons, without the locomotive. gross_weight_t is compared to it as given.

For 2026 the table also has the federal freight subsidy (Trassenpreisförderung) as opt-in adjustments: trafoeg_2026_h1 (−26.5 %, 14.12.2025–30.06.2026) and trafoeg_2026_h2 (−47.7 %, 01.07.2026–30.11.2026). They are approximations: DB InfraGO publishes the subsidy per segment in EUR/train-km, and it is paid out of the federal budget on the invoice. No rate has been published for 2027.

Prices for other IMs will follow as tables are added. Each table is one file per IM and timetable year, built into the service and checked when it is built.

"capacity": {
"stretches": [
{ "from_km": 0, "to_km": 41.2, "distance_km": 41.2, "tracks": 2, "layout": "double", "source": "osm",
"min_speed_kmh": 80, "max_speed_kmh": 160, "speed_known_km": 41.2 },
{ "from_km": 41.2, "to_km": 63.0, "distance_km": 21.8, "tracks": 1, "layout": "single", "source": "rinf",
"min_speed_kmh": 100, "max_speed_kmh": 120, "speed_known_km": 21.8 }
],
"line_categories": [{ "from_km": 0, "to_km": 63.0, "distance_km": 63.0, "category": "P4;F1", "source": "rinf" }],
"summary": { "single_track_km": 21.8, "double_track_km": 41.2, "multiple_track_km": 0, "unknown_tracks_km": 0,
"single_track_share": 0.346, "by_line_category": [{ "category": "P4;F1", "distance_km": 63.0 }] },
"note": "…"
}

(Illustrative values.)

  • Tracks come from the RINF section’s number of running tracks where the data version has it. Otherwise they are counted in OpenStreetMap as for line properties (GET /v1/infra/lines/{line}): every 100 m, the parallel tracks carrying the line number. Track without a line number is unknown.
  • Line categories are the TSI line categories RINF reports (only on track matched to RINF).
  • Line speed is as in sections: the stretch’s lowest and highest known speed.

Stretches under 200 m are ignored and unknown stretches under 1 km are bridged, as for countries and IMs. These are indicators from the data, not a capacity statement. Utilisation, congested-line declarations and timetable capacity are not in the data. See the IM’s network statement for those.