Skip to content

Getting Started

Ein typischer EFA-Workflow durchläuft immer drei Schritte: suchen → verifizieren → abfragen. Diese Seite zeigt das Minimum an einem konkreten Beispiel — ohne irgendeine der optionalen Komplexitäten.

Ausgangslage

  • Base-URL Ihrer EFA-Instanz (je nach Betreiber): https://server:port/virtuellesVerzeichnis/
  • Pflicht-Parameter für JSON-Antwort: outputFormat=JSON

TIP

Falls Sie die Schnittstelle nur ausprobieren wollen, eignet sich der EFA des VRR öffentlich unter https://openservice.vrr.de/vrr/ — beachten Sie dort Rate-Limits.

Schritt 1 — Haltestelle suchen

Der User hat „Essen Hbf" eingetippt. StopFinder-Request wandelt das in eine verifizierte DHID.

GET /XML_STOPFINDER_REQUEST
    ?outputFormat=JSON
    &type_sf=any
    &name_sf=Essen%20Hbf
    &anyObjFilter_sf=2
    &rMethod=PREFIXRATIO

Antwort (gekürzt):

json
{
  "locations": [
    { "id": "de:05113:9009", "name": "Essen Hbf", "isBest": true, "matchQuality": 950 }
  ]
}

Den id-Wert aus isBest: true merken — das ist der Einstieg für alles Weitere.

Schritt 2 — Abfahrten für diese Haltestelle

Mit der ID direkt in den DM-Request:

GET /XML_DM_REQUEST
    ?outputFormat=JSON
    &mode=direct
    &useProxFootSearch=0
    &type_dm=any
    &name_dm=de:05113:9009
    &limit=10
    &useRealtime=1

Antwort (gekürzt):

json
{
  "departureList": [
    {
      "servingLine": { "name": "196", "direction": "Essen Kray", "mot": 5 },
      "platform": "1",
      "departureTimePlanned": "2025-01-25T08:22:00Z",
      "departureTimeEstimated": "2025-01-25T08:24:00Z",
      "realtimeStatus": "MONITORED"
    }
  ]
}

Schritt 3 — Kompletter Code

Das Ganze als JavaScript-Funktion:

js
const base = 'https://server:port/virtuellesVerzeichnis'

async function resolveStop(query) {
  const usp = new URLSearchParams({
    outputFormat: 'JSON',
    type_sf: 'any',
    name_sf: query,
    anyObjFilter_sf: '2',
    anySigWhenPerfectNoOtherMatches: '1'
  })
  const res = await fetch(`${base}/XML_STOPFINDER_REQUEST?${usp}`)
  const data = await res.json()
  return data.locations.find(l => l.isBest)?.id ?? null
}

async function nextDepartures(stopId, limit = 10) {
  const usp = new URLSearchParams({
    outputFormat: 'JSON',
    mode: 'direct',
    useProxFootSearch: '0',
    type_dm: 'any',
    name_dm: stopId,
    limit: String(limit),
    useRealtime: '1'
  })
  const res = await fetch(`${base}/XML_DM_REQUEST?${usp}`)
  const data = await res.json()
  return data.departureList
}

// Nutzung:
const id = await resolveStop('Essen Hbf')
if (id) {
  const departures = await nextDepartures(id)
  console.log(departures)
}

Nächste Schritte

  • Verbindung berechnen: Trip-Request — Start + Ziel, ggf. mit Echtzeit und Accessibility.
  • Umkreis­suche auf der Karte: CoordInfo-Request — Halte und POIs in einer Bounding-Box.
  • Liniennetz visualisieren: Geoobject-Request — Linien­geometrie + Halte für eine Linie.
  • Fehler sauber behandeln: Error HandlingsystemMessages[] und Retry-Strategie.

Cheat-Sheet — die Parameter­muster

KonzeptKurzReferenz
Punkt (Halt/Adresse/POI)type_<usage>=any|coord, name_<usage>=…Point-Input
Linieline=<Netz>:<Nummer>:<Ergänzung>:<Richtung>Line-Input
ZeititdDate=YYYYMMDD, itdTime=HHMMDatum & Uhrzeit
VerkehrsmittelexclMOT_<ID>, inclMOT_<ID>MOT-IDs
ObjekttypanyObjFilter_<usage>=<Bitmaske>Objekttypen
MakrostripReductionMacro=1, calcBicycleMacro=onMakros
JSON-AusgabeoutputFormat=JSONGemeinsame Parameter