BetaWie die App ist auch die API in der Beta. Es gibt keine Verfügbarkeitszusage, und Felder und Limits können sich noch ändern.
Die öffentliche API.
Dieselben Daten, die auch die Apps und diese Website verwenden. Ohne Schlüssel abrufbar, CORS ist offen.
Grundregeln
https://api.oeffigo.appAccess-Control-Allow-Origin: *.429 mit Retry-After: 30.no-store. Erfolge je nachdem, wie schnell sich die Daten bewegen: max-age=10 als Regel, 15 für /v1/vehicles, 60 im Browser und 300 am Edge für /v1/history. POST /v1/predictions/batch ist no-store — die Antwort hängt am gesendeten Body und gehört in keinen geteilten Cache. Maßgeblich ist der Cache-Control-Header der jeweiligen Antwort./v2 zählt getrennt und nennt seine Version in jeder Antwort im Header X-OeffiGo-Contract./v2 ist der App-Vertrag, keine offene API/v2 ist der versionierte App-Vertrag. Sein maschinenlesbares Schema steht unter /v2/schema, die aktuelle Routenliste unter /v2/meta; beides ist offen einsehbar. Aufrufen kann man die Datenrouten von außen trotzdem nicht: sie weisen Browser-Anfragen ab und verlangen ein Installations-Token, das nur die Apps erhalten. Diese Routen sind nur für die Apps gedacht./v1 heißtDie hier dokumentierten /v1-Endpunkte sind die offene Fläche: schlichte GETs, CORS erlaubt, ohne Zugangsdaten nutzbar. Sie bleiben. Die Apps selbst sprechen /v2. Zusätzliche Felder können jederzeit auftauchen; ignoriere unbekannte Felder.{ "error": "code" } mit passendem HTTP-Status.Endpunkte
Kurzer Lebenszeichen-Check.
Antwortet mit 200, solange der Worker einen frischen erfolgreichen Zyklus hinter sich hat, sonst mit 503. Gedacht für Monitoring, nicht für Datenabfragen.
Anfrage
curl -s https://api.oeffigo.app/v1/healthAntwort
{
"ok": true,
"version": "5dc1a29",
"predictionsLive": 1312,
"confidentPredictions": 1190
}Betriebszustand aller Komponenten.
Liefert den Gesamtzustand, eine Komponentenliste und je Datenweg eine Erfolgs-Historie in Halbstundenschritten. Die eigenständige Statusseite verbindet diesen Bericht mit externen Prüfungen. Erfolgreiche Datenabrufe sind keine extern gemessene Verfügbarkeit.
Anfrage
curl -s https://api.oeffigo.app/v1/statusAntwort
{
"generatedAt": "2026-07-26T13:25:06.754Z",
"overall": "operational",
"components": [
{ "id": "api", "name": "…", "status": "operational" }
],
"measurement": { "mode": "official_realtime" }
}Zuverlässigkeits-Auswertung aus offiziellen Ist-Zeiten.
Summen, Tagesverlauf, Linien und ein Wochentag×Stunde-Muster. Gezählt werden einzelne Halte, nicht ganze Fahrten. Ein fehlender Datenpunkt gilt nie als Ausfall — Ausfälle stammen ausschließlich aus expliziten Ereignissen.
| Parameter | Typ | Bedeutung |
|---|---|---|
from | ISO date | Beginn des Zeitraums. |
to | ISO date | Ende des Zeitraums. Maximal 366 Tage Spanne. |
line | string | Auf eine Linie einschränken. |
source | string | Auf eine Datenquelle einschränken: wiener_linien, trias, stmk_gtfs_rt. |
Anfrage
curl -s "https://api.oeffigo.app/v1/history?from=2026-07-15&to=2026-07-26&line=U1"Antwort
{
"period": { "from": "2026-07-15", "to": "2026-07-26" },
"totals": {
"onTimeShare": 0.9556,
"avgDelayMin": 0.57,
"late10Share": 0.007
},
"officialRealtime": {
"daily": [ { "day": "2026-07-26", "events": 18109, "on_time_pct": 97.4 } ],
"lines": [ { "line": "U1", "events": 39970, "on_time_pct": 96 } ],
"heatmap": [ { "dow": 1, "hour": 8, "avg_delay_min": 0.6 } ]
}
}- Fünf Minuten am Edge cachebar, unterstützt ETag und 304.
- `dow` ist ISO: 1 = Montag … 7 = Sonntag.
Eigene Verspätungsprognosen aus offizieller Echtzeit.
Nur Einträge mit hoher oder mittlerer Sicherheit. Jeder Eintrag verfällt spätestens acht Minuten nach der letzten echten Beobachtung; ältere Werte werden nicht ausgeliefert. <strong>Ein Filter ist Pflicht</strong>: ohne einen kommt <code>400 missing_query</code>.
| Parameter | Typ | Bedeutung |
|---|---|---|
lat + lon | number | Umkreis, optional mit radius. Einer der vier Filter. |
line | string | Linienlabel, z. B. U1. Einer der vier Filter. |
jid | string | Eine Fahrt-Referenz. Einer der vier Filter. |
jids | string[] | Bis zu 40 Fahrt-Referenzen, komma-getrennt. Einer der vier Filter. |
radius | int | Nur zusammen mit lat + lon. |
limit | int | Höchstens 200. Ersetzt keinen Filter. |
Anfrage
curl -s "https://api.oeffigo.app/v1/predictions?line=U1&limit=50" -H 'If-None-Match: "abc123"'Antwort
{
"generatedAt": "2026-07-26T13:25:06.754Z",
"count": 2,
"predictions": [
{ "jid": "og1.…", "delayMin": 2, "confidence": "high" }
]
}- Antworten tragen ein schwaches ETag. Mit If-None-Match bekommst du ein 304 ohne Body, solange sich der Snapshot nicht geändert hat — die batteriefreundliche Art zu pollen.
Viele Fahrt-Referenzen auf einmal abfragen.
Fahrt-Referenzen sind lang und gehören nicht in eine URL. Für mehr als eine Handvoll ist das der richtige Weg.
Anfrage
curl -s -X POST https://api.oeffigo.app/v1/predictions/batch \
-H 'content-type: application/json' \
-d '{"jids":["og1.…","og1.…"]}'Antwort
{
"generatedAt": "2026-07-26T13:25:06.754Z",
"count": 2,
"predictions": [ … ]
}Begrenzter Kartenausschnitt mit Fahrzeugen.
Verlangt entweder eine Bounding-Box oder eine Liste von Fahrt-Referenzen — ohne Filter gibt es keine Antwort. Einträge sind höchstens acht Minuten alt. Das Feld `source` sagt dir, was ein leeres Ergebnis bedeutet.
| Parameter | Typ | Bedeutung |
|---|---|---|
minLat, minLon, maxLat, maxLon | number | Sichtbarer Kartenausschnitt — alle vier oder keiner. |
jids | string[] | Kommagetrennte Fahrt-Referenzen. Der Server nimmt bis zu 500 an, praktisch begrenzt die URL-Länge auf rund 40. Löst keinen Abruf aus. |
limit | number | 1–1.000, Standard 500. |
Anfrage
curl -s "https://api.oeffigo.app/v1/vehicles?minLat=48.18&minLon=16.30&maxLat=48.24&maxLon=16.42"Antwort
{
"generatedAt": "2026-08-03T19:25:06.754Z",
"count": 242,
"source": "ondemand_live",
"measurementMode": "official_realtime",
"vehicles": [ { "jid": "og1.…", "lat": 48.2, "lon": 16.37 } ]
}- `ondemand_live` mit leerer Liste heißt „gerade keine Fahrzeuge“, nicht „Dienst aus“. `ondemand_capped` heißt „Live-Fahrzeuge vorübergehend nicht verfügbar“.
Wiener U-Bahn-Echtzeit, gecacht.
Nur Stationen aus einer festen Liste; der Endpunkt reicht keine beliebigen Anfragen an den Betreiber-Monitor weiter. Datenquelle: Stadt Wien, CC BY 4.0.
| Parameter | Typ | Bedeutung |
|---|---|---|
diva | int | Stationskennung aus der Liste. |
Anfrage
curl -s "https://api.oeffigo.app/v1/wiener-linien/metro?diva=60200657"Antwort
{
"generatedAt": "2026-08-03T19:16:51.814Z",
"status": "ok",
"departures": [
{ "line": "1", "towards": "Stefan-Fadinger-Platz",
"plannedAt": "2026-08-03T19:23:30.000Z",
"realAt": "2026-08-03T19:26:50.000Z" }
]
}- Die Verspätung steht nicht als Zahl drin — sie ist die Differenz aus
realAtundplannedAt. Beides sind ISO-Zeitstempel, keine Millisekunden. - Kann
503 source_standbyantworten, wenn die Wiener-Linien-Quelle gerade abgeschaltet ist. Probier es dann später erneut.
Servergesteuerte Meldungen für die Apps.
Erlaubt es, Hinweise ohne App-Update auszuspielen. Geschlossene und abgelaufene Meldungen sind nicht enthalten.
Anfrage
curl -s https://api.oeffigo.app/v1/announcementsAntwort
{
"generatedAt": "2026-07-26T13:25:06.754Z",
"announcements": [ { "id": "…", "title": "…", "body": "…" } ]
}Was die API nicht bietet.
Die typisierten Routen, über die die Apps Fahrplan- und Auskunftsdaten holen, sind fest an die Apps gebunden und nicht Teil dieser Dokumentation. Bitte baue nichts, das darauf angewiesen ist.
Fahrt-Referenzen (og1.…) sind undurchsichtig und an einen Anbieter gebunden. Sie dürfen nicht entpackt, umgebaut oder zwischen Netzen gemischt werden — gib sie unverändert zurück.
Die API ist offen, damit man damit etwas bauen kann. Bleib in den Limits, cache Antworten, und wenn du Wiener Echtzeitdaten weiterverwendest, nenne die Quelle: Stadt Wien — data.wien.gv.at, CC BY 4.0.
ÖffiGo