Lagedaten.

API-Dokumentation

REST-API für amtliche Bodenrichtwerte — für Integrationen ohne Frontend

Startseite · interaktive Doku (Swagger) · Rate-Limit & Keys · Fehlercodes

Amtliche Originalwerte der Bundesländer — unverändert, mit Quelle, Stichtag und Abrufnachweis. Lagedaten ist ein privater Dienst und keine Behörde.

Überblick

Die API liefert amtliche Bodenrichtwerte (BRW) zu einer deutschen Adresse. Die Adresse wird geokodiert, das Bundesland erkannt und der jeweils zuständige amtliche Geodienst abgefragt — standardmäßig zum aktuellsten Stichtag, auf Wunsch zu einem historischen (Parameter stichtag). Basis-URL ist die Domain dieser Seite, alle Antworten sind JSON (UTF-8). Das Tool ist kostenlos und ohne Key nutzbar; ein API-Key erhöht lediglich die Limits.

Optional je Adresse: das amtliche ALKIS-Flurstück (mit_flurstueck) und ein rechnerischer Bodenwert (mit_bodenwert) — beides derzeit nur für NW und ST. Beide Optionen gibt es auch im CSV-Batch.

Hinweis: Bayern (BY) ist derzeit nicht enthalten — Lizenzlage ungeklärt.

Endpunkte

GET /api/v1/abfrage — Einzelabfrage einer Adresse (synchron)

ParameterTypBeschreibung
adresseQuery, Pflicht5–300 Zeichen, z. B. Domplatz 1, 39104 Magdeburg
kompaktQuery, optionaltrue = schlanke Antwort ohne roh_payload und Geometrie (für Integrationen)
mit_flurstueckQuery, optionaltrue = amtliches ALKIS-Flurstück an der Adresse ergänzen. Nur NW und ST — andere Länder liefern den Bodenrichtwert unverändert, aber kein Flurstück.
mit_bodenwertQuery, optionaltrue = rechnerischer Bodenwert (amtliche Fläche × amtlicher BRW, je Zone anteilig). Impliziert mit_flurstueck.
stichtagQuery, optionalJJJJ-MM-TT — historischer Stichtag. Freigegeben für BE, SN, ST, TH. Ohne den Parameter gilt immer der aktuellste Wert.

Historischer Stichtag. Die Abfrage ist geografisch adressiert: „welcher amtliche Wert galt an diesem Punkt zu diesem Stichtag?“ — nicht „was machte Zone X über die Jahre?“. Zonennummern und -zuschnitte sind über Jahrgänge nicht stabil, ein Join über die Nummer würde verschiedene Flächen vermischen.

Ein nicht vorhandener Stichtag wird nie stillschweigend durch den nächstgelegenen oder aktuellen Wert ersetzt. Stattdessen:

{
  "fehler_typ": "stichtag_nicht_verfuegbar",
  "stichtag_angefragt": "2016-01-01",
  "verfuegbare_stichtage": ["2016-12-31", "2018-12-31", "2020-12-31", "2022-01-01"],
  "treffer": []
}

Für ein Land ohne Historie-Freigabe: fehler_typ: "historie_fuer_land_nicht_verfuegbar". Achtung: die Länder mischen die Stichtagskonvention — Thüringen führt 2008–2020 als JJJJ-12-31 und erst ab 2022 als JJJJ-01-01. 2016-01-01 ist dort leer, 2016-12-31 liefert einen Wert. JJJJ-12-31 und 01.01.(JJJJ+1) sind verschiedene Ermittlungszeitpunkte (§ 196 Abs. 1 Satz 5 BauGB, geändert zum 23.06.2021) und werden nicht zusammengelegt.

Bodenwert. ist_amtlich ist immer false: amtlich sind die beiden Eingangswerte (Fläche, Bodenrichtwert), die Multiplikation und Flächenaufteilung sind unsere Berechnung. bodenwert_gesamt_eur ist null, wenn Zonen dieselbe Fläche überdecken — dann sind die Teilwerte alternative Wertansätze, keine Summanden, und Addieren wäre fachlich falsch. Der Grund steht maschinenlesbar in abdeckung und im Klartext in hinweise.

Beispielantwort (gekürzt):

{
  "eingabe_adresse": "Domplatz 1, 39104 Magdeburg",
  "geocode_status": "ok",
  "longitude": 11.6339,
  "latitude": 52.1250,
  "treffer": [
    {
      "bodenrichtwert_eur_qm": 250.0,
      "stichtag": "2024-12-31",
      "bodenrichtwertzone_name": "...",
      "quelle": { "land": "ST", "dienst_bezeichnung": "..." },
      "attribution": {
        "bereitsteller": "(c) GeoBasis-DE / LVermGeo ST (...)",
        "lizenz": "dl-de/by-2-0",
        "lizenz_uri": "https://www.govdata.de/dl-de/by-2-0"
      },
      "modified": "Schema normalisiert, Werte unveraendert"
    }
  ],
  "fehler": null
}

Jeder Treffer trägt die lizenzpflichtige attribution (Bereitsteller · Lizenz · URI) und den Änderungshinweis modified. Diese sind bei jeder Weiterverwendung mitzuführen.

POST /api/v1/batch — CSV-Batch starten (asynchron)

ParameterTypBeschreibung
dateimultipart/form-data, PflichtCSV, max. 1 MB (siehe CSV-Format)
mit_flurstueckForm-Feld, optionaltrue = ALKIS-Flurstück je Adresse (nur NW/ST)
mit_bodenwertForm-Feld, optionaltrue = rechnerischer Bodenwert je Adresse; impliziert mit_flurstueck
stichtagForm-Feld, optionalJJJJ-MM-TT — gilt für den gesamten Lauf, gleiche Regeln wie bei /api/v1/abfrage

Antwort: { "job_id": "abc123...", "adressen": 12, "status": "wartet", "optionen": {...} }

Die Zusatzoptionen verlängern den Lauf spürbar (je Adresse weitere amtliche Abrufe). Die XLSX enthält dann die Flurstücks- und Bodenwertspalten sowie das Detailblatt Bodenwert mit einer Zeile je Teilfläche.

GET /api/v1/batch/{job_id} — Job-Status abfragen

Antwort enthält status (wartet/laeuft/fertig/fehler), verarbeitet, treffer, fehler.

GET /api/v1/batch/{job_id}/download?format=xlsx|json — Ergebnis herunterladen

Liefert die XLSX- bzw. JSON-Datei. Verfügbar, sobald status = fertig.

GET /api/v1/batch/{job_id}/vorschau?limit=20 — Ergebnis-Vorschau (JSON)

GET /api/v1/flurstueck — Flurstück per amtlichem Kennzeichen

ParameterTypBeschreibung
kennzeichenQuery, PflichtALKIS-flstkennz, z. B. 150938145050080001__
mit_bodenwertQuery, optionaltrue = rechnerischer Bodenwert je Flurstück

Das Land wird aus den ersten beiden Stellen abgeleitet (05 = NW, 15 = ST); andere Präfixe liefern HTTP 400 mit klarer Meldung. Das Kennzeichen ist fix 20-stellig und rechts mit Unterstrichen aufgefüllt — kürzere Eingaben werden serverseitig aufgefüllt.

GET /api/v1/laender — aktive Länder, Limits & Quellenvermerke

Das Feld aufrufer zeigt, welche Limits für Sie gelten (erkannt/anonym) — ideal zum Prüfen Ihres Keys.

datenlage weist je Land aus, was der amtliche Dienst wirklich hergibt: geometrie (Zonenfläche für die Karte), klartext (Klartext oder nur amtliche Codes), historie (ist stichtag freigegeben) und zeitreihe (zusätzlich mit Zonenfläche je Stichtag). Die Listen historie_laender und zeitreihe_laender geben dasselbe kompakt.

GET /health — Health-Check (status, version, zeit)

Rate-Limit & API-Keys

ZugangAdressen/BatchAnfragen/StundeZählung
anonym1005pro IP-Adresse
mit gültigem API-Key500100pro Schlüssel

Der Key wird per Header X-API-Key: <key> übergeben; alternativ Authorization: Bearer <key>. Jede Antwort enthält die Header X-RateLimit-Limit und X-RateLimit-Remaining. Firmenkunden hinter einem gemeinsamen Proxy werden pro Schlüssel gezählt, nicht pro IP.

Einen Test-Key können Sie formlos per E-Mail anfragen: foerster.max97@gmail.com.

CSV-Format für Batch-Uploads

CSV (UTF-8 oder Latin-1), eine Adresse je Zeile. Erste Zeile darf die Kopfzeile adresse sein (optional). Enthält eine Zeile mehrere Spalten, werden diese zu einer Adresse zusammengefügt. Duplikate werden entfernt. Maximal 1 MB.

adresse
Domplatz 1, 39104 Magdeburg
Aegidientorplatz 1, 30159 Hannover
Rathausstraße 15, 10178 Berlin

Copy-&-Paste-Beispiele

curl

# Einzelabfrage, ohne Key
curl "https://IHRE-DOMAIN/api/v1/abfrage?adresse=Domplatz%201%2C%2039104%20Magdeburg"

# Einzelabfrage, mit API-Key
curl -H "X-API-Key: IHR_KEY" \
  "https://IHRE-DOMAIN/api/v1/abfrage?adresse=Domplatz%201%2C%2039104%20Magdeburg"

# Batch-Upload (mit Key via Bearer)
curl -H "Authorization: Bearer IHR_KEY" \
  -F "datei=@adressen.csv" \
  "https://IHRE-DOMAIN/api/v1/batch"

Python (requests)

import requests

BASIS = "https://IHRE-DOMAIN"

# ohne Key
r = requests.get(f"{BASIS}/api/v1/abfrage",
                 params={"adresse": "Domplatz 1, 39104 Magdeburg"})
print(r.json())

# mit Key
kopf = {"X-API-Key": "IHR_KEY"}
r = requests.get(f"{BASIS}/api/v1/abfrage",
                 params={"adresse": "Domplatz 1, 39104 Magdeburg"},
                 headers=kopf)
print(r.headers.get("X-RateLimit-Remaining"), r.json())

# Batch mit Key
with open("adressen.csv", "rb") as f:
    r = requests.post(f"{BASIS}/api/v1/batch",
                      files={"datei": f}, headers=kopf)
job = r.json()["job_id"]

JavaScript (fetch)

const BASIS = "https://IHRE-DOMAIN";

// ohne Key
const r1 = await fetch(
  `${BASIS}/api/v1/abfrage?adresse=` +
  encodeURIComponent("Domplatz 1, 39104 Magdeburg"));
console.log(await r1.json());

// mit Key
const r2 = await fetch(
  `${BASIS}/api/v1/abfrage?adresse=` +
  encodeURIComponent("Domplatz 1, 39104 Magdeburg"),
  { headers: { "X-API-Key": "IHR_KEY" } });
console.log(r2.headers.get("X-RateLimit-Remaining"), await r2.json());

// Batch mit Key
const fd = new FormData();
fd.append("datei", dateiObjekt);   // File aus 
const r3 = await fetch(`${BASIS}/api/v1/batch`,
  { method: "POST", body: fd, headers: { "X-API-Key": "IHR_KEY" } });

Fehlercodes

CodeBedeutung
400Ungültige Eingabe (keine Adressen erkannt oder zu viele Adressen im Batch)
401Ungültiger API-Key
404Job oder Ergebnis nicht gefunden
413Upload zu groß (max. 1 MB)
429Rate-Limit überschritten (siehe X-RateLimit-*-Header)

Fehler werden als JSON { "detail": "..." } mit deutscher Meldung zurückgegeben. Ein Abruffehler erscheint nie als „0 Treffer“, sondern als Fehler-/Hinweistext im jeweiligen Ergebnis.

Quellenvermerkspflicht

Die gelieferten Werte stammen unverändert aus amtlichen Diensten der Bundesländer und stehen unter Lizenzen wie dl-de/by-2-0 bzw. dl-de/zero-2.0. Bei jeder Weiterverwendung der Daten sind die zugehörigen Quellen-/Namensnennungen mitzuführen. Die vollständige Liste liefert GET /api/v1/laender (Feld quellenvermerke) und steht in jedem Export. Maschinenlesbar liegt sie je Treffer im Feld attribution vor.

Geocoding: Koordinaten stammen von © OpenStreetMap-Mitwirkenden (ODbL), ermittelt über Nominatim / Photon — bei Weitergabe von Koordinaten mitzuführen.