Einstieg in 5 Minuten
Die Pendelzeit-API berechnet, wie lange man von einer Startadresse zu bis zu 100 Standorten braucht – mit PKW, ÖPNV, Fahrrad, E-Bike und zu Fuß. Sie ist zustandslos: Jede Anfrage enthält Start und Ziele vollständig, die API speichert weder Standorte noch Startadressen.
Der typische Ablauf hat zwei Schritte:
- Adresse auswählen lassen: Der Endnutzer tippt, die API liefert Vorschläge (
GET /v1/address/suggest), der Endnutzer wählt einen aus. Dessen Koordinate ist der Start. - Reisezeiten abfragen: Start und Ziele an
POST /v1/travel-timesschicken. Die Antwort ist nach Reisezeit sortiert.
Statt einer Adresse kann der Start auch direkt eine Koordinate sein, z. B. aus der Standortfreigabe des Browsers.
Was Sie brauchen
- einen API-Key – geheim (
pz_sk_…) für Aufrufe von Ihrem Server oder öffentlich (pz_pk_…) für Aufrufe direkt aus dem Browser. Unterschiede: Schlüsselarten und Bindung. - die Adresse der API, in den Beispielen
https://api.pendelzeit.de.
Mit curl (vom Server, geheimer Key)
Adressvorschläge zur Eingabe „Ulm Münsterplatz“:
curl -sS --fail-with-body 'https://api.pendelzeit.de/v1/address/suggest?q=Ulm+M%C3%BCnsterplatz&limit=3' \
-H 'Authorization: Bearer pz_sk_IHR_GEHEIMER_KEY'Die Antwort enthält je Vorschlag einen Anzeigetext (label) und die Koordinate (location):
{
"suggestions": [
{
"label": "Münsterplatz 1, 89073 Ulm",
"type": "house",
"address": { "street": "Münsterplatz", "houseNumber": "1", "postcode": "89073", "city": "Ulm", "district": "Mitte", "state": "Baden-Württemberg", "countryCode": "DE" },
"location": { "lat": 48.398511, "lon": 9.992502 }
},
{ "label": "Münsterplatz, 89073 Ulm", "type": "street", "…": "…" }
],
"attribution": [ { "text": "© OpenStreetMap-Mitwirkende, ODbL", "url": "https://www.openstreetmap.org/copyright" } ]
}Reisezeiten von dort zu drei Standorten, sortiert nach ÖPNV:
curl -sS --fail-with-body 'https://api.pendelzeit.de/v1/travel-times' \
-H 'Authorization: Bearer pz_sk_IHR_GEHEIMER_KEY' \
-H 'Content-Type: application/json' \
-d '{
"origin": { "lat": 48.39842, "lon": 9.99173 },
"destinations": [
{ "id": "neu-ulm", "label": "Neu-Ulm Bahnhof", "location": { "lat": 48.39265, "lon": 10.01060 } },
{ "id": "blaubeuren", "label": "Blaubeuren", "location": { "lat": 48.41210, "lon": 9.78480 } },
{ "id": "guenzburg", "label": "Günzburg", "location": { "lat": 48.45360, "lon": 10.27740 } }
],
"modes": ["transit", "car", "bike"],
"sortBy": "transit"
}'Gekürzte Antwort:
{
"results": [
{
"id": "neu-ulm",
"label": "Neu-Ulm Bahnhof",
"location": { "lat": 48.39265, "lon": 10.0106 },
"modes": {
"transit": {
"status": "ok",
"durationMinutes": 18,
"arrivalWindow": { "from": "07:30", "to": "08:30", "date": "2026-10-13" },
"details": { "transfers": 0, "walkToStopMinutes": 7, "departure": "2026-10-13T07:25:00+02:00", "arrival": "2026-10-13T07:43:00+02:00", "lines": ["71"] },
"routeUrls": { "googleMaps": "https://www.google.com/maps/dir/?api=1&origin=48.39842%2C9.99173&destination=48.39265%2C10.01060&travelmode=transit" }
},
"car": {
"status": "ok", "durationMinutes": 10, "distanceKm": 2.5,
"trafficNote": { "code": "no_live_traffic", "text": "Übliche Fahrzeit im Berufsverkehr, ohne aktuelle Verkehrslage" },
"routeUrls": { "googleMaps": "…" }
},
"bike": { "status": "ok", "durationMinutes": 9, "distanceKm": 2.2, "routeUrls": { "googleMaps": "…" } }
}
},
{ "id": "blaubeuren", "…": "transit 40 Min., car 42 Min., bike 77 Min." },
{ "id": "guenzburg", "…": "transit 40 Min., car 33 Min., bike over_limit" }
],
"meta": {
"counts": { "requested": 3, "returned": 3, "filtered": 0 },
"referenceDate": "2026-10-13",
"defaultArrivalWindow": { "from": "07:30", "to": "08:30" },
"limits": { "maxDestinations": 100, "maxDurationMinutes": 90 }
},
"attribution": [
{ "text": "© OpenStreetMap-Mitwirkende, ODbL", "url": "https://www.openstreetmap.org/copyright" },
{ "text": "Fahrplandaten DELFI e. V., CC BY 4.0", "url": "https://www.delfi.de" }
]
}Abgerufen gegen die lokale API (Fahrplan Oktober 2026); die Werte hängen vom aktuellen Fahrplan ab. Alle Felder beschreibt die API-Referenz.
Mit JavaScript (im Browser, öffentlicher Key)
Ein öffentlicher Key funktioniert nur auf den Domains, für die er freigegeben ist. Der Browser sendet die Domain
automatisch im Origin-Header mit.
const API = 'https://api.pendelzeit.de';
const KEY = 'pz_pk_IHR_OEFFENTLICHER_KEY';
async function api(path, options = {}) {
const response = await fetch(API + path, {
...options,
headers: { Authorization: `Bearer ${KEY}`, 'Content-Type': 'application/json', ...options.headers },
});
if (!response.ok) {
const problem = await response.json(); // Problem Details (RFC 9457)
throw new Error(`${problem.status} ${problem.title}: ${problem.detail ?? ''}`);
}
return response.json();
}
// 1. Vorschläge zur Eingabe holen, der Endnutzer wählt einen aus (hier: den ersten)
const { suggestions } = await api('/v1/address/suggest?q=' + encodeURIComponent('Ulm Münsterplatz'));
const start = suggestions[0].location;
// 2. Reisezeiten zu den Standorten
const result = await api('/v1/travel-times', {
method: 'POST',
body: JSON.stringify({
origin: start,
destinations: [
{ id: 'neu-ulm', label: 'Neu-Ulm Bahnhof', location: { lat: 48.39265, lon: 10.0106 } },
{ id: 'blaubeuren', label: 'Blaubeuren', location: { lat: 48.4121, lon: 9.7848 } },
],
modes: ['transit', 'walk'],
}),
});
for (const r of result.results) {
const t = r.modes.transit;
console.log(r.label, t.status === 'ok' ? `${t.durationMinutes} Min. mit ÖPNV` : t.status);
}Was Sie außerdem wissen sollten
- Höchstens 100 Ziele je Anfrage, Reisezeiten über 90 Minuten kommen als
over_limit. Bei vielen Standorten wählen Sie vorher aus: Vorauswahl der Ziele. - ÖPNV bezieht sich auf die Ankunft werktags zwischen 07:30 und 08:30 Uhr; das Fenster ist je Anfrage und je Ziel
änderbar (
arrivalWindow). PKW ist die übliche Fahrzeit im Berufsverkehr ohne aktuelle Verkehrslage. - Quellenangabe ist Pflicht: Quellenangabe.
- Fehler und Ausfälle behandeln: Verhalten bei Fehlern und Ausfall.