---
title: "Nachhaltigkeits- und SDG-Indikatoren als Zeitreihe (Wegweiser, Tier A)"
method: GET
path: "/api/v1/cities/{slug}/sustainability"
tags: ["cities"]
---

# Nachhaltigkeits- und SDG-Indikatoren als Zeitreihe (Wegweiser, Tier A)

`GET /api/v1/cities/{slug}/sustainability`

Kommunale Nachhaltigkeits- und SDG-Indikatoren je Gemeinde aus dem Wegweiser Kommune der Bertelsmann Stiftung (CC0): Flächeninanspruchnahme, Naherholungsflächen, erneuerbare Energie im Wohnungsneubau, Breitbandversorgung, Beschäftigung, Bildung, soziale Teilhabe und weitere. Anders als /indicators (INKAR, jüngster Wert) trägt jeder Indikator hier die ganze ZEITREIHE, in der Regel 2006 bis 2023, dazu latest_year/latest_value für den jüngsten Punkt. Jahre ohne Wert fehlen in der Reihe (nie eine erfundene Null). 53 Indikatoren liegen erst ab Kreisebene vor und fehlen deshalb bei kreisangehörigen Städten. Toggle aus -> 200 source_status="disabled"; kein Snapshot -> 200 source_status="not_ingested".

## Path parameters

- `slug` string, required

## Response `200`

Zeitreihen-Envelope (CanonicalRecord mit IndicatorSeriesPayload) oder null.

- object
  - `data` CanonicalRecord, required
    - `city_slug` string, required
    - `schema_version` integer, required
    - `record_id` string, required — Deterministischer Primärschlüssel (computed, immer im Dump).
    - `content_hash` string, required — Deterministischer Dedup-Hash der Nutzdaten (computed, immer im Dump).
    - `ags` string, nullable — Amtlicher Gemeindeschlüssel als Join-Key (kein Pfadsegment).
    - `wikidata_qid` string, nullable — Wikidata-QID als Join-Key.
    - `geo` object, nullable
      - `lat` number
      - `lon` number
    - `observed_at` string, date-time, nullable
    - `retrieved_at` string, date-time, required
    - `source` 'wikidata' | 'dwd' | 'osm' | 'autobahn' | 'bnetza' | 'uba' | 'delfi' | 'hvv' | 'pegelonline' | 'lhp' | 'dwd_pollen' | 'dwd_fire' | 'eea_bathing' | 'klinik_atlas' | 'db_fasta' | 'genesis' | 'zensus' | 'mastr' | 'smard' | 'dwd_warnings' | 'bkg' | 'bundeswahl' | 'divi' | 'holidays' | 'berlin_viz' | 'hamburg_roadworks' | 'koeln_road_events' | 'muenchen_roadworks' | 'dortmund_roadworks' | 'rostock_roadworks' | 'sperrinfosys' | 'mobidata_bw' | 'destination_one' | 'koeln_events' | 'koeln_traffic_flow' | 'koeln_roadworks_live' | 'koeln_incidents_live' | 'koeln_lez_live' | 'berlin_traffic_reports' | 'dortmund_parking' | 'kiel_counting_stations' | 'eround_charging' | 'frankfurt_parking' | 'wuppertal_parking' | 'magdeburg_parking' | 'koeln_parking' | 'gtfs_rt' | 'hvv_geofox' | 'vgn' | 'rmv' | 'vrr' | 'vvs' | 'hamburg_traffic_situation' | 'kba' | 'unfallatlas' | 'tankerkoenig' | 'bremen_roadworks' | 'hannover_traffic_reports' | 'gbfs' | 'inkar' | 'wegweiser' | 'bka_pks' | 'db_timetables' | 'boris' | 'stada' | 'regionalstatistik' | 'solar' | 'solar_cadastre' | 'muenchen_parking' | 'muenchen_bike_counts' | 'muenchen_parking_onstreet' | 'muenchen_park_and_ride' | 'muenchen_mobility_points' | 'muenchen_bike_parking' | 'leipzig_bike_counts' | 'hamburg_bike_counts' | 'berlin_bike_counts' | 'stuttgart_bike_counts' | 'koeln_bike_counts' | 'essen_bike_counts' | 'duesseldorf_bike_counts' | 'parkendd' | 'heritage' | 'tree_cadastre' | 'zensus_grid' | 'oeffentlichevergabe' | 'district_heating' | 'koeln_wait_times' | 'bbk_nina' | 'council' | 'mobidata_parkapi' | 'pr_hessen_parking' | 'db_bahnpark' | 'muenster_parking' | 'aachen_parking' | 'oldenburg_parking' | 'kaiserslautern_parking' | 'dresden_parking' | 'karlsruhe_parking' | 'hamburg_parking', required — Kanonischer Quellname (SourceId). Seit 2026-08-01 tragen alle Quellen einheitlich englische Namen; historische Antworten und Bestandsdaten konnten davor alte deutsche Quellnamen tragen (z.B. hamburg_baustellen statt hamburg_roadworks). Die vollständige Zuordnungstabelle alt -> neu steht im Changelog (Eintrag 2026-08-01).
    - `license_id` 'cc0' | 'cc_by_4_0' | 'dl_de_by_2_0' | 'dl_de_zero_2_0' | 'geonutzv' | 'odbl' | 'cc_by_sa_4_0' | 'unknown', required
    - `license_tier` 'A' | 'B' | 'C', required
    - `attribution` Attribution, required
      - `text` string, required
      - `license_url` string, nullable
      - `modified` boolean
    - `payload` union, required
      - CityBaseDataPayload
        - `kind` 'city_base', required
        - `population` integer, nullable
        - `area_km2` number, nullable
      - AirQualityPayload
        - `kind` 'air_quality', required
        - `station_id` string, nullable
        - `pm10` number, nullable
        - `no2` number, nullable
        - `pm25` number, nullable
        - `o3` number, nullable
        - `so2` number, nullable
      - WeatherPayload
        - `kind` 'weather', required
        - `station_id` string, nullable
        - `temperature_c` number, nullable
        - `humidity` number, nullable
        - `wind_speed` number, nullable
        - `condition` string, nullable
      - PoiPayload
        - `kind` 'poi', required
        - `poi_type` string, required
        - `count` integer, required
        - `total_available` integer, nullable
        - `truncated` boolean
        - `items` object[]
      - TrafficEventPayload
        - `kind` 'traffic_event', required
        - `station_id` string, nullable
        - `roadworks` object[]
        - `warnings` object[]
      - TransitStopPayload
        - `kind` 'transit_stop', required
        - `stop_id` string, required
        - `stop_name` string, required
        - `location_type` integer, nullable
        - `parent_station` string, nullable
        - `platform_code` string, nullable
        - `wheelchair_boarding` integer, nullable
      - ChargingStationPayload
        - `kind` 'charging_station', required
        - `count` integer, required
        - `stations` object[]
      - WaterLevelPayload
        - `kind` 'water_level', required
        - `station` string, nullable
        - `water` string, nullable
        - `value` number, nullable
        - `unit` string, nullable
      - FloodWarningPayload
        - `kind` 'flood_warning', required
        - `warnings` object[]
        - `stand` string, nullable — Abgekündigt, siehe as_of (identischer Wert). Wird frühestens 30 Tage nach Ankündigung vom 2026-08-01 entfernt.
        - `as_of` string, nullable — Stand-Zeitstempel-Text der LHP-Antwort (kanonischer Name; ersetzt das abgekündigte stand).
      - PollenUvPayload
        - `kind` 'pollen_uv', required
        - `region_id` integer, nullable
        - `region_name` string, nullable
        - `pollen` object
        - `uv_index` number, nullable
      - DemographicsPayload
        - `kind` 'demographics', required
        - `population` integer, nullable
        - `households` integer, nullable
        - `buildings` integer, nullable
        - `rent_avg` number, nullable
        - `reference_year` integer, nullable
        - `series` object[]
      - EnergyAssetPayload
        - `kind` 'energy_asset', required
        - `count` integer, required
        - `by_type` object
        - `assets` object[]
      - AdminBoundaryPayload
        - `kind` 'admin_boundary', required
        - `ags` string, nullable
        - `gen_name` string, nullable
        - `area_km2` number, nullable
        - `reference_year` integer, nullable
      - ElectionResultPayload
        - `kind` 'election_result', required
        - `election` string, nullable
        - `granularity` string — Abgekündigt, siehe coverage_granularity (gleiche Bedeutung, deutsche Werte "stadt"/"teilweise"). Wird frühestens 30 Tage nach Ankündigung vom 2026-08-01 entfernt.
        - `coverage_granularity` string, nullable — Abdeckungs-Granularität (kanonischer Name): "city" = stadtgenau aus den Wahlkreisen der Stadt aggregiert, "partial" = Wahlkreis/Kreis- Ebene, Stadt nur teilweise. Ersetzt das abgekündigte granularity.
        - `area_name` string, nullable
        - `turnout` string, nullable — Wahlbeteiligung in Prozent als String mit Dezimal-Komma (kerg2, Zeile Gruppenname "Wählende", Spalte Prozent), z.B. "82,5122".
        - `results` object[]
      - HolidayPayload
        - `kind` 'holiday', required
        - `state` string, nullable
        - `year` integer, nullable
        - `holidays` object[]
        - `school_holidays` object[]
      - HospitalPayload
        - `kind` 'hospital', required
        - `count` integer, required
        - `hospitals` object[]
        - `reference_date` string, nullable
      - IcuCapacityPayload
        - `kind` 'icu_capacity', required
        - `kreis_id` string, nullable — Abgekündigt, siehe district_id (identischer Wert). Wird frühestens 30 Tage nach Ankündigung vom 2026-08-01 entfernt.
        - `kreis_name` string, nullable — Abgekündigt, siehe district_name (identischer Wert). Wird frühestens 30 Tage nach Ankündigung vom 2026-08-01 entfernt.
        - `district_id` string, nullable — Kreis-Kennung, 5-stelliger AGS-Präfix (kanonischer Name; ersetzt das abgekündigte kreis_id).
        - `district_name` string, nullable — Kreis-Name (kanonischer Name; ersetzt das abgekündigte kreis_name).
        - `beds_free` integer, nullable
        - `beds_occupied` integer, nullable
        - `hospitals` object[] — Klinikscharfe Live-Status-Einschätzungen (DIVI, Tier C) je Krankenhaus-Standort (bezeichnung, ort, letzte_meldung, status_high_care, status_ecmo). Die Live-API liefert keine numerische Belegung mehr (beds_free/beds_occupied bleiben null und tragen nur das Tier-A-Kreis-Aggregat).
        - `datum` string, nullable — Abgekündigt, siehe report_date (identischer Wert). Wird frühestens 30 Tage nach Ankündigung vom 2026-08-01 entfernt.
        - `report_date` string, nullable — Stand-Datum der Meldung (kanonischer Name; ersetzt das abgekündigte datum).
      - RoadEventPayload
        - `kind` 'road_event', required
        - `city_source` string, nullable
        - `events` object[]
      - WebcamPayload
        - `kind` 'webcam', required
        - `count` integer, required
        - `webcams` object[]
  - `meta` Meta, required
    - `correlation_id` string, nullable
    - `source_status` 'ok' | 'no_data' | 'disabled' | 'not_ingested' | 'not_covered' — Ehrlicher Quellen-Status der Antwort. "ok" (Daten vorhanden), "no_data" (Quelle erreichbar/abgedeckt, aber gerade keine Daten), "disabled" (Quelle per Toggle aus), "not_ingested" (kein Snapshot), "not_covered" (Stadt ist für diesen teilabgedeckten Endpunkt strukturell nicht abgedeckt; data=null, siehe covered_cities). Klar unterscheidbar vom 404 (Stadt unbekannt).
    - `cache_status` string, nullable — Cache-Herkunft (hit/miss/stale), sofern die Route cacht.
    - `covered_cities` string[] — Nur bei source_status="not_covered": die Stadt-Slugs, die dieser teilabgedeckte Endpunkt tatsächlich bedient (z. B. flood, webcams, traffic, road-events).
    - `pagination` object — Bei paginierbaren Datenart-Listen (charging, energy, events, transit, OSM-Feature-Endpunkte): der EHRLICH ausgewiesene Ausschnitt (keine stille Kappung). KANAL-ABHÄNGIGER Default für gleiche URL: direktes REST liefert die volle Liste (limit=null, returned==total, truncated=false); GPT-Actions (erkannt am OpenAI-Header) bekommen ein serverseitig gebundenes Default-Limit; MCP-Aufrufe sind gebunden, weil der MCP-Client selbst ein Default-Limit setzt. Kanalunabhängige Overrides: limit=all (oder ?all=1) erzwingt die volle Liste, limit + offset blättern gezielt. meta.pagination ist bei ALLEN Kanälen gesetzt.
      - `total` integer — Gesamtzahl der Einträge (voller Bestand).
      - `returned` integer — Zahl der auf dieser Seite ausgelieferten Einträge.
      - `limit` integer, nullable — Angewandtes Seiten-Limit; null bei Vollausgabe (REST-Default oder limit=all).
      - `offset` integer — Start-Offset der Seite.
      - `truncated` boolean — true, wenn hinter dieser Seite noch Einträge liegen (offset + returned < total); bei Vollausgabe false.

## Other responses

- `404` — Unbekannte Stadt

---

[API](https://skmtc.net/infranode/apis/infranode-api.md) · [All operations](https://skmtc.net/infranode/apis/infranode-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/infranode/infranode-api/versions/8fee8b095f31/schema)
