Dokumentation

Schnellstart

Vom Schlüssel zum ersten Aufruf. Wenn nichts dazwischenkommt, dauert das fünf Minuten.

1. Schlüssel anlegen

Das macht eine berechtigte Person der Stadt, nicht Sie.

Im Stadt-Admin unter Schnittstellen wird ein Schlüssel erstellt und dabei ausgewählt, welche Rechte er trägt. Das Geheimnis erscheint genau einmal — danach ist es nicht mehr abrufbar, weil wir nur seinen Hash speichern. Geht es verloren, wird ein neuer Schlüssel erzeugt und der alte widerrufen.

2. Verbindung prüfen

Ein Aufruf, der ohne besondere Rechte funktioniert.
AnfrageShell
curl -sS \
  -H "Authorization: Bearer rb_live_…" \
  https://rufbusle.de/api/v1/me
AntwortJSON
{
  "id": "clx1a2b3c0000abcdefghijkl",
  "slug": "musterstadt",
  "name": "Musterstadt",
  "timezone": "Europe/Berlin",
  "scopes": [
    "read:schedule",
    "read:bookings"
  ]
}

Kommt hier eine Antwort, stimmen Schlüssel, Tarif und Netzwerkweg. Das Feld scopes sagt Ihnen verbindlich, welche Rechte der Schlüssel wirklich hat — verlassen Sie sich nicht auf das, was beim Anlegen angeklickt wurde.

3. Erste Daten lesen

Alles Weitere folgt demselben Muster.

Der häufigste erste echte Aufruf ist der Bedarf für einen Zeitraum. Er braucht das Recht read:bookings.

AnfrageShell
curl -sS \
  -H "Authorization: Bearer rb_live_…" \
  "https://rufbusle.de/api/v1/bookings?from=2026-08-10&to=2026-08-16&limit=50"

Listen sind seitenweise. Solange nextCursor nicht null ist, gibt es eine Folgeseite — den Wert als ?cursor= anhängen und erneut abrufen.

Alle Seiten holen (Node)JavaScript
const base = 'https://rufbusle.de/api/v1';
const headers = { Authorization: `Bearer ${process.env.RUFBUSLE_API_KEY}` };

async function fetchAll(path) {
  const out = [];
  let cursor;
  do {
    const url = new URL(base + path);
    if (cursor) url.searchParams.set('cursor', cursor);
    const res = await fetch(url, { headers });
    if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
    const page = await res.json();
    out.push(...page.data);
    cursor = page.nextCursor;
  } while (cursor);
  return out;
}

const bookings = await fetchAll('/bookings?from=2026-08-10&to=2026-08-16');

Wie weiter?

Für den Aufbau einer echten Integration lohnen sich als Nächstes die Konventionen (Paginierung, Fehler, Rate-Limit) und die Endpunkt-Referenz. Wenn Ihr System auf Änderungen reagieren soll, statt regelmäßig abzufragen, sind Webhooks der sparsamere Weg.