TrinkwassermonitorWasser-Evidenz

Trinkwasser Open Data: CSV, API und Zitierhinweis

Wie kommen Sie an die Daten, und wie zitieren Sie genau den Stand, mit dem Sie gearbeitet haben?

Dateien

Alle Dateien und Druckfassungen stehen im Downloadcenter.

Datenstand und Prüfsumme prüfen

Das jüngste Messdatum allein identifiziert eine Datenversion nicht: Neue Berichte können ältere Messdaten enthalten. Die Prüfsumme schon. Die Tabellen dieses Bereichs beruhen auf der CSV mit der Prüfsumme 33cb9bd2af89 (die ersten 12 Zeichen von SHA-256, Datenstand-Kennung 2026-10-07-291de1d0). So prüfen Sie Ihre Datei:

sha256sum trinkwasser-messwerte.csv

Stimmen die ersten 12 Zeichen nicht überein, ist Ihre Datei ein anderer Stand. Dann können Ihre Zahlen von denen auf diesen Seiten abweichen, ohne dass einer von beiden falsch gerechnet hat.

Schnittstelle (API) und MCP

Ohne Anmeldung, JSON. Für Lehre und Forschung besonders nützlich:

Alle Endpunkte stehen in der OpenAPI-Beschreibung und im Downloadcenter. KI-Assistenten können die Werte über einen MCP-Server abfragen. Die API liefert den jeweils aktuellen Stand der Datenbank; er kann neuer sein als die CSV, auf der diese Seite beruht.

Spaltenwörterbuch

Spalten von trinkwasser-messwerte.csv
SpalteTypEinheitBedeutung
stadtText–Name der Stadt, wie auf der Stadtseite
stadt_slugText–Kennung der Stadt in unseren Adressen (/trinkwasser/{slug}/)
bundeslandText–Bundesland
landkreisText–Landkreis bzw. kreisfreie Stadt
breitengradZahlGrad (WGS 84)Lage des Stadtmittelpunkts (WGS 84), nur zur Einordnung, keine Messstelle
laengengradZahlGrad (WGS 84)Lage des Stadtmittelpunkts (WGS 84)
versorgerText–Wasserversorger hinter den Werten
wasserText–Nur bei Städten mit mehreren Wässern: Name des Wassers laut Versorger, sonst leer
wasser_anteil_adressen_prozentZahlProzentNur bei mehreren Wässern: Anteil der Adressen der Stadt, die dieses Wasser bekommen (Adressabfrage des Versorgers)
parameter_schluesselText–Maschinenlesbarer Schlüssel, z. B. nitrat, haerte, pfas
parameterText–Bezeichnung des Parameters
wertZahlSpalte einheitGemessener Wert; leer, wenn er unter der Bestimmungsgrenze lag
einheitText–Einheit von Wert, Bestimmungsgrenze und Grenzwerten
unter_bestimmungsgrenzetrue/false–true/ja, wenn der Stoff nicht quantifizierbar war
bestimmungsgrenzeZahlSpalte einheitBestimmungsgrenze des Labors, wenn der Wert darunter lag
grenzwert_trinkwvZahlSpalte einheitGeltender Grenzwert der Trinkwasserverordnung (bei pH die Obergrenze, bei Mikrobiologie 0); leer, wenn es keinen gibt (z. B. Härte)
grenzwert_trinkwv_untereZahlSpalte einheitUntere Grenze, nur beim pH-Wert (6,5)
grenzwert_kuenftigZahlSpalte einheitKünftig geltender Wert, z. B. Blei 0,005 mg/L und Summe PFAS-4 ab 12.01.2028
grenzwert_kuenftig_abDatum (ISO 8601)–Datum, ab dem der künftige Wert gilt
messdatumDatum (ISO 8601)–Datum der Probenahme bzw. Ende des Mittelungszeitraums laut Bericht – nur so genau, wie der Bericht es angibt: 2026-03-02, 2026-03 (nur Monat) oder 2025 (nur Jahr, z. B. Jahresmittelwerte)
messdatum_genauigkeitText–tag, monat oder jahr – wie genau der Bericht das Datum angibt
pruefstatusText–verified, partially_verified, unverified, outdated – Prüfstand des Werts in unserer Datenbank
quelle_herausgeberText–Herausgeber des Prüfberichts
quelle_titelText–Titel des Prüfberichts
quelle_urlURL–Link auf den Prüfbericht beim Versorger
seite_urlURL–Unsere Stadtseite mit Einordnung und Hinweisen

Lizenz

Daten und Texte stehen unter Creative Commons Namensnennung 4.0 International (CC BY 4.0). Namensnennung: „Trinkwassermonitor (trinkwassermonitor.ink), Werte aus den Prüfberichten der Wasserversorger“.

Zitierhinweis

  1. Zitieren Sie den Datensatz mit Datenstand und Abrufdatum.
  2. Zitieren Sie einzelne Messwerte immer mit Quelle, Messdatum und URL des Prüfberichts.

So bleiben die Auswertung von Trinkwassermonitor und die Originalquelle getrennt: Für einen einzelnen Wert nennen Sie den Prüfbericht aus den Spalten quelle_herausgeber, quelle_titel und quelle_url sowie messdatum.

Vorschlag für den Datensatz, mit dem Stand dieser Seite:

Trinkwassermonitor: Geprüfte Trinkwasserwerte (Datensatz trinkwasser-messwerte.csv). Lizenz CC BY 4.0. Datenstand 07.10.2026, Kennung 2026-10-07-291de1d0, Prüfsumme SHA-256 33cb9bd2af89. https://trinkwassermonitor.ink/downloads/daten/trinkwasser-messwerte.csv. Abruf: vom Zitierenden einzutragen.

Dieser Stand ist noch nicht bei Zenodo archiviert und hat daher keine eigene Versions-DOI. Zuletzt archiviert wurde der Stand 2026-09-14-ea23f366 (doi:10.5281/zenodo.23670464). Zitieren Sie diesen Stand mit Kennung und Prüfsumme. Die Serien-DOI doi:10.5281/zenodo.23451788 zeigt immer auf die neueste archivierte Fassung.

Codebeispiele

Die Beispiele zählen für den Stoff fluorid (Fluorid) die Zeilen unter der Bestimmungsgrenze, wie in Fall 1. Der Stoff ist nach einer festen Regel gewählt, nicht nach Bedeutung: Er hat einen Grenzwert, eine Einheit und zwischen einem Viertel und drei Vierteln Zeilen unter der Bestimmungsgrenze. Der Code wird auf dieser Seite nur angezeigt, nicht ausgeführt.

Python (pandas, requests)

CSV laden und Zeilen unter der Bestimmungsgrenze zählen

import pandas as pd

URL = "https://trinkwassermonitor.ink/downloads/daten/trinkwasser-messwerte.csv"
df = pd.read_csv(URL, dtype=str, keep_default_na=False)

stoff = df[df["parameter_schluessel"] == "fluorid"]
n = len(stoff)
unter_bg = (stoff["unter_bestimmungsgrenze"] == "true").sum()
print(f"n = {n}, unter Bestimmungsgrenze: {unter_bg} ({100 * unter_bg / n:.0f} %)")

Prüfsumme der heruntergeladenen Datei mit der Seite vergleichen

import hashlib
import requests

daten = requests.get("https://trinkwassermonitor.ink/downloads/daten/trinkwasser-messwerte.csv", timeout=60).content
print(hashlib.sha256(daten).hexdigest()[:12])  # mit „Prüfsumme der CSV“ auf dieser Seite vergleichen

Lücken-Register über die API abfragen

import requests

antwort = requests.get("https://trinkwassermonitor.ink/api/v1/gaps", params={"substance": "fluorid"}, timeout=30)
antwort.raise_for_status()
print(antwort.json())

R (readr, httr2, jsonlite)

CSV laden und Zeilen unter der Bestimmungsgrenze zählen

library(readr)

url <- "https://trinkwassermonitor.ink/downloads/daten/trinkwasser-messwerte.csv"
df <- read_csv(url, col_types = cols(.default = col_character()), na = character())

stoff <- df[df$parameter_schluessel == "fluorid", ]
n <- nrow(stoff)
unter_bg <- sum(stoff$unter_bestimmungsgrenze == "true")
cat("n =", n, "- unter Bestimmungsgrenze:", unter_bg, "(", round(100 * unter_bg / n), "% )\n")

Lücken-Register über die API abfragen

library(httr2)
library(jsonlite)

antwort <- request("https://trinkwassermonitor.ink/api/v1/gaps") |>
  req_url_query(substance = "fluorid") |>
  req_perform()
luecken <- fromJSON(resp_body_string(antwort))
str(luecken)