Open Data API

API-Dokumentation

Programmatischer Zugriff auf alle Umwelt-Score-Daten für Kanton Zürich. Geeignet für Python, R, JavaScript und jede HTTP-Bibliothek.

Pro- oder Schul-Abo erforderlich. Anfragen können per Session-Cookie (Browser-Login) oder per API-Key authentifiziert werden. API-Keys werden im Admin-Bereich generiert und im Header übergeben: Authorization: Bearer usk_live_…
Unauthentifizierte Anfragen erhalten 401, Anfragen ohne passendes Abo 403. Jetzt upgraden →

Basis-URL & Lizenz

Basis-URL
/api/export/gemeinden
Authentifizierung
Session-Cookie oder Authorization: Bearer usk_live_…
Lizenz
CC BY 4.0 – Quellenangabe: BCS FS26 BFH
Format
JSON (Standard) oder CSV
Aktualisierung
Manuell / bei Pipeline-Runs

Query-Parameter

ParameterTypBeschreibungBeispiel
formatstringAusgabeformat: json (Standard) oder csvformat=csv
bezirkstringNur Gemeinden dieses Bezirksbezirk=Zürich
min_scorenumberMindest-Gesamtscore (0–100)min_score=70
max_scorenumberMaximal-Gesamtscore (0–100)max_score=50
sortstringSortierfeld: total, name, bezirk, popsort=total
orderstringSortierrichtung: desc (Standard) oder ascorder=asc

Datenfelder

FeldTypBeschreibung
bfsnumberBFS-Gemeindenummer (eindeutig, stabil)
namestringGemeindename
bezirkstringBezirksname
popnumberEinwohnerzahl
flächenumberGemeindefläche in km²
totalnumberGesamtscore (0–100)
scores.luftnumber|nullKategorie-Score Luftqualität (0–100)
scores.lärmnumber|nullKategorie-Score Lärmbelastung (0–100)
scores.energienumber|nullKategorie-Score Energiemix (0–100)
scores.grünnumber|nullKategorie-Score Grünflächen (0–100)
scores.bodennumber|nullKategorie-Score Boden & Klima (0–100)
data_quality.*stringDatenqualität pro Kategorie: complete, partial, estimated, missing
raw.nox_t_anumber|nullNOx-Emissionen (t/a/km²)
raw.pm10_t_anumber|nullPM10-Emissionen (t/a/km²)
raw.pm25_t_anumber|nullPM2.5-Emissionen (t/a/km²)
raw.solar_usage_pctnumber|nullPV-Nutzungsgrad Gebäude (%)
raw.renewable_heating_pctnumber|nullErneuerbare Wärme (%)
raw.electric_car_share_pctnumber|nullE-Auto-Anteil (‰)
raw.strassenlaerm_pctnumber|nullStrassenlärm: % Bev. über Grenzwert
raw.bahnlaerm_pctnumber|nullBahnlärm: % Bev. über Grenzwert
raw.fluglaerm_pctnumber|nullFluglärm: % Bev. über Grenzwert
raw.wald_pctnumber|nullWaldanteil (%)
raw.schutzgebiet_pctnumber|nullSchutzgebietsanteil (%)
raw.versiegelung_pctnumber|nullVersiegelungsgrad (%)
raw.belastete_per_km2number|nullBelastete Standorte pro km²
raw.hitzetagenumber|nullØ Hitzetage pro Jahr (MeteoSchweiz Klimanorm)
raw.strompreis_rp_kwhnumber|nullStrompreis Haushalt H4 in Rp./kWh (ElCom)

Beispiel-Requests

curlAlle Gemeinden als JSON (API-Key)
curl "https://umwelt-score.com/api/export/gemeinden" \
  -H "Authorization: Bearer usk_live_YOUR_KEY" \
  -o gemeinden-zh.json
curlNur Top-Gemeinden als CSV
curl "https://umwelt-score.com/api/export/gemeinden?format=csv&min_score=70&sort=total" \
  -H "Authorization: Bearer usk_live_YOUR_KEY" \
  -o top-gemeinden.csv
PythonDaten in pandas laden
import requests
import pandas as pd

API_KEY = "usk_live_YOUR_KEY"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

r = requests.get("https://umwelt-score.com/api/export/gemeinden", headers=HEADERS)
if r.status_code != 200:
    raise SystemExit(f"Fehler {r.status_code}: {r.json().get('message', r.text)}")

data = r.json()
df = pd.DataFrame(data["gemeinden"])

# Scores und Rohdaten als eigene Spalten
scores = pd.json_normalize(df["scores"]).add_prefix("score_")
raw    = pd.json_normalize(df["raw"]).add_prefix("raw_")
df = pd.concat([df[["bfs","name","bezirk","pop","fläche","total"]], scores, raw], axis=1)

print(df.sort_values("total", ascending=False).head(10))

# Hitzetage & Strompreis
print(df[["name","raw_hitzetage","raw_strompreis_rp_kwh","total"]].sort_values("raw_hitzetage", ascending=False).head(10))
RDaten in R laden
library(httr)
library(jsonlite)

API_KEY <- "usk_live_YOUR_KEY"

res <- GET("https://umwelt-score.com/api/export/gemeinden",
           add_headers(Authorization = paste("Bearer", API_KEY)))
data <- fromJSON(content(res, "text", encoding = "UTF-8"))
df <- data$gemeinden

# Scores und Rohdaten extrahieren
scores <- as.data.frame(df$scores)
names(scores) <- paste0("score_", names(scores))
raw <- as.data.frame(df$raw)
df <- cbind(df[c("bfs","name","bezirk","pop","total")], scores, raw)

# Korrelation Hitzetage vs. Boden-Score
cor(df$hitzetage, df$score_boden, use = "complete.obs")

# Günstigste Gemeinden nach Strompreis
head(df[order(df$strompreis_rp_kwh), c("name","strompreis_rp_kwh","score_energie")], 10)
JavaScriptFetch im Browser
const API_KEY = 'usk_live_YOUR_KEY'
const res = await fetch('https://umwelt-score.com/api/export/gemeinden?min_score=60', {
  headers: { Authorization: `Bearer ${API_KEY}` }
})
if (!res.ok) throw new Error(`Fehler ${res.status}: ${(await res.json()).message}`)
const { gemeinden, metadata } = await res.json()

console.log(`${gemeinden.length} Gemeinden geladen (Stand: ${metadata.pipeline_meta?.generated_at})`)

// Bezirks-Durchschnitt Score + Ø Hitzetage
const byBezirk = {}
for (const g of gemeinden) {
  if (!byBezirk[g.bezirk]) byBezirk[g.bezirk] = { scores: [], hitzetage: [] }
  byBezirk[g.bezirk].scores.push(g.total)
  if (g.raw?.hitzetage != null) byBezirk[g.bezirk].hitzetage.push(g.raw.hitzetage)
}
const avg = Object.fromEntries(
  Object.entries(byBezirk).map(([b, d]) => [b, {
    score: (d.scores.reduce((a,v) => a+v) / d.scores.length).toFixed(1),
    hitzetage: d.hitzetage.length ? (d.hitzetage.reduce((a,v) => a+v) / d.hitzetage.length).toFixed(1) : '–',
  }])
)
console.table(avg)

Antwort-Struktur (JSON)

{
  "metadata": {
    "exported_at": "2026-05-08T10:00:00.000Z",
    "count": 160,
    "kanton": "ZH",
    "lizenz": "CC BY 4.0",
    "pipeline_meta": { "generated_at": "2026-05-08T08:12:33", ... }
  },
  "gemeinden": [
    {
      "bfs": 261,
      "name": "Zürich",
      "bezirk": "Zürich",
      "pop": 436551,
      "fläche": 87.9,
      "total": 37.5,
      "scores": { "luft": 38, "lärm": 22, "energie": 61, "grün": 52, "boden": 44 },
      "data_quality": { "luft": "complete", "lärm": "estimated", ... },
      "raw": {
        "nox_t_a": 12.4, "solar_usage_pct": 18.2,
        "hitzetage": 8.3, "strompreis_rp_kwh": 24.1, ...
      },
      "meta": { "netzbetreiber": "EWZ", "elcom_year": "2026" }
    },
    ...
  ]
}