{
  "openapi": "3.1.0",
  "info": {
    "title": "Datenkarte – API des Portals",
    "version": "0.1",
    "description": "Datenkatalog, vereinheitlichte Daten aller Anbieter, Abfragen zu einem Ort (was am Punkt und in der Umgebung ist, Übersicht für eine Gemeinde) und Validator des Protokolls. Dokumentation: https://datenkarte.at/dokumentation/api.md, Anleitung für KI-Assistenten: https://datenkarte.at/dokumentation/ki-assistenten.md"
  },
  "servers": [
    {
      "url": "https://datenkarte.at"
    }
  ],
  "externalDocs": {
    "url": "https://datenkarte.at/llms.txt",
    "description": "Wegweiser durch die Dokumentation für Sprachmodelle"
  },
  "paths": {
    "/api/catalog": {
      "get": {
        "operationId": "getCatalog",
        "summary": "Alle Anbieter und Datensätze",
        "responses": {
          "200": {
            "description": "Katalog",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/data/{provider}/{dataset}": {
      "get": {
        "operationId": "fetchData",
        "summary": "Daten eines Datensatzes als GeoJSON (über den Cache des Portals)",
        "description": "Weitere Query-Parameter gemäß `params` des Datensatzes im Katalog. Angaben aus feature.dm stehen in properties mit dem Präfix __dm_.",
        "parameters": [
          {
            "name": "provider",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dataset",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "bbox",
            "in": "query",
            "schema": {
              "type": "string",
              "example": "16.5,49.1,16.7,49.3"
            },
            "description": "minLon,minLat,maxLon,maxLat; Pflicht bei Datensätzen mit mode bbox"
          },
          {
            "name": "zoom",
            "in": "query",
            "schema": {
              "type": "number",
              "minimum": 0,
              "maximum": 24
            },
            "description": "Pflicht bei Datensätzen mit mode bbox"
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "GeoJSON FeatureCollection",
            "headers": {
              "X-DM-Cache": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "hit",
                    "miss",
                    "stale"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string",
                      "const": "FeatureCollection"
                    },
                    "features": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "const": "Feature"
                          },
                          "id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "maxLength": 200
                              },
                              {
                                "type": "number"
                              }
                            ]
                          },
                          "geometry": {
                            "anyOf": [
                              {
                                "oneOf": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "const": "Point"
                                      },
                                      "coordinates": {
                                        "minItems": 2,
                                        "maxItems": 3,
                                        "type": "array",
                                        "items": {
                                          "type": "number"
                                        }
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "coordinates"
                                    ]
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "const": "MultiPoint"
                                      },
                                      "coordinates": {
                                        "type": "array",
                                        "items": {
                                          "minItems": 2,
                                          "maxItems": 3,
                                          "type": "array",
                                          "items": {
                                            "type": "number"
                                          }
                                        }
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "coordinates"
                                    ]
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "const": "LineString"
                                      },
                                      "coordinates": {
                                        "minItems": 2,
                                        "type": "array",
                                        "items": {
                                          "minItems": 2,
                                          "maxItems": 3,
                                          "type": "array",
                                          "items": {
                                            "type": "number"
                                          }
                                        }
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "coordinates"
                                    ]
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "const": "MultiLineString"
                                      },
                                      "coordinates": {
                                        "type": "array",
                                        "items": {
                                          "minItems": 2,
                                          "type": "array",
                                          "items": {
                                            "minItems": 2,
                                            "maxItems": 3,
                                            "type": "array",
                                            "items": {
                                              "type": "number"
                                            }
                                          }
                                        }
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "coordinates"
                                    ]
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "const": "Polygon"
                                      },
                                      "coordinates": {
                                        "type": "array",
                                        "items": {
                                          "minItems": 4,
                                          "type": "array",
                                          "items": {
                                            "minItems": 2,
                                            "maxItems": 3,
                                            "type": "array",
                                            "items": {
                                              "type": "number"
                                            }
                                          }
                                        }
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "coordinates"
                                    ]
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "const": "MultiPolygon"
                                      },
                                      "coordinates": {
                                        "type": "array",
                                        "items": {
                                          "type": "array",
                                          "items": {
                                            "minItems": 4,
                                            "type": "array",
                                            "items": {
                                              "minItems": 2,
                                              "maxItems": 3,
                                              "type": "array",
                                              "items": {
                                                "type": "number"
                                              }
                                            }
                                          }
                                        }
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "coordinates"
                                    ]
                                  }
                                ]
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "properties": {
                            "default": {},
                            "anyOf": [
                              {
                                "type": "object",
                                "propertyNames": {
                                  "type": "string"
                                },
                                "additionalProperties": {}
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "dm": {
                            "type": "object",
                            "properties": {
                              "title": {
                                "description": "Titel des Objekts in der Detailansicht",
                                "type": "string",
                                "maxLength": 200
                              },
                              "description": {
                                "type": "string",
                                "maxLength": 2000
                              },
                              "url": {
                                "description": "Link zur Detailseite des Objekts beim Anbieter",
                                "type": "string",
                                "format": "uri"
                              },
                              "color": {
                                "description": "Überschreibt die Farbe aus der Darstellung",
                                "type": "string",
                                "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                              },
                              "chart": {
                                "description": "Diagramm der Wertentwicklung in der Detailansicht des Objekts",
                                "type": "object",
                                "properties": {
                                  "label": {
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 80,
                                    "description": "Was das Diagramm zeigt, z. B. Einwohnerzahl"
                                  },
                                  "unit": {
                                    "type": "string",
                                    "maxLength": 20
                                  },
                                  "decimals": {
                                    "type": "integer",
                                    "minimum": 0,
                                    "maximum": 6
                                  },
                                  "note": {
                                    "description": "Anmerkung unter dem Diagramm, z. B. zu einer Methodenänderung",
                                    "type": "string",
                                    "maxLength": 200
                                  },
                                  "highlight": {
                                    "description": "Hervorgehobener Zeitraum (z. B. im Zeitfilter gewählt) – das Portal hinterlegt ihn farbig, zeigt den Wert an seinem Ende und berechnet Veränderung und Trend ab seinem Beginn. Gleiche from und to = ein gewählter Zeitraum (z. B. ein Jahr).",
                                    "type": "object",
                                    "properties": {
                                      "from": {
                                        "type": "string",
                                        "pattern": "^\\d{4}(?:-\\d{2}(?:-\\d{2})?)?$",
                                        "description": "Jahr, Monat oder Tag in ISO 8601"
                                      },
                                      "to": {
                                        "type": "string",
                                        "pattern": "^\\d{4}(?:-\\d{2}(?:-\\d{2})?)?$",
                                        "description": "Jahr, Monat oder Tag in ISO 8601"
                                      }
                                    },
                                    "required": [
                                      "from",
                                      "to"
                                    ]
                                  },
                                  "points": {
                                    "minItems": 2,
                                    "maxItems": 100,
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "period": {
                                          "type": "string",
                                          "pattern": "^\\d{4}(?:-\\d{2}(?:-\\d{2})?)?$",
                                          "description": "Jahr, Monat oder Tag in ISO 8601"
                                        },
                                        "value": {
                                          "type": "number"
                                        }
                                      },
                                      "required": [
                                        "period",
                                        "value"
                                      ]
                                    },
                                    "description": "Werte, sortiert ab dem ältesten Zeitraum"
                                  }
                                },
                                "required": [
                                  "label",
                                  "points"
                                ]
                              }
                            }
                          }
                        },
                        "required": [
                          "type",
                          "geometry"
                        ]
                      }
                    },
                    "dm": {
                      "type": "object",
                      "properties": {
                        "protocol": {
                          "type": "string"
                        },
                        "generated": {
                          "description": "Zeitpunkt, zu dem die Antwort erstellt wurde (ISO 8601)",
                          "type": "string",
                          "maxLength": 40
                        },
                        "ttl": {
                          "description": "Wie lange (s) die Antwort gültig ist",
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "total": {
                          "description": "Gesamtzahl der Objekte, die der Abfrage entsprechen",
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "truncated": {
                          "description": "Die Antwort enthält nicht alle Objekte (Limit)",
                          "type": "boolean"
                        },
                        "next": {
                          "description": "Cursor für die nächste Seite",
                          "type": "string",
                          "maxLength": 500
                        },
                        "notice": {
                          "description": "Kurze Mitteilung für Nutzer, z. B. Karte vergrößern",
                          "type": "string",
                          "maxLength": 300
                        },
                        "timeline": {
                          "description": "Anzahl der Objekte im Kartenausschnitt nach Zeiträumen über die gesamte Dauer, die der Datensatz abdeckt – unabhängig vom gewählten Zeitraum und Limit. Das Portal zeichnet daraus ein Diagramm bei der Legende.",
                          "maxItems": 400,
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "period": {
                                "type": "string",
                                "pattern": "^\\d{4}(?:-\\d{2}(?:-\\d{2})?)?$",
                                "description": "Jahr, Monat oder Tag in ISO 8601"
                              },
                              "count": {
                                "type": "integer",
                                "minimum": 0,
                                "maximum": 9007199254740991
                              },
                              "values": {
                                "description": "Aufschlüsselung der Anzahl nach den Werten der Eigenschaft, nach der die Objekte eingefärbt werden (color.field) – das Diagramm färbt sie wie die Legende",
                                "type": "object",
                                "propertyNames": {
                                  "type": "string",
                                  "maxLength": 100
                                },
                                "additionalProperties": {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 9007199254740991
                                }
                              }
                            },
                            "required": [
                              "period",
                              "count"
                            ]
                          }
                        },
                        "chart": {
                          "description": "Zusammengefasste Entwicklung des Werts für das gesamte Gebiet des Datensatzes oder den Kartenausschnitt (z. B. Einwohnerzahl Österreichs) – das Portal zeigt sie beim Zeitfilter an, wenn die Antwort kein dm.timeline mitsendet",
                          "type": "object",
                          "properties": {
                            "label": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 80,
                              "description": "Was das Diagramm zeigt, z. B. Einwohnerzahl"
                            },
                            "unit": {
                              "type": "string",
                              "maxLength": 20
                            },
                            "decimals": {
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 6
                            },
                            "note": {
                              "description": "Anmerkung unter dem Diagramm, z. B. zu einer Methodenänderung",
                              "type": "string",
                              "maxLength": 200
                            },
                            "highlight": {
                              "description": "Hervorgehobener Zeitraum (z. B. im Zeitfilter gewählt) – das Portal hinterlegt ihn farbig, zeigt den Wert an seinem Ende und berechnet Veränderung und Trend ab seinem Beginn. Gleiche from und to = ein gewählter Zeitraum (z. B. ein Jahr).",
                              "type": "object",
                              "properties": {
                                "from": {
                                  "type": "string",
                                  "pattern": "^\\d{4}(?:-\\d{2}(?:-\\d{2})?)?$",
                                  "description": "Jahr, Monat oder Tag in ISO 8601"
                                },
                                "to": {
                                  "type": "string",
                                  "pattern": "^\\d{4}(?:-\\d{2}(?:-\\d{2})?)?$",
                                  "description": "Jahr, Monat oder Tag in ISO 8601"
                                }
                              },
                              "required": [
                                "from",
                                "to"
                              ]
                            },
                            "points": {
                              "minItems": 2,
                              "maxItems": 100,
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "period": {
                                    "type": "string",
                                    "pattern": "^\\d{4}(?:-\\d{2}(?:-\\d{2})?)?$",
                                    "description": "Jahr, Monat oder Tag in ISO 8601"
                                  },
                                  "value": {
                                    "type": "number"
                                  }
                                },
                                "required": [
                                  "period",
                                  "value"
                                ]
                              },
                              "description": "Werte, sortiert ab dem ältesten Zeitraum"
                            }
                          },
                          "required": [
                            "label",
                            "points"
                          ]
                        }
                      }
                    }
                  },
                  "required": [
                    "type",
                    "features"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Ungültige Anfrage",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unbekannter Datensatz",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Fehler der Datenquelle",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/nearby": {
      "get": {
        "operationId": "nearby",
        "summary": "Was laut den ausgewählten Datensätzen am Punkt und in der Umgebung ist",
        "description": "GeoJSON-Datensätze: Objekte bis zur Entfernung radius, sortiert vom nächstgelegenen (distance in Metern, 0 = Punkt innerhalb der Fläche). Rasterdatensätze: Elemente direkt am Punkt (WMS GetFeatureInfo / ArcGIS identify). status ok mit leeren hits = hier ist nichts, unavailable = der Datensatz liefert keinen Wert am Punkt. Einer der Parameter datasets, purpose, search ist Pflicht. Parameter der Datensätze: {provider}/{dataset}.{param}=hodnota.",
        "parameters": [
          {
            "name": "point",
            "in": "query",
            "schema": {
              "type": "string",
              "example": "14.4527,50.0914"
            },
            "description": "lon,lat in WGS84"
          },
          {
            "name": "place",
            "in": "query",
            "schema": {
              "type": "string",
              "example": "Thámova 7, Praha"
            },
            "description": "Ort statt Punkt: Adresse oder Name (erster Treffer der Ortssuche)"
          },
          {
            "name": "radius",
            "in": "query",
            "schema": {
              "type": "number",
              "minimum": 1,
              "maximum": 20000,
              "default": 500
            },
            "description": "Umkreis in Metern"
          },
          {
            "name": "datasets",
            "in": "query",
            "schema": {
              "type": "string",
              "example": "vuv/zaplavova-uzemi,cgs/radon"
            },
            "description": "Schlüssel provider/dataset, durch Komma getrennt, höchstens 12"
          },
          {
            "name": "purpose",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "construction",
                "housing",
                "land-purchase",
                "agriculture",
                "investment",
                "transport",
                "tourism",
                "business",
                "public-administration"
              ]
            },
            "description": "Datensätze mit diesem Zweck, die den Punkt abdecken"
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Datensätze nach Übereinstimmung mit dem Text"
          },
          {
            "name": "max",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 5
            },
            "description": "Höchstzahl der Objekte pro Datensatz"
          }
        ],
        "responses": {
          "200": {
            "description": "Ergebnisse nach Datensätzen",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PointAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Ungültige Anfrage",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Der Ort wurde nicht gefunden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/summary/{provider}/{dataset}": {
      "get": {
        "operationId": "summary",
        "summary": "Übersicht eines GeoJSON-Datensatzes für das gesamte Gebiet oder für eine Gemeinde",
        "description": "Anzahl der Objekte, Kategorien, höchste und niedrigste Werte, beim Kartogramm die Werte der Gemeindefläche (own). Weitere Query-Parameter sind Parameter des Datensatzes.",
        "parameters": [
          {
            "name": "provider",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dataset",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "municipality",
            "in": "query",
            "schema": {
              "type": "string",
              "example": "Ostrava"
            },
            "description": "Jede Gemeinde Österreichs: Name, Name mit Bezirk („Krumbach (Bezirk Bregenz)“) oder Gemeindekennziffer"
          }
        ],
        "responses": {
          "200": {
            "description": "Übersicht",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Rasterdatensatz oder Datensatz nur bei starker Vergrößerung (geben Sie eine Gemeinde an)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unbekannter Datensatz oder unbekannte Gemeinde",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Fehler der Datenquelle",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/validate": {
      "get": {
        "operationId": "checkProvider",
        "summary": "Live-Test: ruft das Manifest ab und sendet eine Testabfrage an jeden Datensatz",
        "parameters": [
          {
            "name": "manifestUrl",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Bericht",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Report"
                }
              }
            }
          },
          "400": {
            "description": "manifestUrl fehlt",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "validate",
        "summary": "Prüfung von Manifest oder Daten ohne Veröffentlichung",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/Manifest"
                  },
                  {
                    "$ref": "#/components/schemas/DataResponse"
                  },
                  {
                    "type": "object",
                    "required": [
                      "manifest"
                    ],
                    "properties": {
                      "manifest": {
                        "$ref": "#/components/schemas/Manifest"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "data"
                    ],
                    "properties": {
                      "data": {
                        "$ref": "#/components/schemas/DataResponse"
                      },
                      "dataset": {
                        "type": "object",
                        "description": "Datensatz aus dem Manifest"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "manifestUrl"
                    ],
                    "properties": {
                      "manifestUrl": {
                        "type": "string",
                        "format": "uri"
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bericht",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Report"
                }
              }
            }
          },
          "400": {
            "description": "Ungültige Eingabe",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/registration": {
      "post": {
        "operationId": "registerProvider",
        "summary": "Registrierung eines Anbieters: Live-Test des Manifests und Aufnahme unter die ungeprüften Daten",
        "description": "Nach der Registrierung sind die Daten nur auf den Datensatzseiten mit Warnhinweis verfügbar; in den Katalog gelangen sie nach Freigabe durch den Betreiber. Die Freigabe gilt für den konkreten Inhalt des Manifests.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "manifestUrl"
                ],
                "properties": {
                  "manifestUrl": {
                    "type": "string",
                    "format": "uri"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bereits registriert (Stand im Feld status)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "201": {
            "description": "Registriert, wartet auf Freigabe",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Ungültige Eingabe",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Die Registrierung wurde abgelehnt",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Id oder URL des Manifests ist bereits registriert",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Das Manifest hat den Live-Test nicht bestanden (Bericht im Feld check)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Zu viele Anfragen oder volle Warteschlange für die Freigabe",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Registrierung nicht verfügbar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dokumentation/fuer-ki-agenten.md": {
      "get": {
        "operationId": "documentation_ai_agents",
        "summary": "Anleitung für KI-Agenten",
        "description": "Vorgehen Schritt für Schritt, Regeln, Codevorlagen und Kriterien für eine fertige Arbeit für den Agenten, der die Daten eines Anbieters vorbereitet.",
        "responses": {
          "200": {
            "description": "Markdown",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/dokumentation/ki-assistenten.md": {
      "get": {
        "operationId": "documentation_ai_assistants",
        "summary": "Daten für KI-Assistenten",
        "description": "Wie Sie die Datenkarte mit einem KI-Assistenten verbinden (MCP, HTTP-API) und nach Orten und Daten fragen.",
        "responses": {
          "200": {
            "description": "Markdown",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/dokumentation/fuer-datenanbieter.md": {
      "get": {
        "operationId": "documentation_providers",
        "summary": "Für Datenanbieter",
        "description": "Wie Sie Daten anbinden: statische Dateien, eigener Endpunkt oder WMS; Manifest, Daten, Visualisierungen, Prüfung, Bedingungen.",
        "responses": {
          "200": {
            "description": "Markdown",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/dokumentation/protokoll.md": {
      "get": {
        "operationId": "documentation_protocol",
        "summary": "Protokoll 0.1",
        "description": "Normative Spezifikation von Manifest, Datenabfrage, Antwort und Cache.",
        "responses": {
          "200": {
            "description": "Markdown",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/dokumentation/api.md": {
      "get": {
        "operationId": "documentation_api",
        "summary": "Portal-API und MCP-Server",
        "description": "Katalog, Daten, Validator, MCP-Werkzeuge, Links auf die Karte und Fundcodes.",
        "responses": {
          "200": {
            "description": "Markdown",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/dokumentation/ueber-das-projekt.md": {
      "get": {
        "operationId": "documentation_about",
        "summary": "Über das Projekt",
        "description": "Vision der Datenkarte, Prinzipien und Entwicklungsplan.",
        "responses": {
          "200": {
            "description": "Markdown",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Manifest": {
        "type": "object",
        "properties": {
          "$schema": {
            "type": "string"
          },
          "protocol": {
            "type": "string",
            "pattern": "^\\d+\\.\\d+$",
            "description": "Version des Protokolls, nach der das Manifest geschrieben ist, z. B. 0.1"
          },
          "provider": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$",
                "examples": [
                  "mesto-brno",
                  "kontejnery-na-odpad"
                ]
              },
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120
              },
              "description": {
                "type": "string",
                "maxLength": 1000
              },
              "homepage": {
                "type": "string",
                "format": "uri"
              },
              "logo": {
                "type": "string",
                "format": "uri"
              },
              "contact": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email",
                    "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                  },
                  "url": {
                    "type": "string",
                    "format": "uri"
                  }
                }
              },
              "managedBy": {
                "default": "provider",
                "description": "portal = das Manifest für einen öffentlichen Dienst pflegt die Datenkarte, nicht der Dateninhaber",
                "type": "string",
                "enum": [
                  "provider",
                  "portal"
                ]
              }
            },
            "required": [
              "id",
              "name"
            ]
          },
          "license": {
            "description": "Standardlizenz für alle Datensätze",
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1,
                "description": "Name der Lizenz, z. B. CC BY 4.0"
              },
              "url": {
                "type": "string",
                "format": "uri"
              },
              "attribution": {
                "type": "string",
                "minLength": 1,
                "maxLength": 300,
                "description": "Text der Namensnennung, den das Portal bei der Karte anzeigt, z. B. © GeoSphere Austria"
              }
            },
            "required": [
              "name",
              "attribution"
            ]
          },
          "datasets": {
            "minItems": 1,
            "maxItems": 200,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "pattern": "^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$",
                  "examples": [
                    "mesto-brno",
                    "kontejnery-na-odpad"
                  ]
                },
                "title": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 120
                },
                "description": {
                  "type": "string",
                  "maxLength": 1000
                },
                "category": {
                  "description": "Empfohlene Werte: territory, nature, water, risks, energy, transport, society, economy, infrastructure, sample, other",
                  "type": "string",
                  "maxLength": 40
                },
                "tags": {
                  "maxItems": 30,
                  "type": "array",
                  "items": {
                    "type": "string",
                    "maxLength": 40
                  }
                },
                "keywords": {
                  "description": "Wörter und Synonyme, über die Nutzer und der KI-Assistent des Portals den Datensatz finden. Schreiben Sie auf Deutsch, auch umgangssprachliche Formen.",
                  "examples": [
                    [
                      "odpad",
                      "kontejner",
                      "třídění",
                      "popelnice"
                    ]
                  ],
                  "maxItems": 60,
                  "type": "array",
                  "items": {
                    "type": "string",
                    "maxLength": 60
                  }
                },
                "useCases": {
                  "description": "Wofür der Datensatz nützlich ist. Empfohlene Werte: construction, housing, land-purchase, agriculture, investment, transport, tourism, business, public-administration; andere sind erlaubt.",
                  "examples": [
                    [
                      "construction",
                      "housing"
                    ]
                  ],
                  "maxItems": 20,
                  "type": "array",
                  "items": {
                    "type": "string",
                    "maxLength": 60
                  }
                },
                "coverage": {
                  "type": "object",
                  "properties": {
                    "bbox": {
                      "type": "array",
                      "prefixItems": [
                        {
                          "type": "number",
                          "minimum": -180,
                          "maximum": 180
                        },
                        {
                          "type": "number",
                          "minimum": -90,
                          "maximum": 90
                        },
                        {
                          "type": "number",
                          "minimum": -180,
                          "maximum": 180
                        },
                        {
                          "type": "number",
                          "minimum": -90,
                          "maximum": 90
                        }
                      ],
                      "items": false,
                      "minItems": 4,
                      "maxItems": 4,
                      "description": "[minLon, minLat, maxLon, maxLat] in WGS84"
                    },
                    "area": {
                      "description": "Beschreibung der Abdeckung in Worten, z. B. Österreich, Steiermark",
                      "type": "string",
                      "maxLength": 60
                    },
                    "minZoom": {
                      "description": "Unterhalb dieser Zoomstufe lädt das Portal keine Daten",
                      "type": "number",
                      "minimum": 0,
                      "maximum": 24
                    },
                    "maxZoom": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 24
                    }
                  }
                },
                "temporal": {
                  "type": "object",
                  "properties": {
                    "updated": {
                      "description": "Datum der letzten Aktualisierung der Daten (ISO 8601)",
                      "type": "string",
                      "maxLength": 40
                    },
                    "frequency": {
                      "description": "Wie oft sich die Daten ändern, z. B. täglich",
                      "type": "string",
                      "maxLength": 60
                    },
                    "param": {
                      "description": "Schlüssel des Parameters, mit dem Nutzer den Zeitraum wählen (Typ range in Jahren oder date-range). Das Portal zeigt ihn als Zeitfilter bei der Legende, mit einem Diagramm aus dm.timeline.",
                      "type": "string",
                      "maxLength": 32
                    }
                  }
                },
                "license": {
                  "description": "Überschreibt die Lizenz des Anbieters",
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "minLength": 1,
                      "description": "Name der Lizenz, z. B. CC BY 4.0"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "attribution": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 300,
                      "description": "Text der Namensnennung, den das Portal bei der Karte anzeigt, z. B. © GeoSphere Austria"
                    }
                  },
                  "required": [
                    "name",
                    "attribution"
                  ]
                },
                "source": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "geojson"
                        },
                        "url": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 2048,
                          "description": "Endpoint, der eine FeatureCollection liefert; kann relativ zum Manifest sein",
                          "examples": [
                            "https://data.example.cz/datovamapa/kontejnery",
                            "kontejnery.geojson"
                          ]
                        },
                        "mode": {
                          "default": "full",
                          "description": "full = gesamter Datensatz mit einer Abfrage, bbox = das Portal fragt den aktuellen Kartenausschnitt ab",
                          "type": "string",
                          "enum": [
                            "full",
                            "bbox"
                          ]
                        },
                        "maxFeatures": {
                          "description": "Wie viele Objekte der Anbieter höchstens liefert; das Portal sendet den Wert als limit",
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 5000
                        }
                      },
                      "required": [
                        "type",
                        "url"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "raster"
                        },
                        "tiles": {
                          "minItems": 1,
                          "maxItems": 4,
                          "type": "array",
                          "items": {
                            "type": "string",
                            "pattern": "^https:\\/\\/\\S+$"
                          },
                          "description": "URL-Vorlagen mit {z}/{x}/{y} oder {bbox-epsg-3857}"
                        },
                        "tileSize": {
                          "default": 256,
                          "anyOf": [
                            {
                              "type": "number",
                              "const": 256
                            },
                            {
                              "type": "number",
                              "const": 512
                            }
                          ]
                        },
                        "minZoom": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 24
                        },
                        "maxZoom": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 24
                        }
                      },
                      "required": [
                        "type",
                        "tiles"
                      ]
                    }
                  ]
                },
                "presentation": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "circle"
                        },
                        "color": {
                          "anyOf": [
                            {
                              "type": "string",
                              "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                            },
                            {
                              "type": "object",
                              "properties": {
                                "field": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 64
                                },
                                "type": {
                                  "type": "string",
                                  "const": "categorical"
                                },
                                "values": {
                                  "type": "object",
                                  "propertyNames": {
                                    "type": "string"
                                  },
                                  "additionalProperties": {
                                    "type": "string",
                                    "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                  },
                                  "description": "Wert der Eigenschaft → Farbe"
                                },
                                "default": {
                                  "type": "string",
                                  "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                }
                              },
                              "required": [
                                "field",
                                "type",
                                "values"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "field": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 64
                                },
                                "type": {
                                  "type": "string",
                                  "const": "interpolate"
                                },
                                "stops": {
                                  "minItems": 2,
                                  "type": "array",
                                  "items": {
                                    "type": "array",
                                    "prefixItems": [
                                      {
                                        "type": "number"
                                      },
                                      {
                                        "type": "string",
                                        "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                      }
                                    ],
                                    "items": false,
                                    "minItems": 2,
                                    "maxItems": 2
                                  },
                                  "description": "Sortierte Paare [Wert, Farbe]"
                                }
                              },
                              "required": [
                                "field",
                                "type",
                                "stops"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "field": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 64
                                },
                                "type": {
                                  "type": "string",
                                  "const": "step"
                                },
                                "default": {
                                  "type": "string",
                                  "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
                                  "description": "Farbe für Werte unter der ersten Schwelle"
                                },
                                "stops": {
                                  "minItems": 1,
                                  "type": "array",
                                  "items": {
                                    "type": "array",
                                    "prefixItems": [
                                      {
                                        "type": "number"
                                      },
                                      {
                                        "type": "string",
                                        "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                      }
                                    ],
                                    "items": false,
                                    "minItems": 2,
                                    "maxItems": 2
                                  },
                                  "description": "Sortierte Paare [ab Wert, Farbe]"
                                }
                              },
                              "required": [
                                "field",
                                "type",
                                "default",
                                "stops"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "type": "string",
                                  "const": "trend"
                                },
                                "threshold": {
                                  "description": "Durchschnittliche Veränderung pro Diagrammzeitraum in % des Anfangswerts, unterhalb der der Wert als stagnierend gilt (Standard 0,5)",
                                  "type": "number",
                                  "minimum": 0,
                                  "maximum": 100
                                },
                                "colors": {
                                  "description": "Überschreibt die Standardfarben (steigt grün, stagniert grau, sinkt rot) – z. B. wenn Wachstum unerwünscht ist",
                                  "type": "object",
                                  "properties": {
                                    "up": {
                                      "type": "string",
                                      "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                    },
                                    "flat": {
                                      "type": "string",
                                      "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                    },
                                    "down": {
                                      "type": "string",
                                      "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                    }
                                  }
                                }
                              },
                              "required": [
                                "type"
                              ]
                            }
                          ]
                        },
                        "radius": {
                          "description": "Radius in Pixeln",
                          "anyOf": [
                            {
                              "type": "number",
                              "minimum": 0
                            },
                            {
                              "type": "object",
                              "properties": {
                                "field": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 64
                                },
                                "type": {
                                  "type": "string",
                                  "const": "interpolate"
                                },
                                "stops": {
                                  "minItems": 2,
                                  "type": "array",
                                  "items": {
                                    "type": "array",
                                    "prefixItems": [
                                      {
                                        "type": "number"
                                      },
                                      {
                                        "type": "number",
                                        "minimum": 0
                                      }
                                    ],
                                    "items": false,
                                    "minItems": 2,
                                    "maxItems": 2
                                  }
                                }
                              },
                              "required": [
                                "field",
                                "type",
                                "stops"
                              ]
                            }
                          ]
                        },
                        "opacity": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 1
                        },
                        "strokeColor": {
                          "type": "string",
                          "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                        },
                        "strokeWidth": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 10
                        },
                        "label": {
                          "type": "object",
                          "properties": {
                            "field": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 64,
                              "description": "Eigenschaft, deren Wert als Beschriftung angezeigt wird"
                            },
                            "minZoom": {
                              "type": "number",
                              "minimum": 0,
                              "maximum": 24
                            },
                            "color": {
                              "type": "string",
                              "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                            },
                            "size": {
                              "type": "number",
                              "minimum": 6,
                              "maximum": 32
                            }
                          },
                          "required": [
                            "field"
                          ]
                        },
                        "cluster": {
                          "description": "Gruppierung nahe beieinanderliegender Punkte",
                          "anyOf": [
                            {
                              "type": "boolean"
                            },
                            {
                              "type": "object",
                              "properties": {
                                "radius": {
                                  "type": "number",
                                  "minimum": 10,
                                  "maximum": 200
                                },
                                "maxZoom": {
                                  "type": "number",
                                  "minimum": 0,
                                  "maximum": 20
                                }
                              }
                            }
                          ]
                        },
                        "legend": {
                          "description": "Eigene Legende; sonst leitet das Portal sie aus den Farben ab",
                          "maxItems": 20,
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "label": {
                                "type": "string",
                                "maxLength": 80
                              },
                              "color": {
                                "type": "string",
                                "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                              }
                            },
                            "required": [
                              "label",
                              "color"
                            ]
                          }
                        }
                      },
                      "required": [
                        "type"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "heatmap"
                        },
                        "weight": {
                          "description": "Gewicht des Punkts, typischerweise aus einer numerischen Eigenschaft",
                          "anyOf": [
                            {
                              "type": "number",
                              "minimum": 0
                            },
                            {
                              "type": "object",
                              "properties": {
                                "field": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 64
                                },
                                "type": {
                                  "type": "string",
                                  "const": "interpolate"
                                },
                                "stops": {
                                  "minItems": 2,
                                  "type": "array",
                                  "items": {
                                    "type": "array",
                                    "prefixItems": [
                                      {
                                        "type": "number"
                                      },
                                      {
                                        "type": "number",
                                        "minimum": 0
                                      }
                                    ],
                                    "items": false,
                                    "minItems": 2,
                                    "maxItems": 2
                                  }
                                }
                              },
                              "required": [
                                "field",
                                "type",
                                "stops"
                              ]
                            }
                          ]
                        },
                        "radius": {
                          "type": "number",
                          "minimum": 1,
                          "maximum": 100
                        },
                        "intensity": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 10
                        },
                        "colors": {
                          "description": "Farbskala von geringer bis hoher Dichte",
                          "minItems": 2,
                          "maxItems": 10,
                          "type": "array",
                          "items": {
                            "type": "string",
                            "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                          }
                        },
                        "opacity": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 1
                        },
                        "legend": {
                          "description": "Eigene Legende; sonst leitet das Portal sie aus den Farben ab",
                          "maxItems": 20,
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "label": {
                                "type": "string",
                                "maxLength": 80
                              },
                              "color": {
                                "type": "string",
                                "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                              }
                            },
                            "required": [
                              "label",
                              "color"
                            ]
                          }
                        }
                      },
                      "required": [
                        "type"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "line"
                        },
                        "color": {
                          "anyOf": [
                            {
                              "type": "string",
                              "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                            },
                            {
                              "type": "object",
                              "properties": {
                                "field": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 64
                                },
                                "type": {
                                  "type": "string",
                                  "const": "categorical"
                                },
                                "values": {
                                  "type": "object",
                                  "propertyNames": {
                                    "type": "string"
                                  },
                                  "additionalProperties": {
                                    "type": "string",
                                    "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                  },
                                  "description": "Wert der Eigenschaft → Farbe"
                                },
                                "default": {
                                  "type": "string",
                                  "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                }
                              },
                              "required": [
                                "field",
                                "type",
                                "values"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "field": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 64
                                },
                                "type": {
                                  "type": "string",
                                  "const": "interpolate"
                                },
                                "stops": {
                                  "minItems": 2,
                                  "type": "array",
                                  "items": {
                                    "type": "array",
                                    "prefixItems": [
                                      {
                                        "type": "number"
                                      },
                                      {
                                        "type": "string",
                                        "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                      }
                                    ],
                                    "items": false,
                                    "minItems": 2,
                                    "maxItems": 2
                                  },
                                  "description": "Sortierte Paare [Wert, Farbe]"
                                }
                              },
                              "required": [
                                "field",
                                "type",
                                "stops"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "field": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 64
                                },
                                "type": {
                                  "type": "string",
                                  "const": "step"
                                },
                                "default": {
                                  "type": "string",
                                  "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
                                  "description": "Farbe für Werte unter der ersten Schwelle"
                                },
                                "stops": {
                                  "minItems": 1,
                                  "type": "array",
                                  "items": {
                                    "type": "array",
                                    "prefixItems": [
                                      {
                                        "type": "number"
                                      },
                                      {
                                        "type": "string",
                                        "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                      }
                                    ],
                                    "items": false,
                                    "minItems": 2,
                                    "maxItems": 2
                                  },
                                  "description": "Sortierte Paare [ab Wert, Farbe]"
                                }
                              },
                              "required": [
                                "field",
                                "type",
                                "default",
                                "stops"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "type": "string",
                                  "const": "trend"
                                },
                                "threshold": {
                                  "description": "Durchschnittliche Veränderung pro Diagrammzeitraum in % des Anfangswerts, unterhalb der der Wert als stagnierend gilt (Standard 0,5)",
                                  "type": "number",
                                  "minimum": 0,
                                  "maximum": 100
                                },
                                "colors": {
                                  "description": "Überschreibt die Standardfarben (steigt grün, stagniert grau, sinkt rot) – z. B. wenn Wachstum unerwünscht ist",
                                  "type": "object",
                                  "properties": {
                                    "up": {
                                      "type": "string",
                                      "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                    },
                                    "flat": {
                                      "type": "string",
                                      "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                    },
                                    "down": {
                                      "type": "string",
                                      "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                    }
                                  }
                                }
                              },
                              "required": [
                                "type"
                              ]
                            }
                          ]
                        },
                        "width": {
                          "anyOf": [
                            {
                              "type": "number",
                              "minimum": 0
                            },
                            {
                              "type": "object",
                              "properties": {
                                "field": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 64
                                },
                                "type": {
                                  "type": "string",
                                  "const": "interpolate"
                                },
                                "stops": {
                                  "minItems": 2,
                                  "type": "array",
                                  "items": {
                                    "type": "array",
                                    "prefixItems": [
                                      {
                                        "type": "number"
                                      },
                                      {
                                        "type": "number",
                                        "minimum": 0
                                      }
                                    ],
                                    "items": false,
                                    "minItems": 2,
                                    "maxItems": 2
                                  }
                                }
                              },
                              "required": [
                                "field",
                                "type",
                                "stops"
                              ]
                            }
                          ]
                        },
                        "opacity": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 1
                        },
                        "dash": {
                          "minItems": 2,
                          "maxItems": 8,
                          "type": "array",
                          "items": {
                            "type": "number",
                            "minimum": 0
                          }
                        },
                        "label": {
                          "type": "object",
                          "properties": {
                            "field": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 64,
                              "description": "Eigenschaft, deren Wert als Beschriftung angezeigt wird"
                            },
                            "minZoom": {
                              "type": "number",
                              "minimum": 0,
                              "maximum": 24
                            },
                            "color": {
                              "type": "string",
                              "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                            },
                            "size": {
                              "type": "number",
                              "minimum": 6,
                              "maximum": 32
                            }
                          },
                          "required": [
                            "field"
                          ]
                        },
                        "legend": {
                          "description": "Eigene Legende; sonst leitet das Portal sie aus den Farben ab",
                          "maxItems": 20,
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "label": {
                                "type": "string",
                                "maxLength": 80
                              },
                              "color": {
                                "type": "string",
                                "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                              }
                            },
                            "required": [
                              "label",
                              "color"
                            ]
                          }
                        }
                      },
                      "required": [
                        "type"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "fill"
                        },
                        "color": {
                          "anyOf": [
                            {
                              "type": "string",
                              "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                            },
                            {
                              "type": "object",
                              "properties": {
                                "field": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 64
                                },
                                "type": {
                                  "type": "string",
                                  "const": "categorical"
                                },
                                "values": {
                                  "type": "object",
                                  "propertyNames": {
                                    "type": "string"
                                  },
                                  "additionalProperties": {
                                    "type": "string",
                                    "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                  },
                                  "description": "Wert der Eigenschaft → Farbe"
                                },
                                "default": {
                                  "type": "string",
                                  "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                }
                              },
                              "required": [
                                "field",
                                "type",
                                "values"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "field": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 64
                                },
                                "type": {
                                  "type": "string",
                                  "const": "interpolate"
                                },
                                "stops": {
                                  "minItems": 2,
                                  "type": "array",
                                  "items": {
                                    "type": "array",
                                    "prefixItems": [
                                      {
                                        "type": "number"
                                      },
                                      {
                                        "type": "string",
                                        "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                      }
                                    ],
                                    "items": false,
                                    "minItems": 2,
                                    "maxItems": 2
                                  },
                                  "description": "Sortierte Paare [Wert, Farbe]"
                                }
                              },
                              "required": [
                                "field",
                                "type",
                                "stops"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "field": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 64
                                },
                                "type": {
                                  "type": "string",
                                  "const": "step"
                                },
                                "default": {
                                  "type": "string",
                                  "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
                                  "description": "Farbe für Werte unter der ersten Schwelle"
                                },
                                "stops": {
                                  "minItems": 1,
                                  "type": "array",
                                  "items": {
                                    "type": "array",
                                    "prefixItems": [
                                      {
                                        "type": "number"
                                      },
                                      {
                                        "type": "string",
                                        "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                      }
                                    ],
                                    "items": false,
                                    "minItems": 2,
                                    "maxItems": 2
                                  },
                                  "description": "Sortierte Paare [ab Wert, Farbe]"
                                }
                              },
                              "required": [
                                "field",
                                "type",
                                "default",
                                "stops"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "type": "string",
                                  "const": "trend"
                                },
                                "threshold": {
                                  "description": "Durchschnittliche Veränderung pro Diagrammzeitraum in % des Anfangswerts, unterhalb der der Wert als stagnierend gilt (Standard 0,5)",
                                  "type": "number",
                                  "minimum": 0,
                                  "maximum": 100
                                },
                                "colors": {
                                  "description": "Überschreibt die Standardfarben (steigt grün, stagniert grau, sinkt rot) – z. B. wenn Wachstum unerwünscht ist",
                                  "type": "object",
                                  "properties": {
                                    "up": {
                                      "type": "string",
                                      "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                    },
                                    "flat": {
                                      "type": "string",
                                      "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                    },
                                    "down": {
                                      "type": "string",
                                      "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                                    }
                                  }
                                }
                              },
                              "required": [
                                "type"
                              ]
                            }
                          ]
                        },
                        "opacity": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 1
                        },
                        "outlineColor": {
                          "type": "string",
                          "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                        },
                        "outlineWidth": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 10
                        },
                        "label": {
                          "type": "object",
                          "properties": {
                            "field": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 64,
                              "description": "Eigenschaft, deren Wert als Beschriftung angezeigt wird"
                            },
                            "minZoom": {
                              "type": "number",
                              "minimum": 0,
                              "maximum": 24
                            },
                            "color": {
                              "type": "string",
                              "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                            },
                            "size": {
                              "type": "number",
                              "minimum": 6,
                              "maximum": 32
                            }
                          },
                          "required": [
                            "field"
                          ]
                        },
                        "legend": {
                          "description": "Eigene Legende; sonst leitet das Portal sie aus den Farben ab",
                          "maxItems": 20,
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "label": {
                                "type": "string",
                                "maxLength": 80
                              },
                              "color": {
                                "type": "string",
                                "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                              }
                            },
                            "required": [
                              "label",
                              "color"
                            ]
                          }
                        }
                      },
                      "required": [
                        "type"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "raster"
                        },
                        "opacity": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 1
                        },
                        "legend": {
                          "description": "Eigene Legende; sonst leitet das Portal sie aus den Farben ab",
                          "maxItems": 20,
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "label": {
                                "type": "string",
                                "maxLength": 80
                              },
                              "color": {
                                "type": "string",
                                "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                              }
                            },
                            "required": [
                              "label",
                              "color"
                            ]
                          }
                        }
                      },
                      "required": [
                        "type"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "auto"
                        },
                        "color": {
                          "type": "string",
                          "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                        },
                        "legend": {
                          "description": "Eigene Legende; sonst leitet das Portal sie aus den Farben ab",
                          "maxItems": 20,
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "label": {
                                "type": "string",
                                "maxLength": 80
                              },
                              "color": {
                                "type": "string",
                                "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                              }
                            },
                            "required": [
                              "label",
                              "color"
                            ]
                          }
                        }
                      },
                      "required": [
                        "type"
                      ]
                    }
                  ]
                },
                "fields": {
                  "maxItems": 100,
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "key": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 64
                      },
                      "label": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 80
                      },
                      "type": {
                        "default": "string",
                        "type": "string",
                        "enum": [
                          "string",
                          "number",
                          "integer",
                          "boolean",
                          "date",
                          "datetime",
                          "url",
                          "image",
                          "email",
                          "phone"
                        ]
                      },
                      "unit": {
                        "type": "string",
                        "maxLength": 20
                      },
                      "decimals": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 8
                      },
                      "description": {
                        "type": "string",
                        "maxLength": 300
                      },
                      "primary": {
                        "description": "Der Wert dient als Titel des Objekts in der Detailansicht",
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "key",
                      "label"
                    ]
                  }
                },
                "params": {
                  "maxItems": 20,
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "key": {
                        "type": "string",
                        "pattern": "^[a-zA-Z][a-zA-Z0-9_]{0,31}$"
                      },
                      "label": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 80
                      },
                      "type": {
                        "type": "string",
                        "enum": [
                          "enum",
                          "multi-enum",
                          "number",
                          "range",
                          "boolean",
                          "date",
                          "date-range",
                          "text"
                        ]
                      },
                      "description": {
                        "type": "string",
                        "maxLength": 300
                      },
                      "options": {
                        "description": "Für enum und multi-enum",
                        "maxItems": 200,
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 100
                            },
                            "label": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 100
                            }
                          },
                          "required": [
                            "value",
                            "label"
                          ]
                        }
                      },
                      "min": {
                        "type": "number"
                      },
                      "max": {
                        "type": "number"
                      },
                      "step": {
                        "type": "number",
                        "exclusiveMinimum": 0
                      },
                      "unit": {
                        "type": "string",
                        "maxLength": 20
                      },
                      "default": {
                        "type": [
                          "string",
                          "number",
                          "boolean"
                        ]
                      },
                      "required": {
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "key",
                      "label",
                      "type"
                    ]
                  }
                },
                "cache": {
                  "type": "object",
                  "properties": {
                    "ttl": {
                      "description": "Wie lange (s) das Portal die Antwort im Cache halten darf",
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 31536000
                    },
                    "store": {
                      "description": "Ob das Portal die Daten für Analysen und Kombinationen in seiner Cache-Schicht speichern darf (Standard: ja)",
                      "type": "boolean"
                    }
                  }
                }
              },
              "required": [
                "id",
                "title",
                "source",
                "presentation"
              ]
            }
          }
        },
        "required": [
          "protocol",
          "provider",
          "datasets"
        ]
      },
      "DataResponse": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "FeatureCollection"
          },
          "features": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "Feature"
                },
                "id": {
                  "anyOf": [
                    {
                      "type": "string",
                      "maxLength": 200
                    },
                    {
                      "type": "number"
                    }
                  ]
                },
                "geometry": {
                  "anyOf": [
                    {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "Point"
                            },
                            "coordinates": {
                              "minItems": 2,
                              "maxItems": 3,
                              "type": "array",
                              "items": {
                                "type": "number"
                              }
                            }
                          },
                          "required": [
                            "type",
                            "coordinates"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "MultiPoint"
                            },
                            "coordinates": {
                              "type": "array",
                              "items": {
                                "minItems": 2,
                                "maxItems": 3,
                                "type": "array",
                                "items": {
                                  "type": "number"
                                }
                              }
                            }
                          },
                          "required": [
                            "type",
                            "coordinates"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "LineString"
                            },
                            "coordinates": {
                              "minItems": 2,
                              "type": "array",
                              "items": {
                                "minItems": 2,
                                "maxItems": 3,
                                "type": "array",
                                "items": {
                                  "type": "number"
                                }
                              }
                            }
                          },
                          "required": [
                            "type",
                            "coordinates"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "MultiLineString"
                            },
                            "coordinates": {
                              "type": "array",
                              "items": {
                                "minItems": 2,
                                "type": "array",
                                "items": {
                                  "minItems": 2,
                                  "maxItems": 3,
                                  "type": "array",
                                  "items": {
                                    "type": "number"
                                  }
                                }
                              }
                            }
                          },
                          "required": [
                            "type",
                            "coordinates"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "Polygon"
                            },
                            "coordinates": {
                              "type": "array",
                              "items": {
                                "minItems": 4,
                                "type": "array",
                                "items": {
                                  "minItems": 2,
                                  "maxItems": 3,
                                  "type": "array",
                                  "items": {
                                    "type": "number"
                                  }
                                }
                              }
                            }
                          },
                          "required": [
                            "type",
                            "coordinates"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "MultiPolygon"
                            },
                            "coordinates": {
                              "type": "array",
                              "items": {
                                "type": "array",
                                "items": {
                                  "minItems": 4,
                                  "type": "array",
                                  "items": {
                                    "minItems": 2,
                                    "maxItems": 3,
                                    "type": "array",
                                    "items": {
                                      "type": "number"
                                    }
                                  }
                                }
                              }
                            }
                          },
                          "required": [
                            "type",
                            "coordinates"
                          ]
                        }
                      ]
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "properties": {
                  "default": {},
                  "anyOf": [
                    {
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {}
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "dm": {
                  "type": "object",
                  "properties": {
                    "title": {
                      "description": "Titel des Objekts in der Detailansicht",
                      "type": "string",
                      "maxLength": 200
                    },
                    "description": {
                      "type": "string",
                      "maxLength": 2000
                    },
                    "url": {
                      "description": "Link zur Detailseite des Objekts beim Anbieter",
                      "type": "string",
                      "format": "uri"
                    },
                    "color": {
                      "description": "Überschreibt die Farbe aus der Darstellung",
                      "type": "string",
                      "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
                    },
                    "chart": {
                      "description": "Diagramm der Wertentwicklung in der Detailansicht des Objekts",
                      "type": "object",
                      "properties": {
                        "label": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 80,
                          "description": "Was das Diagramm zeigt, z. B. Einwohnerzahl"
                        },
                        "unit": {
                          "type": "string",
                          "maxLength": 20
                        },
                        "decimals": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 6
                        },
                        "note": {
                          "description": "Anmerkung unter dem Diagramm, z. B. zu einer Methodenänderung",
                          "type": "string",
                          "maxLength": 200
                        },
                        "highlight": {
                          "description": "Hervorgehobener Zeitraum (z. B. im Zeitfilter gewählt) – das Portal hinterlegt ihn farbig, zeigt den Wert an seinem Ende und berechnet Veränderung und Trend ab seinem Beginn. Gleiche from und to = ein gewählter Zeitraum (z. B. ein Jahr).",
                          "type": "object",
                          "properties": {
                            "from": {
                              "type": "string",
                              "pattern": "^\\d{4}(?:-\\d{2}(?:-\\d{2})?)?$",
                              "description": "Jahr, Monat oder Tag in ISO 8601"
                            },
                            "to": {
                              "type": "string",
                              "pattern": "^\\d{4}(?:-\\d{2}(?:-\\d{2})?)?$",
                              "description": "Jahr, Monat oder Tag in ISO 8601"
                            }
                          },
                          "required": [
                            "from",
                            "to"
                          ]
                        },
                        "points": {
                          "minItems": 2,
                          "maxItems": 100,
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "period": {
                                "type": "string",
                                "pattern": "^\\d{4}(?:-\\d{2}(?:-\\d{2})?)?$",
                                "description": "Jahr, Monat oder Tag in ISO 8601"
                              },
                              "value": {
                                "type": "number"
                              }
                            },
                            "required": [
                              "period",
                              "value"
                            ]
                          },
                          "description": "Werte, sortiert ab dem ältesten Zeitraum"
                        }
                      },
                      "required": [
                        "label",
                        "points"
                      ]
                    }
                  }
                }
              },
              "required": [
                "type",
                "geometry"
              ]
            }
          },
          "dm": {
            "type": "object",
            "properties": {
              "protocol": {
                "type": "string"
              },
              "generated": {
                "description": "Zeitpunkt, zu dem die Antwort erstellt wurde (ISO 8601)",
                "type": "string",
                "maxLength": 40
              },
              "ttl": {
                "description": "Wie lange (s) die Antwort gültig ist",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "total": {
                "description": "Gesamtzahl der Objekte, die der Abfrage entsprechen",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "truncated": {
                "description": "Die Antwort enthält nicht alle Objekte (Limit)",
                "type": "boolean"
              },
              "next": {
                "description": "Cursor für die nächste Seite",
                "type": "string",
                "maxLength": 500
              },
              "notice": {
                "description": "Kurze Mitteilung für Nutzer, z. B. Karte vergrößern",
                "type": "string",
                "maxLength": 300
              },
              "timeline": {
                "description": "Anzahl der Objekte im Kartenausschnitt nach Zeiträumen über die gesamte Dauer, die der Datensatz abdeckt – unabhängig vom gewählten Zeitraum und Limit. Das Portal zeichnet daraus ein Diagramm bei der Legende.",
                "maxItems": 400,
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "period": {
                      "type": "string",
                      "pattern": "^\\d{4}(?:-\\d{2}(?:-\\d{2})?)?$",
                      "description": "Jahr, Monat oder Tag in ISO 8601"
                    },
                    "count": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991
                    },
                    "values": {
                      "description": "Aufschlüsselung der Anzahl nach den Werten der Eigenschaft, nach der die Objekte eingefärbt werden (color.field) – das Diagramm färbt sie wie die Legende",
                      "type": "object",
                      "propertyNames": {
                        "type": "string",
                        "maxLength": 100
                      },
                      "additionalProperties": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 9007199254740991
                      }
                    }
                  },
                  "required": [
                    "period",
                    "count"
                  ]
                }
              },
              "chart": {
                "description": "Zusammengefasste Entwicklung des Werts für das gesamte Gebiet des Datensatzes oder den Kartenausschnitt (z. B. Einwohnerzahl Österreichs) – das Portal zeigt sie beim Zeitfilter an, wenn die Antwort kein dm.timeline mitsendet",
                "type": "object",
                "properties": {
                  "label": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80,
                    "description": "Was das Diagramm zeigt, z. B. Einwohnerzahl"
                  },
                  "unit": {
                    "type": "string",
                    "maxLength": 20
                  },
                  "decimals": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 6
                  },
                  "note": {
                    "description": "Anmerkung unter dem Diagramm, z. B. zu einer Methodenänderung",
                    "type": "string",
                    "maxLength": 200
                  },
                  "highlight": {
                    "description": "Hervorgehobener Zeitraum (z. B. im Zeitfilter gewählt) – das Portal hinterlegt ihn farbig, zeigt den Wert an seinem Ende und berechnet Veränderung und Trend ab seinem Beginn. Gleiche from und to = ein gewählter Zeitraum (z. B. ein Jahr).",
                    "type": "object",
                    "properties": {
                      "from": {
                        "type": "string",
                        "pattern": "^\\d{4}(?:-\\d{2}(?:-\\d{2})?)?$",
                        "description": "Jahr, Monat oder Tag in ISO 8601"
                      },
                      "to": {
                        "type": "string",
                        "pattern": "^\\d{4}(?:-\\d{2}(?:-\\d{2})?)?$",
                        "description": "Jahr, Monat oder Tag in ISO 8601"
                      }
                    },
                    "required": [
                      "from",
                      "to"
                    ]
                  },
                  "points": {
                    "minItems": 2,
                    "maxItems": 100,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "period": {
                          "type": "string",
                          "pattern": "^\\d{4}(?:-\\d{2}(?:-\\d{2})?)?$",
                          "description": "Jahr, Monat oder Tag in ISO 8601"
                        },
                        "value": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "period",
                        "value"
                      ]
                    },
                    "description": "Werte, sortiert ab dem ältesten Zeitraum"
                  }
                },
                "required": [
                  "label",
                  "points"
                ]
              }
            }
          }
        },
        "required": [
          "type",
          "features"
        ]
      },
      "Issue": {
        "type": "object",
        "required": [
          "path",
          "code",
          "message"
        ],
        "properties": {
          "path": {
            "type": "string",
            "description": "Stelle im Dokument, z. B. datasets[0].keywords"
          },
          "code": {
            "type": "string",
            "description": "Stabiler Code des Befunds, siehe /dokumentation/api.md#kody-nalezu"
          },
          "message": {
            "type": "string"
          },
          "hint": {
            "type": "string",
            "description": "Hinweis, wie der Befund zu beheben ist"
          }
        }
      },
      "Report": {
        "type": "object",
        "required": [
          "valid",
          "errors",
          "warnings",
          "summary"
        ],
        "properties": {
          "valid": {
            "type": "boolean"
          },
          "summary": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Issue"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Issue"
            }
          },
          "kind": {
            "type": "string",
            "enum": [
              "manifest",
              "data"
            ]
          },
          "featureCount": {
            "type": "integer"
          },
          "manifestUrl": {
            "type": "string"
          },
          "provider": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "datasets": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "sourceType": {
                  "type": "string"
                },
                "request": {
                  "type": "string"
                },
                "durationMs": {
                  "type": "integer"
                },
                "featureCount": {
                  "type": "integer"
                },
                "valid": {
                  "type": "boolean"
                },
                "summary": {
                  "type": "string"
                },
                "errors": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Issue"
                  }
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Issue"
                  }
                }
              }
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error",
          "code"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string"
          }
        }
      },
      "Place": {
        "type": "object",
        "required": [
          "name",
          "type",
          "point"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "description": "Adresse, Straße, Gemeinde, Ortsteil …"
          },
          "point": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[lon, lat]"
          },
          "municipality": {
            "type": "object",
            "description": "Gemeinde, in der der Ort liegt; code (Gemeindekennziffer) ist auch bei gleichnamigen Gemeinden eindeutig",
            "properties": {
              "slug": {
                "type": "string"
              },
              "code": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "district": {
                "type": "string"
              },
              "region": {
                "type": "string"
              }
            }
          },
          "near": {
            "type": "object",
            "description": "Nächste Gemeinde über 10 000 Einwohner (bei Orten außerhalb dieser Städte)",
            "properties": {
              "name": {
                "type": "string"
              },
              "km": {
                "type": "number"
              }
            }
          }
        }
      },
      "PointAnswer": {
        "type": "object",
        "required": [
          "point",
          "radius",
          "generated",
          "results",
          "map"
        ],
        "properties": {
          "place": {
            "$ref": "#/components/schemas/Place"
          },
          "point": {
            "type": "array",
            "items": {
              "type": "number"
            }
          },
          "radius": {
            "type": "number"
          },
          "generated": {
            "type": "string",
            "format": "date-time"
          },
          "skipped": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Datensätze über dem Limit, nach denen nicht gefragt wurde"
          },
          "map": {
            "type": "string",
            "format": "uri"
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "dataset",
                "title",
                "status",
                "hits"
              ],
              "properties": {
                "dataset": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                },
                "legend": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "provider": {
                  "type": "string"
                },
                "attribution": {
                  "type": "string"
                },
                "license": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "ok",
                    "unavailable",
                    "error"
                  ]
                },
                "count": {
                  "type": "integer"
                },
                "radius": {
                  "type": "number"
                },
                "truncated": {
                  "type": "boolean"
                },
                "notice": {
                  "type": "string"
                },
                "error": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                },
                "hits": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "title",
                      "distance",
                      "values"
                    ],
                    "properties": {
                      "title": {
                        "type": "string"
                      },
                      "distance": {
                        "type": "number"
                      },
                      "values": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "required": [
                            "label",
                            "value"
                          ],
                          "properties": {
                            "label": {
                              "type": "string"
                            },
                            "value": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "description": {
                        "type": "string"
                      },
                      "url": {
                        "type": "string"
                      },
                      "chart": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}