Verkehrsbetriebe
Alle Verkehrsbetriebe in Deutschland in einem Fahrplan: Bus, Straßenbahn, U-Bahn, S-Bahn, Regional- und Fernverkehr, Fähren und Seilbahnen. Mit Verspätungen, Ausfällen und Störungsmeldungen in Echtzeit, wo die Betriebe sie liefern.
Objekte
Objekt Abfahrt im Nahverkehr
| Feld | Typ | Beschreibung |
|---|---|---|
trip_id | string | Fahrt für Fahrt im Nahverkehr |
service_date | string | Betriebstag (eine Fahrt nach Mitternacht gehört noch zum Vortag) |
line | object | { id, name, long_name, mode, color, text_color }, mode siehe unten |
operator | ?object | { id, name }, der Verkehrsbetrieb |
destination | ?string | Ziel ohne Kürzel und Abkürzungen: „Wannsee“ statt „S Wannsee Bhf“, „Warschauer Straße“ statt „S+U Warschauer Str.“, „Köln Hauptbahnhof“ statt „Köln Hbf“ |
destination_full | ?string | Ziel im vollen Wortlaut des Verkehrsbetriebs |
stop | object | { id, name, full_name, platform }: Steig bzw. Gleis, an dem gehalten wird; name gekürzt wie destination |
departure | object | { scheduled, expected, delay } (bei Ankünften arrival) |
cancelled | boolean | Fahrt oder Halt fällt aus |
realtime | ?string | live (der Betrieb meldet diesen Halt), propagated (aus der letzten Meldung davor), null (nur Fahrplan) |
boarding | string | Einsteigen: regular, none (nur Ausstieg), on_request (Bedarfshalt, beim Fahrpersonal melden), phone (vorher beim Betrieb anmelden) |
alighting | string | Aussteigen, Werte wie boarding; none heißt: hier nur Einstieg |
on_request | boolean | Bedarfshalt: hält nur, wenn jemand ein- oder aussteigen will |
{
"trip_id": "1883727",
"service_date": "2026-10-15",
"line": {
"id": "6711",
"name": "S7",
"long_name": null,
"mode": "suburban",
"color": "#816DA6",
"text_color": "#FFFFFF"
},
"operator": {
"id": "135",
"name": "S Bahn Berlin GmbH"
},
"destination": "Wannsee",
"destination_full": "S Wannsee Bhf",
"stop": {
"id": "244359",
"name": "Warschauer Straße",
"full_name": "S+U Warschauer Str.",
"platform": "4"
},
"departure": {
"scheduled": "2026-10-15T22:23:00+02:00",
"expected": "2026-10-15T22:24:00+02:00",
"delay": 1
},
"cancelled": false,
"realtime": "live",
"boarding": "regular",
"alighting": "regular",
"on_request": false
}Objekt Störungsmeldung
| Feld | Typ | Beschreibung |
|---|---|---|
id | string | Kennung der Meldung |
title | ?string | Überschrift |
text | ?string | Meldungstext |
url | ?string | Weitere Informationen |
cause | ?string | technical_problem, strike, accident, weather, maintenance, construction, police_activity, medical_emergency … |
effect | ?string | no_service, reduced_service, significant_delays, detour, modified_service, stop_moved, accessibility_issue … |
active_periods | object[] | { from, until } |
affected | object | { operators, lines, stops, trips }: Kennungen, je höchstens 50. Nennt eine Meldung nur Fahrten, stehen deren Linien und Betriebe trotzdem hier |
Überblick
/v1/transitEimer standardStand des Fahrplans und der Echtzeit, Umfang und Verkehrsmittel.
Antwort
Objekt { timetable: { updated, publisher, operators, stops, trips }, realtime: { updated, trips, alerts }, modes, attribution }
Beispiel
curl "https://developer.bahnhoftafel.de/v1/transit" \
-H "Authorization: Bearer $BT_SCHLUESSEL"const antwort = await fetch("https://developer.bahnhoftafel.de/v1/transit", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.BT_SCHLUESSEL}`, },
});
const daten = await antwort.json();import os, requests
antwort = requests.get(
"https://developer.bahnhoftafel.de/v1/transit",
headers={"Authorization": f"Bearer {os.environ['BT_SCHLUESSEL']}"},
timeout=30,
)
daten = antwort.json()Verkehrsbetriebe
/v1/transit/operatorsEimer standardAlle Verkehrsbetriebe im Fahrplan, mit der Zahl ihrer Linien.
Query-Parameter
| Feld | Typ | Beschreibung |
|---|---|---|
query | string | Nur Betriebe, deren Name das enthält, z. B. BVG oder Rheinbahn |
Antwort
Liste von { id, name, url, lines }
[
{
"id": "78",
"name": "Berliner Verkehrsbetriebe",
"url": "https://www.bahn.de",
"lines": 254
}
]Beispiel
curl "https://developer.bahnhoftafel.de/v1/transit/operators" \
-H "Authorization: Bearer $BT_SCHLUESSEL"const antwort = await fetch("https://developer.bahnhoftafel.de/v1/transit/operators", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.BT_SCHLUESSEL}`, },
});
const daten = await antwort.json();import os, requests
antwort = requests.get(
"https://developer.bahnhoftafel.de/v1/transit/operators",
headers={"Authorization": f"Bearer {os.environ['BT_SCHLUESSEL']}"},
timeout=30,
)
daten = antwort.json()Verkehrsbetrieb mit Linien
/v1/transit/operators/{operator_id}Eimer standardEin Verkehrsbetrieb und alle seine Linien.
Pfad-Parameter
| Feld | Typ | Beschreibung |
|---|---|---|
operator_idPflicht | string | Kennung aus Verkehrsbetriebe |
Antwort
Objekt { id, name, url, lines: [{ id, name, long_name, mode, color, text_color }] }
Beispiel
curl "https://developer.bahnhoftafel.de/v1/transit/operators/operator_id" \
-H "Authorization: Bearer $BT_SCHLUESSEL"const antwort = await fetch("https://developer.bahnhoftafel.de/v1/transit/operators/operator_id", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.BT_SCHLUESSEL}`, },
});
const daten = await antwort.json();import os, requests
antwort = requests.get(
"https://developer.bahnhoftafel.de/v1/transit/operators/operator_id",
headers={"Authorization": f"Bearer {os.environ['BT_SCHLUESSEL']}"},
timeout=30,
)
daten = antwort.json()Haltestellen suchen
/v1/transit/stopsEimer standardHaltestellen aller Verkehrsmittel nach Name oder in der Nähe eines Punktes. Rund 660 000 Halte in Deutschland, von der Dorfbushaltestelle bis zum Hauptbahnhof.
Query-Parameter
| Feld | Typ | Beschreibung |
|---|---|---|
query | string | Name oder Teil davon |
lat | number | Breite (mit lon statt query)47 bis 56 |
lon | number | Länge5 bis 16 |
radius | integer | Umkreis in MeternStandard: 50050 bis 3000 |
limit | integer | Höchstens so vieleStandard: 151 bis 50 |
Antwort
Liste von { id, name, full_name, kind, location, distance_m? }; name wie auf der Anzeige, full_name im Wortlaut des Betriebs; kind ist station (mit Steigen) oder stop
[
{
"id": "379152",
"name": "Warschauer Straße",
"full_name": "S+U Warschauer Str. (Berlin)",
"kind": "station",
"location": {
"lat": 52.505764,
"lon": 13.449159
},
"distance_m": 47
}
]Beispiel
curl "https://developer.bahnhoftafel.de/v1/transit/stops" \
-H "Authorization: Bearer $BT_SCHLUESSEL"const antwort = await fetch("https://developer.bahnhoftafel.de/v1/transit/stops", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.BT_SCHLUESSEL}`, },
});
const daten = await antwort.json();import os, requests
antwort = requests.get(
"https://developer.bahnhoftafel.de/v1/transit/stops",
headers={"Authorization": f"Bearer {os.environ['BT_SCHLUESSEL']}"},
timeout=30,
)
daten = antwort.json()Haltestelle mit Steigen
/v1/transit/stops/{stop_id}Eimer standardEine Haltestelle mit ihren Steigen bzw. Gleisen.
Pfad-Parameter
| Feld | Typ | Beschreibung |
|---|---|---|
stop_idPflicht | string | Kennung aus Haltestellen suchen |
Antwort
Objekt { id, name, kind, location, parent, platforms: [{ id, name, platform, location }] }
Beispiel
curl "https://developer.bahnhoftafel.de/v1/transit/stops/stop_id" \
-H "Authorization: Bearer $BT_SCHLUESSEL"const antwort = await fetch("https://developer.bahnhoftafel.de/v1/transit/stops/stop_id", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.BT_SCHLUESSEL}`, },
});
const daten = await antwort.json();import os, requests
antwort = requests.get(
"https://developer.bahnhoftafel.de/v1/transit/stops/stop_id",
headers={"Authorization": f"Bearer {os.environ['BT_SCHLUESSEL']}"},
timeout=30,
)
daten = antwort.json()Abfahrten im Nahverkehr
/v1/transit/stops/{stop_id}/departuresEimer standardAbfahrten an einer Haltestelle und allen ihren Steigen, mit Echtzeit, wo der Betrieb sie liefert.
Pfad-Parameter
| Feld | Typ | Beschreibung |
|---|---|---|
stop_idPflicht | string | Kennung der Haltestelle oder eines Steigs |
Query-Parameter
| Feld | Typ | Beschreibung |
|---|---|---|
when | ISO 8601 | Ab diesem Zeitpunkt (ISO 8601), Standard jetzt |
duration | integer | Zeitraum in MinutenStandard: 605 bis 240 |
modes | string[] | Nur diese Verkehrsmittellong_distance Fernverkehr, regional Regionalverkehr, suburban S-Bahn, subway U-Bahn, Stadtbahn, tram Straßenbahn, bus Bus, coach Fernbus, ferry Fähre, aerial_lift Seilbahn, funicular Standseilbahn, taxi Rufbus, Anrufsammeltaxi, other Sonstiges |
lines | string[] | Nur diese Linien (Name, z. B. M10,S3) |
exclude_modes | string[] | Alle außer diesen Verkehrsmitteln, z. B. bus, um nur Schiene zu sehenlong_distance Fernverkehr, regional Regionalverkehr, suburban S-Bahn, subway U-Bahn, Stadtbahn, tram Straßenbahn, bus Bus, coach Fernbus, ferry Fähre, aerial_lift Seilbahn, funicular Standseilbahn, taxi Rufbus, Anrufsammeltaxi, other Sonstiges |
exclude_lines | string[] | Alle außer diesen Linien |
operators | string[] | Nur diese Verkehrsbetriebe (id aus Verkehrsbetriebe) |
arrivals | bool | Ankünfte statt AbfahrtenStandard: false |
limit | integer | Höchstens so vieleStandard: 601 bis 200 |
Antwort
Objekt { stop, departures: Abfahrt im Nahverkehr[] } (bei arrivals=true: arrivals)
{
"stop": {
"id": "379152",
"name": "Warschauer Straße",
"full_name": "S+U Warschauer Str. (Berlin)",
"kind": "station",
"location": {
"lat": 52.505764,
"lon": 13.449159
}
},
"departures": [
{
"trip_id": "1883727",
"service_date": "2026-10-15",
"line": {
"id": "6711",
"name": "S7",
"long_name": null,
"mode": "suburban",
"color": "#816DA6",
"text_color": "#FFFFFF"
},
"operator": {
"id": "135",
"name": "S Bahn Berlin GmbH"
},
"destination": "Wannsee",
"destination_full": "S Wannsee Bhf",
"stop": {
"id": "244359",
"name": "Warschauer Straße",
"full_name": "S+U Warschauer Str.",
"platform": "4"
},
"departure": {
"scheduled": "2026-10-15T22:23:00+02:00",
"expected": "2026-10-15T22:24:00+02:00",
"delay": 1
},
"cancelled": false,
"realtime": "live",
"boarding": "regular",
"alighting": "regular",
"on_request": false
}
]
}Beispiel
curl "https://developer.bahnhoftafel.de/v1/transit/stops/stop_id/departures" \
-H "Authorization: Bearer $BT_SCHLUESSEL"const antwort = await fetch("https://developer.bahnhoftafel.de/v1/transit/stops/stop_id/departures", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.BT_SCHLUESSEL}`, },
});
const daten = await antwort.json();import os, requests
antwort = requests.get(
"https://developer.bahnhoftafel.de/v1/transit/stops/stop_id/departures",
headers={"Authorization": f"Bearer {os.environ['BT_SCHLUESSEL']}"},
timeout=30,
)
daten = antwort.json()Fahrt im Nahverkehr
/v1/transit/trips/{trip_id}Eimer standardAlle Halte einer Fahrt mit Plan- und Echtzeit.
Pfad-Parameter
| Feld | Typ | Beschreibung |
|---|---|---|
trip_idPflicht | string | aus einer Abfahrt |
Query-Parameter
| Feld | Typ | Beschreibung |
|---|---|---|
date | string | Betriebstag JJJJ-MM-TT, Standard heute |
Antwort
Objekt { trip_id, service_date, runs, line, operator, destination, destination_full, cancelled, stops: [{ id, name, full_name, station, platform, location, arrival, departure, cancelled, realtime, boarding, alighting, on_request }] }. Bedarfshalte haben on_request: true; boarding: "none" heißt nur Ausstieg, alighting: "none" nur Einstieg
Beispiel
curl "https://developer.bahnhoftafel.de/v1/transit/trips/b2ViYh8yfCNWTiMxI1NUIzE3OTIwNjk4OTgj…" \
-H "Authorization: Bearer $BT_SCHLUESSEL"const antwort = await fetch("https://developer.bahnhoftafel.de/v1/transit/trips/b2ViYh8yfCNWTiMxI1NUIzE3OTIwNjk4OTgj…", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.BT_SCHLUESSEL}`, },
});
const daten = await antwort.json();import os, requests
antwort = requests.get(
"https://developer.bahnhoftafel.de/v1/transit/trips/b2ViYh8yfCNWTiMxI1NUIzE3OTIwNjk4OTgj…",
headers={"Authorization": f"Bearer {os.environ['BT_SCHLUESSEL']}"},
timeout=30,
)
daten = antwort.json()Fahrt im Nahverkehr als Kalendertermin
/v1/transit/trips/{trip_id}/calendar.icsEimer standardEin Termin für den Kalender vom Einstieg bis zum Ausstieg, mit Steig, Halten unterwegs, Hinweis auf Bedarfshalte und auf Wunsch einer Erinnerung.
Pfad-Parameter
| Feld | Typ | Beschreibung |
|---|---|---|
trip_idPflicht | string | aus einer Abfahrt |
Query-Parameter
| Feld | Typ | Beschreibung |
|---|---|---|
date | string | Betriebstag JJJJ-MM-TT, Standard heute |
from | string | Einsteigen an diesem Halt (Kennung aus der Fahrt), Standard: erster Halt |
to | string | Aussteigen an diesem Halt, Standard: letzter Halt |
reminder | integer | Erinnerung so viele Minuten vor der Abfahrt0 bis 240 |
Antwort
text/calendar, Datei fahrt.ics mit einem Termin (Planzeiten; eine Verspätung beim Abruf steht in der Beschreibung)
Beispiel
curl "https://developer.bahnhoftafel.de/v1/transit/trips/b2ViYh8yfCNWTiMxI1NUIzE3OTIwNjk4OTgj…/calendar.ics" \
-H "Authorization: Bearer $BT_SCHLUESSEL"const antwort = await fetch("https://developer.bahnhoftafel.de/v1/transit/trips/b2ViYh8yfCNWTiMxI1NUIzE3OTIwNjk4OTgj…/calendar.ics", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.BT_SCHLUESSEL}`, },
});
const daten = await antwort.json();import os, requests
antwort = requests.get(
"https://developer.bahnhoftafel.de/v1/transit/trips/b2ViYh8yfCNWTiMxI1NUIzE3OTIwNjk4OTgj…/calendar.ics",
headers={"Authorization": f"Bearer {os.environ['BT_SCHLUESSEL']}"},
timeout=30,
)
daten = antwort.json()Fahrt im Nahverkehr als GPX
/v1/transit/trips/{trip_id}/route.gpxEimer standardDie Halte einer Fahrt als GPX-Route mit Wegpunkten und Planzeiten. Der Fahrplan enthält keinen Linienverlauf, deshalb verbindet die Route die Halte direkt.
Pfad-Parameter
| Feld | Typ | Beschreibung |
|---|---|---|
trip_idPflicht | string | aus einer Abfahrt |
Query-Parameter
| Feld | Typ | Beschreibung |
|---|---|---|
date | string | Betriebstag JJJJ-MM-TT, Standard heute |
Antwort
application/gpx+xml, Datei fahrt.gpx (GPX 1.1)
Beispiel
curl "https://developer.bahnhoftafel.de/v1/transit/trips/b2ViYh8yfCNWTiMxI1NUIzE3OTIwNjk4OTgj…/route.gpx" \
-H "Authorization: Bearer $BT_SCHLUESSEL"const antwort = await fetch("https://developer.bahnhoftafel.de/v1/transit/trips/b2ViYh8yfCNWTiMxI1NUIzE3OTIwNjk4OTgj…/route.gpx", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.BT_SCHLUESSEL}`, },
});
const daten = await antwort.json();import os, requests
antwort = requests.get(
"https://developer.bahnhoftafel.de/v1/transit/trips/b2ViYh8yfCNWTiMxI1NUIzE3OTIwNjk4OTgj…/route.gpx",
headers={"Authorization": f"Bearer {os.environ['BT_SCHLUESSEL']}"},
timeout=30,
)
daten = antwort.json()Störungsmeldungen
/v1/transit/alertsEimer standardAktuelle Meldungen der Verkehrsbetriebe: Umleitungen, Ausfälle, Bauarbeiten, verlegte Haltestellen.
Query-Parameter
| Feld | Typ | Beschreibung |
|---|---|---|
operator | string | Nur für diesen Betrieb |
line | string | Nur für diese Linie (Kennung) |
stop | string | Nur für diese Haltestelle und ihre Steige |
trip | string | Nur für diese Fahrt |
limit | integer | Höchstens so vieleStandard: 501 bis 200 |
Antwort
Liste von Störungsmeldung
Beispiel
curl "https://developer.bahnhoftafel.de/v1/transit/alerts" \
-H "Authorization: Bearer $BT_SCHLUESSEL"const antwort = await fetch("https://developer.bahnhoftafel.de/v1/transit/alerts", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.BT_SCHLUESSEL}`, },
});
const daten = await antwort.json();import os, requests
antwort = requests.get(
"https://developer.bahnhoftafel.de/v1/transit/alerts",
headers={"Authorization": f"Bearer {os.environ['BT_SCHLUESSEL']}"},
timeout=30,
)
daten = antwort.json()