API des Portals Datenkarte
Die maschinelle Schnittstelle des Portals für Anwendungen und KI-Agenten: Datenkatalog, Daten aus allen Quellen in einheitlicher Form, Abfragen zu einem Ort (was sich an einem Punkt und in seiner Umgebung befindet, Zusammenfassung für eine Gemeinde), Validator und Registrierung für Datenanbieter sowie ein MCP-Server. Alles ist öffentlich, ohne Authentifizierung, mit CORS *. Die formale Beschreibung steht in der OpenAPI.
Überblick
| Methode und Pfad | Zweck |
|---|---|
GET /api/catalog |
alle Anbieter und Datensätze (JSON) |
GET /api/data/{provider}/{dataset} |
Daten eines Datensatzes als GeoJSON, über den Cache des Portals |
GET /api/places?query=… |
Suche nach Adresse, Straße oder Gemeinde → Koordinaten |
GET /api/nearby?point=… |
was sich an einem Punkt und in seiner Umgebung befindet, aus ausgewählten Datensätzen |
GET /api/summary/{provider}/{dataset} |
Zusammenfassung eines Datensatzes für das gesamte Gebiet oder eine Gemeinde |
GET /api/validate?manifestUrl=… |
Live-Test eines Anbieters |
POST /api/validate |
Prüfung von Manifest oder Daten ohne Veröffentlichung |
POST /api/registration |
Registrierung eines Anbieters (die Daten warten auf Freigabe) |
POST /mcp |
MCP-Server (Streamable HTTP) |
GET /llms.txt, /llms-full.txt |
Wegweiser und vollständige Dokumentation für Sprachmodelle |
GET /index.md, /quellen.md, /dokumentation/{slug}.md |
Seiten des Portals in Markdown |
GET /schema/0.1/manifest.json, /schema/0.1/data.json |
JSON Schema des Protokolls |
GET /schema/0.1/provider-openapi.json |
OpenAPI-Vertrag, den der Anbieter implementiert |
GET /beispiele/{datei}.json |
gültige Beispielmanifeste und -antworten |
Katalog
GET /api/catalog
{
"protocol": "0.1",
"generated": "2026-10-06T08:00:00.000Z",
"providers": [{ "id": "cgs", "name": "Česká geologická služba", "status": "ok", "datasetCount": 2, "managedBy": "portal" }],
"datasets": [
{
"key": "cgs/radon",
"providerId": "cgs",
"providerName": "Česká geologická služba",
"title": "Radonový index",
"category": "risks",
"categoryLabel": "Risiken und Einschränkungen",
"keywords": ["radon"],
"useCases": ["construction", "housing"],
"source": { "type": "raster", "tiles": ["https://…"] },
"presentation": { "type": "raster", "opacity": 0.45 },
"attribution": "© Česká geologická služba",
"links": { "data": null, "map": "/?d=cgs/radon" }
}
]
}
Der Katalog enthält nur freigegebene Daten. Datensätze von Anbietern, die sich selbst registriert haben und noch nicht freigegeben sind, sind darin nicht enthalten (siehe Registrierung).
Die Datensätze tragen alle Felder aus dem Manifest des Anbieters (description, fields, params, coverage…) außer der Quell-URL – GeoJSON-Daten werden über das Portal gelesen (links.data), Rasterkacheln direkt von der Quelle (source.tiles). Derselbe Inhalt, lesbar für Menschen wie Modelle: quellen.md.
Daten
GET /api/data/{provider}/{dataset}
| Parameter | Wann | Beschreibung |
|---|---|---|
bbox |
Datensätze mit source.mode = "bbox" (Pflicht) |
minLon,minLat,maxLon,maxLat in WGS84; das Portal richtet ihn an den Kacheln aus |
zoom |
Datensätze mit source.mode = "bbox" (Pflicht) |
Zoomstufe 0–24 |
cursor |
optional | Cursor aus dm.next |
{param} |
nach den params des Datensatzes |
Werte im Format des Protokolls (a,b, von,bis); nicht ausgefüllte erhalten default |
Die Antwort ist eine GeoJSON FeatureCollection. Angaben aus feature.dm des Anbieters werden in properties mit dem Präfix __dm_ verschoben (__dm_title, __dm_description, __dm_url, __dm_color, __dm_chart). Bei Datensätzen mit color.type = "trend" ergänzt das Portal __dm_trend (roste, stagnuje, klesá), berechnet aus dm.chart. Metadaten der Antwort:
{ "dm": { "protocol": "0.1", "dataset": "aopk/pamatne-stromy", "generated": "…", "ttl": 86400, "total": 13, "truncated": false, "notice": null } }
Header X-DM-Cache: hit (aus dem Cache), miss (frisch von der Quelle), stale (Quelle nicht erreichbar, letzte bekannte Daten – siehe dm.notice).
Fehler haben die Form { "error": "Meldung", "code": "kod" }: 400 ungültige Anfrage, 404 unbekannter Datensatz, 502 Fehler der Quelle.
Datensätze nur zur Anzeige. Bei einigen vom Portal verwalteten Datensätzen ist für die Quelle keine Lizenz zur Weiterverbreitung belegt. Das Portal zeichnet sie in seiner eigenen Karte, gibt die Daten aber nicht weiter: Im Katalog ist links.data leer und links.source enthält die Adresse des ursprünglichen Dienstes des Anbieters. Eine Anfrage außerhalb der Karte des Portals erhält 303 mit dem Header Location auf diesen Dienst und dem Body { "error": "…", "code": "display_only", "source": "…" }. Ebenso antwortet das MCP-Werkzeug fetch_data.
Ort und Umgebung
Abfragen für KI-Assistenten und Anwendungen, die Fragen zu einem konkreten Ort beantworten. Sie liefern für Menschen beschriebene Werte (Beschriftungen und Einheiten nach den fields des Datensatzes) ohne Geometrien, mit Quellenangabe und Link zur Karte. Anleitung für Nutzerinnen und Nutzer von Assistenten: Daten für KI-Assistenten.
Ortssuche
GET /api/places?query=Hauptplatz 1, Graz (optional max, standardmäßig 5, höchstens 10)
Sucht im Adressregister nach Adressen, Straßen, Gemeinden, Ortschaften und weiteren Gebietseinheiten. Geben Sie nur die Adresse oder den Namen ein; Präzisierungen wie den Bezirk oder „bei Bad Ischl“ versteht der Dienst nicht. municipality ist die Gemeinde, in der der Ort liegt (name, district, region und die Gemeindekennziffer code) – für sie liefert die Zusammenfassung Daten für die ganze Gemeinde. Bei Orten außerhalb von Städten mit über 10 000 Einwohnern gibt es zusätzlich near mit der nächstgelegenen solchen Stadt und der Entfernung in km; anhand beider Angaben lassen sich gleichnamige Orte unterscheiden.
Für Österreich ist noch kein Adressregister angeschlossen. Bis dahin antwortet die Ortssuche mit geocoding_unavailable (HTTP 501); Abfragen zur Umgebung funktionieren mit Koordinaten (point). Das Beispiel zeigt die Form der Antwort:
{
"query": "Hauptplatz 1, Graz",
"count": 1,
"places": [{ "name": "Hauptplatz 1, 8010 Graz", "type": "Adresse", "point": [15.4382, 47.0709], "municipality": { "slug": "graz", "code": "60101", "name": "Graz", "district": "Graz", "region": "Steiermark" } }],
"attribution": "© Quelle des Adressregisters"
}
Was sich an einem Punkt und in der Umgebung befindet
GET /api/nearby
| Parameter | Beschreibung |
|---|---|
point |
lon,lat in WGS84 |
place |
statt point: Adresse oder Name, verwendet wird der erste Treffer der Ortssuche |
radius |
Umkreis in Metern, standardmäßig 500, höchstens 20 000 |
datasets |
Schlüssel provider/dataset, durch Kommas getrennt, höchstens 12 |
purpose |
statt datasets: Datensätze mit diesem Zweck (useCases), die den Punkt abdecken |
search |
statt datasets: Datensätze nach Übereinstimmung mit einem Text, z. B. Risiken für ein Bauvorhaben |
max |
höchstens so viele Objekte je Datensatz, standardmäßig 5, höchstens 50 |
{provider}/{dataset}.{param} |
Parameter eines Datensatzes, wie im Link zur Karte |
Eines von datasets, purpose, search ist Pflicht. Die automatische Auswahl nimmt nur Datensätze, die zum Punkt Auskunft geben können: zuerst Risiken und Einschränkungen, Grundkarten zuletzt. Datensätze über dem Limit landen in skipped.
- GeoJSON-Datensätze: Objekte bis zur Entfernung
radius, vom nächstgelegenen an sortiert.distanceist in Metern, 0 = der Punkt liegt innerhalb einer Fläche (z. B. einer Gemeinde im Kartogramm).countist die Anzahl der Objekte in der Umgebung. Datensätze, die nur bei starker Vergrößerung geladen werden, verkleinern die Umgebung (radius,notice). Bei vollständigen Datensätzen (mode: full), die in der Umgebung nichts haben, wird zumindest das nächstgelegene Objekt zurückgegeben (z. B. eine Messstation). - Raster-Datensätze: Das Portal fragt die Quelle direkt nach dem Punkt. Die Abfrage leitet es aus der Kachelvorlage ab: WMS
GetMap→GetFeatureInfo, ArcGISMapServer/export→identify,ImageServer/exportImage→identifymit der Klassentabelle des Rasters. Die Werte sind Attribute der Quelle (Feldnamen so, wie die Quelle sie liefert). Bei der Deutung von Codes helfendescriptionundlegend.
status |
Bedeutung |
|---|---|
ok |
Abfrage erfolgreich; leere hits = in der Umgebung / am Punkt ist nichts (z. B. außerhalb eines Überflutungsgebiets) |
unavailable |
der Datensatz liefert am Punkt keinen Wert (die Kacheln sind nur ein Bild) oder der Punkt liegt außerhalb der Abdeckung |
error |
die Quelle ist ausgefallen (error, code) |
{
"place": { "name": "Hauptplatz 1, 8010 Graz", "type": "Adresse", "point": [15.4382, 47.0709] },
"point": [15.4382, 47.0709],
"radius": 500,
"generated": "2026-10-06T16:00:00.000Z",
"results": [
{
"dataset": "cgs/radon",
"title": "Radonový index",
"provider": "Česká geologická služba",
"attribution": "© Česká geologická služba",
"status": "ok",
"hits": [{ "title": "Radonový index", "distance": 0, "values": [{ "label": "radonovériziko", "value": "přechodný" }, { "label": "stupeňradonovéhoindexu", "value": "2" }] }]
},
{
"dataset": "npu/kulturni-pamatky",
"title": "Kulturní památky",
"provider": "Národní památkový ústav",
"attribution": "Národní památkový ústav",
"license": "CC BY-SA 4.0",
"status": "ok",
"count": 27,
"radius": 500,
"hits": [
{
"title": "továrna Breitfeld-Daněk",
"distance": 91,
"values": [{ "label": "Rejstříkové číslo ÚSKP", "value": "105958" }, { "label": "Stav ochrany", "value": "památkově chráněno" }],
"url": "https://pamatkovykatalog.cz/x-14624751"
}
]
}
],
"map": "https://datenkarte.at/?d=cgs/radon&d=npu/kulturni-pamatky#15/47.0709/15.4382"
}
Zusammenfassung
GET /api/summary/{provider}/{dataset}?municipality=Graz (die übrigen Query-Parameter sind Parameter des Datensatzes)
Zusammenfassung eines GeoJSON-Datensatzes für das gesamte Gebiet oder, mit municipality, nur für eine Gemeinde – jede beliebige Gemeinde Österreichs: count, categories (Anzahlen nach Farbkategorie), rankings (höchste und niedrigste Werte) und beim Kartogramm own – die Werte der Fläche, in der die Gemeinde liegt. Es sind dieselben Zahlen, die die Seite des Datensatzes zeigt. Datensätze, die nur bei starker Vergrößerung geladen werden, haben eine Zusammenfassung nur für eine Gemeinde. Raster-Datensätze haben keine Zusammenfassung.
municipality ist der Name („Graz“), der Name mit Bezirk oder Bundesland („Krumbach (Bezirk Bregenz)“), die Gemeindekennziffer („60101“, die Ortssuche liefert sie in municipality.code) oder die Adresse ihrer Übersichtsseite („vorarlberg/krumbach“). Ein bloßer Name, den mehrere Gemeinden tragen, endet mit dem Fehler ambiguous_place und einer Liste dieser Gemeinden mit Bezirk und Code.
Validator
Ein Werkzeug für Datenanbieter und ihre KI-Agenten. Liefert immer HTTP 200 und einen Bericht:
{
"valid": false,
"summary": "Das Manifest ist nicht gültig: 1 Fehler, 2 Empfehlungen.",
"errors": [{ "path": "datasets[0].source.tiles[0]", "code": "raster_without_template", "message": "Die Kachelvorlage enthält weder {z}/{x}/{y} noch {bbox-epsg-3857}." }],
"warnings": [{ "path": "datasets[0].keywords", "code": "missing_keywords", "message": "Der Datensatz hat keine Schlüsselwörter.", "hint": "Ergänzen Sie 5–15 Wörter…" }]
}
POST /api/validatemit dem Body:- Manifest (Objekt mit
datasets) oder{ "manifest": … }– statische Prüfung, - GeoJSON
FeatureCollectionoder{ "data": …, "dataset": … }– Prüfung der Daten; mitdataset(Datensatz-Objekt aus dem Manifest) auch die Übereinstimmung mit dem Manifest, { "manifestUrl": "https://…" }– Live-Test.
- Manifest (Objekt mit
GET /api/validate?manifestUrl=https://…– Live-Test: lädt das Manifest, prüft es und sendet für jeden Datensatz eine Testanfrage wie das Portal (beibboxauf die Mitte voncoverage.bbox, Zoom 12 odercoverage.minZoom; bei Rastern eine Kachel). Der Bericht enthält zusätzlichproviderunddatasets[]mitrequest,durationMs,featureCount,errors,warnings.
Registrierung
POST /api/registration mit dem Body { "manifestUrl": "https://…" }. Das Portal prüft das Manifest mit einem Live-Test (wie der Validator). Besteht es, wird der Anbieter unter den ungeprüften Daten registriert:
- Die Daten sind über
/api/data/…und auf den Seiten der Datensätze/karte/{provider}/{dataset}verfügbar. Die Seite zeigt zuerst eine Warnung, dass die Daten von Dritten hochgeladen und vom Betreiber nicht freigegeben wurden. Die Daten werden erst nach Bestätigung in die Karte geladen. Die Seite hatnoindex. - In den Katalog, die Suche,
llms.txt, das MCP-Werkzeugcatalogund auf die Gemeindeseiten gelangen die Daten erst nach Freigabe durch den Betreiber. - Die Freigabe gilt für den Fingerabdruck (SHA-256) des Manifestinhalts. Nach einer Änderung des Manifests ist der Anbieter wieder ungeprüft, bis ihn der Betreiber erneut freigibt.
- Übersicht der ungeprüften Anbieter: /ungepruefte-daten.
{
"registered": true,
"status": "pending_review",
"message": "Registriert. …",
"provider": { "id": "gemeinde-beispiel", "name": "Gemeinde Beispiel" },
"links": { "review": "/ungepruefte-daten#gemeinde-beispiel", "datasets": ["/karte/gemeinde-beispiel/parkbaenke"] },
"check": { "summary": "Der Anbieter ist ohne Einschränkungen gültig.", "warnings": [] }
}
| HTTP | code |
Bedeutung |
|---|---|---|
| 201 | – | registriert, wartet auf Freigabe |
| 200 | – | bereits registriert; status ist pending_review oder approved |
| 400 | invalid_input, invalid_url |
manifestUrl fehlt oder ist ungültig |
| 403 | rejected |
der Betreiber hat die Registrierung abgelehnt |
| 409 | id_taken, url_registered |
provider.id existiert im Portal bereits / die URL ist unter einer anderen id registriert |
| 422 | manifest_rejected |
der Live-Test ist fehlgeschlagen; der Bericht steht in check |
| 429 | too_many_requests, queue_full |
mehr als 5 Versuche pro Minute von einer Adresse / über 100 Anbieter warten auf Freigabe |
| 503 | registration_unavailable |
die Registrierung funktioniert derzeit nicht |
MCP-Server
Endpoint https://datenkarte.at/mcp, Transport Streamable HTTP (zustandslos, Antworten in JSON), ohne Authentifizierung.
| Werkzeug | Eingabe | Ausgabe |
|---|---|---|
documentation |
topic: ai-agents, ai-assistants, protocol, providers, api, about |
Markdown des Dokuments |
schema |
type: manifest, data, provider-openapi |
JSON Schema / OpenAPI |
example |
name: manifest-minimal, manifest-complete, data-points, data-polygons |
gültiges Beispiel-JSON |
validate_manifest |
manifest (Objekt) oder manifestUrl (Live-Test) |
Bericht des Validators |
validate_data |
data, optional dataset |
Bericht des Validators |
register_provider |
manifestUrl |
Ergebnis der Registrierung |
catalog |
optional search (Freitext), point ([lon, lat]) |
Datensätze im Portal, nach Übereinstimmung sortiert; pointQuery = der Datensatz beantwortet nearby |
find_place |
query, maxResults |
wie die Ortssuche |
nearby |
point oder place; datasets, purpose oder search; radius, maxFeatures, params ({ "provider/dataset": { "param": "wert" } }) |
wie was sich an einem Punkt und in der Umgebung befindet |
summary |
dataset, optional municipality, params |
wie die Zusammenfassung |
fetch_data |
dataset (provider/dataset), bbox oder municipality, zoom, params, maxFeatures |
GeoJSON (auf maxFeatures gekürzt) |
Verbindung:
claude mcp add --transport http datenkarte https://datenkarte.at/mcp
{ "mcpServers": { "datenkarte": { "type": "http", "url": "https://datenkarte.at/mcp" } } }
Link zur Karte
https://datenkarte.at/?d={provider}/{dataset}&d=…&{provider}/{dataset}.{param}={wert}#{zoom}/{lat}/{lon}
Jeder Datensatz hat außerdem eine eigene Seite mit Karte und Beschreibung: https://datenkarte.at/karte/{provider}/{dataset}, bundesweite GeoJSON-Datensätze auch für Gemeinden mit über 10 000 Einwohnern: https://datenkarte.at/karte/{provider}/{dataset}/{gemeinde} (z. B. /karte/{provider}/{dataset}/graz). Der Link zur Seite des Datensatzes steht im Katalog in links.map. Auf der Seite eines Datensatzes (auch einer zusammengestellten Karte /karten/{slug}) wird in ?d=… nur die Abweichung von der Standardauswahl geschrieben: Ohne d gelten die Datensätze der Seite, d zählt die gesamte Auswahl auf (?d= = nichts ist eingeschaltet), und ein Parameter wird nur angegeben, wenn er vom Standardwert abweicht.
Beispiel – Verkehrsunfälle in Brünn zusammengefasst für die Jahre 2019–2023: /?d=brno/dopravni-nehody&brno/dopravni-nehody.obdobi=2019,2023#13/49.195/16.608
Befundcodes
Stabile Codes für Fehler (errors) und Empfehlungen (warnings) von Validator und Proxy.
Manifest
| Code | Stufe | Bedeutung |
|---|---|---|
schema_* |
Fehler | Verstoß gegen das JSON Schema (schema_invalid_type, schema_too_small, schema_invalid_format, schema_invalid_value, schema_custom…), path zeigt die Stelle |
unsupported_version |
Fehler | andere Hauptversion des Protokolls |
raster_without_template |
Fehler | Kachel-URL weder mit {z}/{x}/{y} noch mit {bbox-epsg-3857} |
geojson_with_raster_presentation |
Fehler | GeoJSON-Quelle mit presentation.type: "raster" |
param_without_options |
Fehler | enum / multi-enum ohne options |
invalid_default |
Fehler | default des Parameters passt nicht zum Typ oder zu den Optionen |
time_param_missing |
Fehler | temporal.param verweist auf einen Parameter, der nicht in params steht |
time_param_type |
Fehler | der Zeitparameter ist weder vom Typ range noch date-range |
time_param_no_range |
Empfehlung | der Zeitparameter vom Typ range hat kein min und max |
unknown_presentation_type |
Empfehlung | das Portal kennt den Typ nicht und zeichnet auto |
raster_without_raster_presentation |
Empfehlung | ein Raster wird immer als raster gezeichnet |
missing_description, missing_keywords, missing_use_cases |
Empfehlung | Menschen wie Assistent finden den Datensatz schlechter |
missing_category, unknown_category |
Empfehlung | der Datensatz landet unter „Sonstiges“ |
missing_field |
Empfehlung | das Objektdetail zeigt rohe Eigenschaftsnamen |
field_not_described, field_not_number |
Empfehlung | die Darstellung verweist auf eine Eigenschaft außerhalb von fields / mit nicht numerischem Typ |
bbox_unbounded |
Empfehlung | bbox-Datensatz ohne coverage.minZoom und maxFeatures |
missing_coverage |
Empfehlung | bbox-Datensatz ohne coverage.bbox |
missing_license, missing_website |
Empfehlung | Lizenz / Website des Anbieters fehlt |
Daten
| Code | Stufe | Bedeutung |
|---|---|---|
coordinates_out_of_range |
Fehler | Koordinaten außerhalb von WGS84 (typischerweise nicht umgerechnetes MGI / Austria Lambert, EPSG:31287, oder Gauß-Krüger, EPSG:31257–31259) |
unclosed_polygon |
Fehler | der Ring eines Polygons ist nicht geschlossen |
too_many_features |
Empfehlung | mehr Objekte als limit / 5 000 |
missing_time_series |
Empfehlung | der Datensatz hat temporal.param, die Antwort sendet weder dm.timeline noch dm.chart |
missing_trend_chart |
Empfehlung | der Datensatz färbt nach einem Zahlenwert und wählt den Zeitraum per Parameter, die Objekte senden jedoch kein dm.chart |
trend_without_chart |
Empfehlung | der Datensatz färbt nach Trend, manche Objekte haben kein dm.chart (sie bleiben grau) |
swapped_coordinates |
Empfehlung | Koordinaten vermutlich in der Reihenfolge [lat, lon] |
outside_coverage |
Empfehlung | die meisten Objekte liegen außerhalb von coverage.bbox |
geometry_presentation_mismatch |
Empfehlung | z. B. Flächen bei circle |
field_missing_in_data, missing_presentation_property |
Empfehlung | eine Eigenschaft aus dem Manifest fehlt in den Daten |
missing_id |
Empfehlung | Objekte ohne id |
empty_geometry |
Empfehlung | Objekte mit geometry: null werden übersprungen |
Live-Test und Proxy
| Code | Bedeutung |
|---|---|
invalid_url, https_required |
ungültige URL / die Quelle läuft nicht über HTTPS |
source_unreachable, timeout, http_error |
die Quelle antwortet nicht, hat die 10 s überschritten, hat einen HTTP-Fehler geliefert |
invalid_json, empty_body, response_too_large |
die Antwort ist kein JSON / ist leer / ist größer als 15 MB |
invalid_manifest, id_mismatch |
das Manifest eines registrierten Anbieters ist durchgefallen / hat eine andere provider.id |
registration_unavailable, too_many_requests, queue_full, manifest_rejected, id_taken, url_registered, rejected |
Fehler der Registrierung |
data_schema_mismatch |
die Daten der Quelle entsprechen nicht dem Schema |
empty_response, slow_response |
die Testanfrage lieferte 0 Objekte / dauerte über 3 s |
tile_http_error, tile_not_image, tile_unreachable |
die Test-Rasterkachel ist fehlgeschlagen |
source_error |
anderer Fehler bei der Kommunikation mit der Quelle (Details in message) |
invalid_query, unknown_dataset, raster_dataset, invalid_input, internal_error |
Fehler einer Anfrage an das Portal |
display_only |
das Portal zeigt den Datensatz nur an, die Daten liefert der ursprüngliche Dienst (source) |
missing_place, unknown_place |
Ortsabfrage ohne Punkt und ohne Ort / der Ort (Adresse, Gemeinde) wurde nicht gefunden |
geocoding_unavailable |
die Suche nach Adressen und Orten gibt es im Portal für dieses Land noch nicht (HTTP 501) |
ambiguous_place |
den Gemeindenamen tragen mehrere Gemeinden – die Meldung zählt sie mit Bezirk und Code auf |
missing_dataset_selection |
Umgebungsabfrage ohne datasets, purpose und search |
summary_requires_place |
der Datensatz lässt sich nur vergrößert laden und hat keine Zusammenfassung für das gesamte Gebiet – geben Sie eine Gemeinde an |
unknown_schema, unknown_example |
nicht existierendes Schema / Beispiel (die Antwort enthält die Liste available) |