Zum Inhalt springen
Adventskonzerte BerlinTermine-API OpenAPI-Spezifikation (JSON)

Entwickler-Schnittstelle · Version 1

Termine-API

Alle Konzerttermine von adventskonzerte-berlin.de als JSON – für Kalender, Gemeindeseiten, Apps und Bildschirme im Foyer.

Schnellstart

Basis-URL: https://api.adventskonzerte-berlin.de. Alle Antworten sind JSON in UTF-8; Fehler ebenfalls.

curl https://api.adventskonzerte-berlin.de/v1/termine

Bitte höchstens einmal pro Stunde abfragen. Die Termine ändern sich nur selten. Zwischenspeichern Sie die Antwort und nutzen Sie ETag und If-None-Match.

Endpunkte

Erlaubt sind GET, HEAD und OPTIONS.

GET/v1/termine

Alle veröffentlichten Termine, sortiert nach beginn, bei Gleichstand nach reihenfolge. Optional gefiltert.

{
  "termine": [
    "… Termin-Objekte …"
  ],
  "anzahl": 1,
  "stand": "2026-11-09T10:15:00.000Z",
  "quelle": "https://adventskonzerte-berlin.de/konzerte/"
}

anzahl ist die Zahl der gelieferten Termine, stand der Zeitpunkt, zu dem die Website die Daten erzeugt hat, quelle die Seite mit den Terminen.

GET/v1/termine/{id}

Ein einzelnes Termin-Objekt, z. B. /v1/termine/friedrichshain. Unbekannte Kennung → 404.

{
  "id": "friedrichshain",
  "name": "Friedrichshain",
  "reihenfolge": 3,
  "datum": "2026-12-19",
  "uhrzeit": "17:30",
  "beginn": "2026-12-19T17:30:00+01:00",
  "zeitzone": "Europe/Berlin",
  "veranstalter": "Eckstein-Gemeinde",
  "adresse": "An der Schillingbrücke 4, 10243 Berlin",
  "website": {
    "url": "https://eckstein.online",
    "text": "eckstein.online"
  },
  "bild": {
    "url": "https://adventskonzerte-berlin.de/bilder/konzerte_05.webp",
    "beschreibung": "Konzert Friedrichshain"
  },
  "koordinaten": {
    "breitengrad": 52.509829,
    "laengengrad": 13.429333
  },
  "livestream": false,
  "links": {
    "konzertseite": "https://adventskonzerte-berlin.de/konzerte/#termine",
    "karte": "https://www.google.com/maps/search/?api=1&query=Eckstein-Gemeinde%2C%20An%20der%20Schillingbr%C3%BCcke%204%2C%2010243%20Berlin"
  }
}

Weitere Adressen

  • GET /v1 – kleine Übersicht mit Links
  • GET /gesundheit – antwortet {"status": "ok"} (zählt zum Rate Limit)
  • GET /openapi.json – maschinenlesbare Spezifikation (OpenAPI 3.1)
  • GET / bzw. /doku/ – diese Seite

Filter

Für /v1/termine, beliebig kombinierbar. Leere Ergebnisse liefern anzahl: 0, keinen Fehler.

Filterparameter
ParameterWertBedeutung
abYYYY-MM-DDTermine an oder nach diesem Tag (einschließlich).
bisYYYY-MM-DDTermine an oder vor diesem Tag (einschließlich).
livestreamtrue | falseNur Termine mit bzw. ohne Livestream.

Ungültige Werte führen zu 400 mit Code ungueltiger_parameter.

https://api.adventskonzerte-berlin.de/v1/termine?ab=2026-12-01&bis=2026-12-24&livestream=true

Feldverzeichnis: Termin-Objekt

Alle Felder sind immer vorhanden. Nur website kann null sein. Versteckte Termine werden nicht ausgegeben.

Felder des Termin-Objekts
FeldTypBeschreibung
idstringEindeutige, stabile Kennung (Dateiname, z. B. friedrichshain). Für /v1/termine/{id}.
namestringName des Termins, meist der Bezirk.
reihenfolgeintegerRedaktionelle Reihenfolge; zweites Sortierkriterium nach beginn.
datumstring (date)Konzerttag im Format YYYY-MM-DD.
uhrzeitstringBeginn als Berliner Ortszeit, HH:MM.
beginnstring (date-time)Beginn als ISO 8601 mit Zeitversatz, z. B. 2026-12-19T17:30:00+01:00. Sommer- und Winterzeit sind berücksichtigt.
zeitzonestringImmer Europe/Berlin.
veranstalterstringGemeinde oder Veranstalter.
adressestringAnschrift des Veranstaltungsorts.
websiteobject | nullWebsite des Veranstalters, sonst null.
website.urlstring (uri)Adresse der Website.
website.textstringAnzeigetext für den Link.
bildobjectBild zum Termin.
bild.urlstring (uri)Absolute Bildadresse (WebP).
bild.beschreibungstringAlternativtext – bitte als alt verwenden.
koordinatenobjectLage des Veranstaltungsorts (WGS 84).
koordinaten.breitengradnumberBreitengrad, z. B. 52.509829.
koordinaten.laengengradnumberLängengrad, z. B. 13.429333.
livestreambooleantrue, wenn das Konzert live übertragen wird.
linksobjectWeiterführende Links.
links.konzertseitestring (uri)Konzertseite der Website (Abschnitt mit allen Terminen).
links.kartestring (uri)Ort in der Karten-App (Google-Maps-Link, öffnet auf dem Handy die Karten-App).

Tipp: Für Kalender und Zeitberechnungen beginn verwenden – das Feld enthält den korrekten Zeitversatz. datum und uhrzeit eignen sich für die Anzeige.

Rate Limits

Damit der kostenlose Dienst für alle verfügbar bleibt, gelten pro IP-Adresse feste Grenzen. Jede Anfrage zählt – auch 304-Antworten, HEAD und /gesundheit. Nur CORS-Vorabanfragen (OPTIONS) zählen nicht.

  • 5 Anfragen pro Minute
  • 30 Anfragen pro Stunde
  • 100 Anfragen pro Tag

Empfehlung: höchstens einmal pro Stunde abfragen, das Ergebnis zwischenspeichern und mit If-None-Match nachfragen. Für Webseiten mit vielen Besuchern: die Daten auf Ihrem Server abrufen und von dort ausliefern, statt jeden Browser direkt anfragen zu lassen.

Antwort-Header

Rate-Limit-Header
HeaderBeispielBedeutung
X-RateLimit-Limit30Erlaubte Anfragen im Stundenfenster.
X-RateLimit-Remaining27Verbleibende Anfragen im Stundenfenster.
X-RateLimit-Reset1834Sekunden bis zum Zurücksetzen des Stundenfensters.
RateLimit-Policy"minute";q=5;w=60, "stunde";q=30;w=3600, "tag";q=100;w=86400Geltende Grenzen nach IETF-Entwurf.
RateLimit"stunde";r=27;t=1834Aktueller Stand nach IETF-Entwurf.
Retry-After60Nur bei 429: Sekunden bis zur nächsten erlaubten Anfrage.

Bei 429 Too Many Requests: nicht sofort wiederholen. Warten Sie mindestens die in Retry-After angegebenen Sekunden. Wiederholte Anfragen während der Sperre verlängern nichts, werden aber ebenfalls abgewiesen.

{
  "fehler": {
    "code": "zu_viele_anfragen",
    "nachricht": "Zu viele Anfragen. Bitte in 1834 Sekunden erneut versuchen."
  }
}

Caching & ETag

Antworten tragen Cache-Control: public, max-age=900 (15 Minuten) und einen ETag. Schicken Sie den ETag beim nächsten Abruf als If-None-Match mit: Hat sich nichts geändert, antwortet die API mit 304 Not Modified ohne Inhalt – schnell und sparsam. Auch 304-Antworten zählen zum Rate Limit; der Vorteil liegt in der geringeren Datenmenge.

Die API liest ihre Daten selbst aus der Website, mit etwa 15 Minuten Zwischenspeicher. Änderungen erscheinen daher mit kurzer Verzögerung. Der Zeitpunkt der Datenerzeugung steht in stand.

Fehlercodes

Fehler kommen immer als JSON in dieser Form:

{ "fehler": { "code": "nicht_gefunden", "nachricht": "Termin „mitte“ nicht gefunden." } }

Werten Sie code aus – nachricht ist für Menschen gedacht und kann sich ändern.

Fehlercodes
HTTPcodeBedeutung
400ungueltiger_parameterFilterwert ungültig, z. B. ab=19.12.2026 statt 2026-12-19.
404nicht_gefundenTermin oder Adresse existiert nicht.
405methode_nicht_erlaubtAndere Methode als GET, HEAD oder OPTIONS.
429zu_viele_anfragenRate Limit überschritten. Retry-After abwarten.
503quelle_nicht_erreichbarDie Datenquelle ist vorübergehend nicht erreichbar. Später erneut versuchen.
503konfiguration_fehltDie API ist auf Betreiberseite nicht vollständig eingerichtet. Später erneut versuchen.

Beispiele

curl

# Alle Termine
curl -i https://api.adventskonzerte-berlin.de/v1/termine

# Nur Termine im Dezember mit Livestream
curl "https://api.adventskonzerte-berlin.de/v1/termine?ab=2026-12-01&bis=2026-12-31&livestream=true"

# Ein einzelner Termin
curl https://api.adventskonzerte-berlin.de/v1/termine/friedrichshain

# Bedingte Anfrage: 304, wenn sich nichts geändert hat
curl -i -H 'If-None-Match: "a1b2c3d4"' https://api.adventskonzerte-berlin.de/v1/termine

JavaScript (fetch)

// Funktioniert im Browser (CORS ist offen) und in Node.js ab Version 18.
const antwort = await fetch('https://api.adventskonzerte-berlin.de/v1/termine?ab=2026-12-01');

if (antwort.status === 429) {
  const warten = Number(antwort.headers.get('Retry-After') ?? 60);
  throw new Error('Rate Limit erreicht, bitte in ' + warten + ' s erneut versuchen.');
}
if (!antwort.ok) {
  const { fehler } = await antwort.json();
  throw new Error(fehler.code + ': ' + fehler.nachricht);
}

const { termine, stand } = await antwort.json();
for (const t of termine) {
  const zeit = new Date(t.beginn).toLocaleString('de-DE', {
    dateStyle: 'full', timeStyle: 'short', timeZone: t.zeitzone,
  });
  console.log(zeit, '–', t.name, '–', t.adresse);
}
console.log('Datenstand:', stand);

Python

# Nur Standardbibliothek, Python 3.8+
import json, time, urllib.request, urllib.error

URL = "https://api.adventskonzerte-berlin.de/v1/termine"
etag, termine = None, []

def abrufen():
    global etag, termine
    anfrage = urllib.request.Request(URL, headers={"User-Agent": "mein-kalender/1.0"})
    if etag:
        anfrage.add_header("If-None-Match", etag)
    try:
        with urllib.request.urlopen(anfrage, timeout=10) as antwort:
            etag = antwort.headers.get("ETag")
            termine = json.load(antwort)["termine"]
    except urllib.error.HTTPError as e:
        if e.code == 304:
            return termine                 # unverändert, alten Stand behalten
        if e.code == 429:
            time.sleep(int(e.headers.get("Retry-After", "60")))
        raise
    return termine

for t in abrufen():
    print(t["datum"], t["uhrzeit"], t["name"], "Livestream" if t["livestream"] else "")

CORS

Die API sendet Access-Control-Allow-Origin: *. Sie kann also direkt aus jeder Webseite per fetch abgefragt werden, ohne Cookies oder Anmeldedaten. Vorabanfragen (OPTIONS) werden beantwortet und zählen nicht zum Rate Limit. Bedenken Sie bei direkter Einbindung, dass jeder Besucher Ihrer Seite eigene Anfragen erzeugt – und die Grenzen pro Besucher-IP gelten.

Datenschutz

Für die Rate Limits wird jede IP-Adresse nur als gesalzener Hash (SHA-256 mit täglich wechselndem Salz) gezählt. Die Zählerstände werden spätestens nach 24 Stunden gelöscht. Es werden keine Zugriffsprotokolle mit IP-Adressen geführt, keine Cookies gesetzt und keine Daten an Dritte weitergegeben. Die API wird über Cloudflare betrieben. Weitere Informationen in der Datenschutzerklärung.

Kontakt & Nutzung

Die Termindaten dürfen gern übernommen werden. Bitte nennen Sie als Quelle adventskonzerte-berlin.de und verlinken Sie auf die Konzertseite (links.konzertseite). Fragen und Hinweise: siehe Impressum.