Zum Inhalt springen

API-Dokumentation

Die LageLuchs-API liefert LuchsScore, Trend und Dimensions-Scores je Region als JSON. Der Zugang erfordert einen API-Key aus deinem Konto (Developer-Abo). Was du mit den abgerufenen Daten tun darfst, steht in den Nutzungsrechten für die Developer-API.

Authentifizierung

Sende deinen API-Key bei jedem Request — als Bearer-Token oder im x-api-key-Header:

Authorization: Bearer ll_live_…
# oder alternativ:
x-api-key: ll_live_…

Endpunkte

GET/api/v1/regions

Paginierte Liste aller ~11.000 Regionen. Filtere nach Verwaltungsebene mit type.

type — gemeinde | landkreis | bundesland (optional)
page — Seitennummer, 1-basiert (Standard: 1)
per_page — Ergebnisse pro Seite, max. 500 (Standard: 100)
curl -H "Authorization: Bearer ll_live_…" \
  "https://lageluchs.de/api/v1/regions?type=landkreis&per_page=50"
{
  "data": [
    { "ags": "01001", "name": "Flensburg", "type": "landkreis", "slug": "flensburg", "parent_ags": "01" },
    { "ags": "01002", "name": "Kiel", "type": "landkreis", "slug": "kiel", "parent_ags": "01" }
  ],
  "meta": { "total": 400, "page": 1, "per_page": 50, "pages": 8 }
}
GET/api/v1/regions/search?q=

Suche nach Regionen per Name (min. 2 Zeichen). Gibt max. 10 Treffer zurück. Ideal für Discovery: erst suchen, dann AGS nehmen, dann Region abrufen.

q — Suchbegriff (Pflicht, min. 2 Zeichen)
curl -H "Authorization: Bearer ll_live_…" \
  "https://lageluchs.de/api/v1/regions/search?q=München"
{
  "data": [
    { "ags": "09162", "name": "München", "type": "landkreis", "slug": "muenchen" },
    { "ags": "09184", "name": "München (Landkreis)", "type": "landkreis", "slug": "muenchen-landkreis" }
  ]
}
GET/api/v1/regions/{ags-oder-slug}

Vollständige Score-Daten einer Region per AGS (8-stellig für Gemeinden, 5-stellig für Landkreise) oder URL-Slug. Die Antwort enthält zusätzlich die Gebietshierarchie bis zum Bundesland (hierarchie, bundesland) und die tatsächlich verwendeten Dimensionsgewichte (dimension_gewichte).

curl -H "Authorization: Bearer ll_live_…" \
  https://lageluchs.de/api/v1/regions/05315000
{
  "ags": "05315000",
  "name": "Köln",
  "type": "landkreis",
  "slug": "koeln",
  "luchs_score": 61,
  "trend": "stable",
  "dimension_scores": {
    "bevoelkerung": 72,
    "wirtschaft": 65,
    "arbeitsmarkt": 58,
    "infrastruktur": 80,
    "immobilien": 43
  },
  "data_vintage": "2025-01-01",
  "trust_level": "hoch",
  "parent_region": { "ags": "05000000", "name": "Nordrhein-Westfalen", "slug": "nordrhein-westfalen", "type": "bundesland" },
  "hierarchie": [
    { "ags": "05000000", "name": "Nordrhein-Westfalen", "slug": "nordrhein-westfalen", "type": "bundesland" }
  ],
  "bundesland": { "ags": "05000000", "name": "Nordrhein-Westfalen" },
  "dynamik": null,
  "staerke": null,
  "dimension_gewichte": {
    "bevoelkerung": 16,
    "wirtschaft": 16,
    "arbeitsmarkt": 15,
    "infrastruktur": 15,
    "immobilien": 18
  },
  "gewichtung_hinweis": "Verhältniszahlen der amtlichen LuchsScore-Gewichtung, keine Prozentwerte (Summe 80). Der Score normalisiert intern über die Gewichtssumme."
}
GET/api/v1/regions/{ags-oder-slug}/indicators

Verzeichnis der für diese Region verfügbaren Indikatorcodes mit ihrem jeweils jüngsten Datenstand — ohne Werte. Für den Wert selbst den Einzelindikator abrufen (siehe unten).

curl -H "Authorization: Bearer ll_live_…" \
  https://lageluchs.de/api/v1/regions/05315000/indicators
{
  "ags": "05315000",
  "name": "Köln",
  "slug": "koeln",
  "anzahl": 2,
  "data": [
    { "indicator_code": "alo_quote", "label": "Arbeitslosenquote", "einheit": "%", "dimension": "arbeitsmarkt", "sub_type": "staerke", "data_vintage": "2026-07-31", "quelle": "ba_statistik", "metadaten_bekannt": true },
    { "indicator_code": "bev_insgesamt", "label": null, "einheit": null, "dimension": "bevoelkerungsdynamik", "sub_type": "staerke", "data_vintage": "2025-12-31", "quelle": "regionalstatistik", "metadaten_bekannt": false }
  ]
}
GET/api/v1/regions/{ags-oder-slug}/indicators/{code}

Einzelindikator mit vollständigen Metadaten: Wert, Einheit, Bezugsjahr, Datenstand, Quelle und Qualitätshinweise. Ohne Parameter der jüngste echte Jahrgang (Prognosen ausgeschlossen).

vintage — genauer Jahrgang YYYY-MM-DD (optional)
include_forecast — true erlaubt auch die Prognosezeile (optional)
curl -H "Authorization: Bearer ll_live_…" \
  https://lageluchs.de/api/v1/regions/05315000/indicators/alo_quote
{
  "ags": "05315000",
  "name": "Köln",
  "slug": "koeln",
  "indicator_code": "alo_quote",
  "label": "Arbeitslosenquote",
  "einheit": "%",
  "beschreibung": "Anteil der Arbeitslosen an den Erwerbspersonen. Höher = schwächerer Arbeitsmarkt, daher invertiert gewertet.",
  "nachkommastellen": 1,
  "dimension": "arbeitsmarkt",
  "sub_type": "staerke",
  "wert": 9,
  "normalisierter_wert": null,
  "bezugsjahr": 2026,
  "data_vintage": "2026-07-31",
  "vintage_kind": "erhebung",
  "quelle": "ba_statistik",
  "qualitaet": {
    "geschaetzt": false,
    "fallback_ags": null,
    "prognose": false,
    "metadaten_bekannt": true
  }
}

18 von 158 Indikatorcodes (Stand 10.09.2026, z. B. bev_insgesamt) tragen keine Anzeige-Metadaten. Das ist kein Fehler: label/einheit/beschreibung sind dann null und qualitaet.metadaten_bekannt ist false — der Rohwert ist trotzdem gültig:

curl -H "Authorization: Bearer ll_live_…" \
  https://lageluchs.de/api/v1/regions/05315000/indicators/bev_insgesamt
{
  "ags": "05315000",
  "name": "Köln",
  "slug": "koeln",
  "indicator_code": "bev_insgesamt",
  "label": null,
  "einheit": null,
  "beschreibung": null,
  "nachkommastellen": null,
  "dimension": "bevoelkerungsdynamik",
  "sub_type": "staerke",
  "wert": 1025523,
  "normalisierter_wert": null,
  "bezugsjahr": 2025,
  "data_vintage": "2025-12-31",
  "vintage_kind": "erhebung",
  "quelle": "regionalstatistik",
  "qualitaet": {
    "geschaetzt": false,
    "fallback_ags": null,
    "prognose": false,
    "metadaten_bekannt": false
  }
}

Die vollständige Zeitreihe eines Indikators liefert nicht dieser Endpunkt, sondern der Zeitreihen-Endpunkt weiter unten.

GET/api/v1/regions/{ags-oder-slug}/timeseries

Zeitreihe: ohne Parameter der LuchsScore über mehrere echte Jahrgänge, mit ?indicator={code} die Reihe genau dieses Indikators. Historie und Prognose stehen getrennt — eine Prognosezeile taucht nie in historie auf, sondern immer in prognose. Ladedatum-Zeilen (kein echter Erhebungsjahrgang) fehlen bewusst in beiden Listen; hinweise.ladedatum_zeilen_ausgeschlossen nennt, wie viele das waren. Eine Dimensions-Historie gibt es nicht — Detailtiefe je Dimension kommt über ?indicator={code}. Keine leere Zeitreihe ist ein Fehler: eine Region/ein Code ohne Werte antwortet mit 200 und leeren Feldern, nicht 404.

indicator — Indikatorcode. Ohne diesen Parameter kommt die LuchsScore-Reihe (optional)
curl -H "Authorization: Bearer ll_live_…" \
  https://lageluchs.de/api/v1/regions/05315000/timeseries
{
  "ags": "05315000",
  "name": "Köln",
  "slug": "koeln",
  "reihe": "luchs_score",
  "einheit": "Punkte",
  "label": "LuchsScore",
  "verfuegbare_jahre": [2024, 2026],
  "historie": [
    { "data_vintage": "2024-12-31", "jahr": 2024, "wert": 55.63 },
    { "data_vintage": "2026-06-06", "jahr": 2026, "wert": 67 },
    { "data_vintage": "2026-06-07", "jahr": 2026, "wert": 67, "score_delta": 0, "trend": "stable" },
    { "data_vintage": "2026-06-08", "jahr": 2026, "wert": 62, "score_delta": 2, "trend": "stable" },
    { "data_vintage": "2026-06-30", "jahr": 2026, "wert": 62, "score_delta": 2, "trend": "stable" },
    { "data_vintage": "2026-07-31", "jahr": 2026, "wert": 62, "score_delta": 0, "trend": "stable" },
    { "data_vintage": "2026-08-24", "jahr": 2026, "wert": 63 },
    { "data_vintage": "2026-08-31", "jahr": 2026, "wert": 62, "score_delta": -1, "trend": "stable" }
  ],
  "prognose": [
    { "data_vintage": "2040-01-01", "jahr": 2040, "wert": 69, "prognose": true }
  ],
  "hinweise": {
    "ladedatum_zeilen_ausgeschlossen": 0,
    "dimensions_historie": "Eine Historie je Score-Dimension existiert nicht; region_score_history führt nur score_total. Detailtiefe je Dimension über ?indicator={code}."
  }
}
curl -H "Authorization: Bearer ll_live_…" \
  "https://lageluchs.de/api/v1/regions/05315000/timeseries?indicator=alo_quote"
{
  "ags": "05315000",
  "name": "Köln",
  "slug": "koeln",
  "reihe": "indicator:alo_quote",
  "einheit": "%",
  "label": "Arbeitslosenquote",
  "verfuegbare_jahre": [2025, 2026],
  "historie": [
    { "data_vintage": "2025-06-30", "jahr": 2025, "wert": 9.1 },
    { "data_vintage": "2025-07-31", "jahr": 2025, "wert": 9.2 },
    { "data_vintage": "2026-05-31", "jahr": 2026, "wert": 8.9 },
    { "data_vintage": "2026-06-30", "jahr": 2026, "wert": 8.9 },
    { "data_vintage": "2026-07-31", "jahr": 2026, "wert": 9 }
  ],
  "prognose": [],
  "hinweise": {
    "ladedatum_zeilen_ausgeschlossen": 0,
    "dimensions_historie": "Eine Historie je Score-Dimension existiert nicht; region_score_history führt nur score_total. Detailtiefe je Dimension über ?indicator={code}."
  }
}
GET/api/v1/regions/{ags-oder-slug}/comparison

Vergleichswerte — Perzentil, Rang und Bezugsgruppe — ausschließlich aus dem, was intern bereits berechnet vorliegt. Dieser Endpunkt rechnet nichts neu. Der Score-Vergleich kommt aus drei Bezugsräumen (regionstyp, einwohnerklasse, bundesland) und liegt nur für Gemeinden vor — für Landkreise und Bundesländer ist peer_vergleich null, nie ein erfundener Rang. Mit ?indicator={code} ergänzt indikator_vergleich das Perzentil dieses Indikators gegen alle Regionen derselben Verwaltungsebene bundesweit.

Die Vergleichswerte können älter sein als der aktuelle LuchsScore der Region — jeder Block trägt sein eigenes stand-Feld und ein veraltet-Kennzeichen, das zur Laufzeit gegen den aktuellen Score-Stand der Region berechnet wird.

indicator — Indikatorcode. Ergänzt indikator_vergleich (optional)
curl -H "Authorization: Bearer ll_live_…" \
  https://lageluchs.de/api/v1/regions/16075133/comparison
{
  "ags": "16075133",
  "name": "Wurzbach, Stadt",
  "slug": "wurzbach-stadt",
  "type": "gemeinde",
  "luchs_score": 33,
  "score_stand": "2026-08-31",
  "peer_vergleich": {
    "regionstyp": { "perzentil": 1.73, "rang": 7805, "gruppe": "laendliche_gemeinde", "gruppengroesse": 7997, "score_grundlage": 40.54, "stand": "2024-12-31", "veraltet": true },
    "einwohnerklasse": { "perzentil": 1.74, "rang": 7616, "gruppe": "ew_unter_5k", "gruppengroesse": 7806, "score_grundlage": 40.54, "stand": "2024-12-31", "veraltet": true },
    "bundesland": { "perzentil": 17.98, "rang": 431, "gruppe": "16", "gruppengroesse": 596, "score_grundlage": 40.54, "stand": "2024-12-31", "veraltet": true }
  },
  "hinweis_stand": "Vergleichswerte vom 2024-12-31; der aktuelle LuchsScore der Region hat den Stand 2026-08-31.",
  "hinweis_ebene": null,
  "hinweis_bezugsgruppe": "Die Ränge vergleichen ausschließlich Gemeinden untereinander: regionstyp = gleichartige Gemeinden, einwohnerklasse = Gemeinden ähnlicher Größe, bundesland = Gemeinden desselben Bundeslands. Indikator-Perzentile vergleichen gegen alle Regionen derselben Verwaltungsebene bundesweit.",
  "indikator_vergleich": null
}

Mit ?indicator=alo_quote kommt zusätzlich:

curl -H "Authorization: Bearer ll_live_…" \
  "https://lageluchs.de/api/v1/regions/16075133/comparison?indicator=alo_quote"
{
  "indikator_vergleich": {
    "indicator_code": "alo_quote",
    "label": "Arbeitslosenquote",
    "einheit": "%",
    "wert": 5.5,
    "data_vintage": "2026-07-31",
    "invertiert": true,
    "perzentil_guete": 37,
    "perzentil_roh": 63,
    "bezugsgruppe": "alle gemeinde bundesweit"
  }
}

Für einen Landkreis (hier kreisfrei, ohne eigene Peer-Zeilen) bleibt peer_vergleich null — die Antwort ist trotzdem 200, kein 404:

curl -H "Authorization: Bearer ll_live_…" \
  https://lageluchs.de/api/v1/regions/05315000/comparison
{
  "ags": "05315000",
  "name": "Köln, Stadt",
  "slug": "koeln-stadt",
  "type": "landkreis",
  "luchs_score": 62,
  "score_stand": "2026-08-31",
  "peer_vergleich": null,
  "hinweis_stand": null,
  "hinweis_ebene": "Vorberechnete Ränge liegen nur für Gemeinden vor.",
  "hinweis_bezugsgruppe": "Die Ränge vergleichen ausschließlich Gemeinden untereinander: regionstyp = gleichartige Gemeinden, einwohnerklasse = Gemeinden ähnlicher Größe, bundesland = Gemeinden desselben Bundeslands. Indikator-Perzentile vergleichen gegen alle Regionen derselben Verwaltungsebene bundesweit.",
  "indikator_vergleich": null
}

Wogegen wird verglichen?

bundesland — Rang innerhalb des Bundeslands (nur Gemeinden).

regionstyp — Rang unter gleichartigen Gemeinden (nur Gemeinden).

einwohnerklasse — Rang unter Gemeinden ähnlicher Größe (nur Gemeinden).

indikator_vergleich — Perzentil gegen ALLE Regionen derselben Verwaltungsebene bundesweit (der „Deutschland-Vergleich").

Es gibt keine Ähnlichkeitsberechnung nach Bevölkerungsgröße mehr — dieses Konzept wurde stillgelegt. „Peer" bezeichnet hier ausschließlich die drei oben genannten, konkret berechneten Bezugsräume.

GET/api/v1/regions/{ags-oder-slug}/mikrolage

Mikrolage — das materialisierte Rasteraggregat einer Region: Score, Median, Quartile, Zellenzahl, elf Faktor-Mediane und Histogramm. Stand 2 943 von 11 251 Regionen haben Mikrolage-Abdeckung (Stand 11.09.2026, die Abdeckung wächst noch).

Regionen ohne Abdeckung antworten mit 200 und mikrolage_verfuegbar: false, nie mit einem 404 und nie mit erfundenen Nullwerten. geprueft unterscheidet „geprüft, kein Ergebnis" von „nicht erfasst".

Mikrolage-Abrufe zählen gegen ein EIGENES Kontingent — 20 Anfragen pro Minute pro API-Key, getrennt vom Standardkontingent von 60/min. Ein erschöpftes Mikrolage-Kontingent blockiert deine Standardabrufe nicht, und umgekehrt. Begründung: Mikrolage ist die rasterabgeleitete Datenfamilie — allein Köln trägt 12 946 Rasterzellen.

Preis und genaue Grenzen des Mikrolage-Kontingents: folgt separat. Wir nennen hier bewusst keine vorläufige Zahl und keine vorläufige Mengenobergrenze, an der du später nicht festhalten könntest.

curl -H "Authorization: Bearer ll_live_…" \
  https://lageluchs.de/api/v1/regions/05315000/mikrolage
{
  "ags": "05315000",
  "name": "Köln, Stadt",
  "slug": "koeln-stadt",
  "type": "landkreis",
  "mikrolage_verfuegbar": true,
  "geprueft": true,
  "grund": null,
  "score": 67.8,
  "median": 67.8,
  "q25": 59.54,
  "q75": 74.38,
  "n_cells": 12946,
  "gerechnet_am": "2026-08-17T09:14:02.519Z",
  "faktor_mediane": {
    "osm_supermarkt_1km": 4,
    "osm_arzt_1km": 4,
    "osm_schule_1km": 4,
    "osm_kita_1km": 6,
    "osm_oepnv_500m": 6,
    "anteil_eigentuemer": 0.45,
    "anteil_leerstand": 0.0597,
    "anteil_baujahr_vor1949": 0,
    "anteil_baujahr_nach2000": 0,
    "einwohner": 57,
    "anteil_unter18": null
  },
  "histogram": [19, 13, 20, 39, 65, 110, 147, 234, 315, 472, 752, 1185, 1847, 2308, 2512, 1446, 715, 570, 171, 6]
}

Für eine Region ohne Abdeckung bleibt die Antwort 200, kein 404:

curl -H "Authorization: Bearer ll_live_…" \
  https://lageluchs.de/api/v1/regions/07231017/mikrolage
{
  "ags": "07231017",
  "name": "Burtscheid",
  "slug": "burtscheid",
  "type": "gemeinde",
  "mikrolage_verfuegbar": false,
  "geprueft": false,
  "grund": "Für diese Region sind keine Mikrolage-Rasterdaten erfasst.",
  "score": null,
  "median": null,
  "q25": null,
  "q75": null,
  "n_cells": null,
  "gerechnet_am": null,
  "faktor_mediane": null,
  "histogram": null
}
GET/api/v1/regions.csv

Alle Regionen als CSV-Download (AGS, Name, Typ, Slug). Kein Paging — geeignet für lokales Caching des AGS-Verzeichnisses, ohne Rate-Limits zu verbrauchen.

curl -H "Authorization: Bearer ll_live_…" \
  "https://lageluchs.de/api/v1/regions.csv" -o regionen.csv
ags,name,type,slug
01001,Flensburg,landkreis,flensburg
01002,Kiel,landkreis,kiel
01003,Lübeck,landkreis,luebeck
…

Rate-Limits

60 Anfragen pro Minute pro API-Key (gleitendes Fenster). Bei Überschreitung antwortet die API mit HTTP 429.

Response-Header: X-RateLimit-Limit, X-RateLimit-Remaining, Retry-After
Mikrolage-Abrufe (/mikrolage) haben ein eigenes, getrenntes Kontingent — siehe den Mikrolage-Endpunkt oben.

Preis

Der Developer-Zugang enthält alles aus Pro und dazu den API-Zugang:

  • 49,00 € für 1 Monat
  • 245,00 € für 6 Monate
  • 390,00 € für 1 Jahr

Einmalige Zahlung. Kein Abo, keine automatische Verlängerung. Bestellen kannst du ihn unter Preise.

Fehlercodes

HTTPcodeBedeutung
401unauthorizedAPI-Key fehlt, ungültig oder widerrufen
403forbiddenKein aktives Developer-Abo
404not_foundRegion nicht gefunden (kein Score)
429rate_limitedRate-Limit überschritten
500internalDatenbankfehler

Alle Fehler verwenden dasselbe JSON-Format:

{ "error": { "code": "not_found", "message": "Region nicht gefunden." } }

Nutzungsrechte

Was du mit den abgerufenen Daten tun darfst — interne Nutzung, Speicherung, Caching, Weiterverarbeitung, Weiterverkauf, Bulk-Download, Konkurrenzprodukte und Attributionspflicht — steht vollständig in den Nutzungsrechten für die Developer-API. Sie gelten für jeden Abruf über /api/v1/*.

OpenAPI-Spezifikation

Maschinenlesbare Spezifikation (OpenAPI 3.0) für Codegen und API-Clients: /api/v1/openapi.json