Developer
Menü

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

FeldTypBeschreibung
trip_idstringFahrt für Fahrt im Nahverkehr
service_datestringBetriebstag (eine Fahrt nach Mitternacht gehört noch zum Vortag)
lineobject{ id, name, long_name, mode, color, text_color }, mode siehe unten
operator?object{ id, name }, der Verkehrsbetrieb
destination?stringZiel 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?stringZiel im vollen Wortlaut des Verkehrsbetriebs
stopobject{ id, name, full_name, platform }: Steig bzw. Gleis, an dem gehalten wird; name gekürzt wie destination
departureobject{ scheduled, expected, delay } (bei Ankünften arrival)
cancelledbooleanFahrt oder Halt fällt aus
realtime?stringlive (der Betrieb meldet diesen Halt), propagated (aus der letzten Meldung davor), null (nur Fahrplan)
boardingstringEinsteigen: regular, none (nur Ausstieg), on_request (Bedarfshalt, beim Fahrpersonal melden), phone (vorher beim Betrieb anmelden)
alightingstringAussteigen, Werte wie boarding; none heißt: hier nur Einstieg
on_requestbooleanBedarfshalt: 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

FeldTypBeschreibung
idstringKennung der Meldung
title?stringÜberschrift
text?stringMeldungstext
url?stringWeitere Informationen
cause?stringtechnical_problem, strike, accident, weather, maintenance, construction, police_activity, medical_emergency …
effect?stringno_service, reduced_service, significant_delays, detour, modified_service, stop_moved, accessibility_issue …
active_periodsobject[]{ from, until }
affectedobject{ operators, lines, stops, trips }: Kennungen, je höchstens 50. Nennt eine Meldung nur Fahrten, stehen deren Linien und Betriebe trotzdem hier

Überblick

GET/v1/transitEimer standard

Stand des Fahrplans und der Echtzeit, Umfang und Verkehrsmittel.

Antwort

Objekt { timetable: { updated, publisher, operators, stops, trips }, realtime: { updated, trips, alerts }, modes, attribution }

Beispiel

curl
curl "https://developer.bahnhoftafel.de/v1/transit" \
  -H "Authorization: Bearer $BT_SCHLUESSEL"
JavaScript
const antwort = await fetch("https://developer.bahnhoftafel.de/v1/transit", {
  method: "GET",
  headers: { Authorization: `Bearer ${process.env.BT_SCHLUESSEL}`, },
});
const daten = await antwort.json();
Python
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

GET/v1/transit/operatorsEimer standard

Alle Verkehrsbetriebe im Fahrplan, mit der Zahl ihrer Linien.

Query-Parameter

FeldTypBeschreibung
querystringNur 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
curl "https://developer.bahnhoftafel.de/v1/transit/operators" \
  -H "Authorization: Bearer $BT_SCHLUESSEL"
JavaScript
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();
Python
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

GET/v1/transit/operators/{operator_id}Eimer standard

Ein Verkehrsbetrieb und alle seine Linien.

Pfad-Parameter

FeldTypBeschreibung
operator_idPflichtstringKennung aus Verkehrsbetriebe

Antwort

Objekt { id, name, url, lines: [{ id, name, long_name, mode, color, text_color }] }

Beispiel

curl
curl "https://developer.bahnhoftafel.de/v1/transit/operators/operator_id" \
  -H "Authorization: Bearer $BT_SCHLUESSEL"
JavaScript
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();
Python
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

GET/v1/transit/stopsEimer standard

Haltestellen 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

FeldTypBeschreibung
querystringName oder Teil davon
latnumberBreite (mit lon statt query)47 bis 56
lonnumberLänge5 bis 16
radiusintegerUmkreis in MeternStandard: 50050 bis 3000
limitintegerHö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
curl "https://developer.bahnhoftafel.de/v1/transit/stops" \
  -H "Authorization: Bearer $BT_SCHLUESSEL"
JavaScript
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();
Python
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

GET/v1/transit/stops/{stop_id}Eimer standard

Eine Haltestelle mit ihren Steigen bzw. Gleisen.

Pfad-Parameter

FeldTypBeschreibung
stop_idPflichtstringKennung aus Haltestellen suchen

Antwort

Objekt { id, name, kind, location, parent, platforms: [{ id, name, platform, location }] }

Beispiel

curl
curl "https://developer.bahnhoftafel.de/v1/transit/stops/stop_id" \
  -H "Authorization: Bearer $BT_SCHLUESSEL"
JavaScript
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();
Python
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

GET/v1/transit/stops/{stop_id}/departuresEimer standard

Abfahrten an einer Haltestelle und allen ihren Steigen, mit Echtzeit, wo der Betrieb sie liefert.

Pfad-Parameter

FeldTypBeschreibung
stop_idPflichtstringKennung der Haltestelle oder eines Steigs

Query-Parameter

FeldTypBeschreibung
whenISO 8601Ab diesem Zeitpunkt (ISO 8601), Standard jetzt
durationintegerZeitraum in MinutenStandard: 605 bis 240
modesstring[]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
linesstring[]Nur diese Linien (Name, z. B. M10,S3)
exclude_modesstring[]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_linesstring[]Alle außer diesen Linien
operatorsstring[]Nur diese Verkehrsbetriebe (id aus Verkehrsbetriebe)
arrivalsboolAnkünfte statt AbfahrtenStandard: false
limitintegerHö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
curl "https://developer.bahnhoftafel.de/v1/transit/stops/stop_id/departures" \
  -H "Authorization: Bearer $BT_SCHLUESSEL"
JavaScript
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();
Python
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

GET/v1/transit/trips/{trip_id}Eimer standard

Alle Halte einer Fahrt mit Plan- und Echtzeit.

Pfad-Parameter

FeldTypBeschreibung
trip_idPflichtstringaus einer Abfahrt

Query-Parameter

FeldTypBeschreibung
datestringBetriebstag 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
curl "https://developer.bahnhoftafel.de/v1/transit/trips/b2ViYh8yfCNWTiMxI1NUIzE3OTIwNjk4OTgj…" \
  -H "Authorization: Bearer $BT_SCHLUESSEL"
JavaScript
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();
Python
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

GET/v1/transit/trips/{trip_id}/calendar.icsEimer standard

Ein Termin für den Kalender vom Einstieg bis zum Ausstieg, mit Steig, Halten unterwegs, Hinweis auf Bedarfshalte und auf Wunsch einer Erinnerung.

Pfad-Parameter

FeldTypBeschreibung
trip_idPflichtstringaus einer Abfahrt

Query-Parameter

FeldTypBeschreibung
datestringBetriebstag JJJJ-MM-TT, Standard heute
fromstringEinsteigen an diesem Halt (Kennung aus der Fahrt), Standard: erster Halt
tostringAussteigen an diesem Halt, Standard: letzter Halt
reminderintegerErinnerung 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
curl "https://developer.bahnhoftafel.de/v1/transit/trips/b2ViYh8yfCNWTiMxI1NUIzE3OTIwNjk4OTgj…/calendar.ics" \
  -H "Authorization: Bearer $BT_SCHLUESSEL"
JavaScript
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();
Python
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

GET/v1/transit/trips/{trip_id}/route.gpxEimer standard

Die 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

FeldTypBeschreibung
trip_idPflichtstringaus einer Abfahrt

Query-Parameter

FeldTypBeschreibung
datestringBetriebstag JJJJ-MM-TT, Standard heute

Antwort

application/gpx+xml, Datei fahrt.gpx (GPX 1.1)

Beispiel

curl
curl "https://developer.bahnhoftafel.de/v1/transit/trips/b2ViYh8yfCNWTiMxI1NUIzE3OTIwNjk4OTgj…/route.gpx" \
  -H "Authorization: Bearer $BT_SCHLUESSEL"
JavaScript
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();
Python
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

GET/v1/transit/alertsEimer standard

Aktuelle Meldungen der Verkehrsbetriebe: Umleitungen, Ausfälle, Bauarbeiten, verlegte Haltestellen.

Query-Parameter

FeldTypBeschreibung
operatorstringNur für diesen Betrieb
linestringNur für diese Linie (Kennung)
stopstringNur für diese Haltestelle und ihre Steige
tripstringNur für diese Fahrt
limitintegerHöchstens so vieleStandard: 501 bis 200

Antwort

Liste von Störungsmeldung

Beispiel

curl
curl "https://developer.bahnhoftafel.de/v1/transit/alerts" \
  -H "Authorization: Bearer $BT_SCHLUESSEL"
JavaScript
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();
Python
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()