API & Agenten
Eine kostenlose, selbstbediente API für Schweizer Baugesuche — aggregiert
aus 19 amtlichen Quellen in 18 Kantonen (öffentliche amtsblattportal.ch-API,
kantonale Open-Data-/Geo-Dienste [GE: SITG, NE: SITN] und amtliche Wochenblätter [UR, GL, JU]),
harmonisiert in ein Modell (bgch.v1) und als JSON & XML abrufbar.
Aktuell 11'300 Publikationen aus
18 Kantonscodes / 842 Quellbezeichnungen im Gemeindefeld
(neuestes gespeichertes Datum: 12.10.2026, ältestes: 09.06.2026).
Gezählt werden Publikationen und Registereinträge, keine eindeutigen Projekte. Genfer Daten
verwenden das Einreichedatum; Abdeckung und Aktualität stehen auf der Methodikseite.
Swagger-Docs OpenAPI JSON /meta (Live-Coverage) MCP-Server llms-full.txt llms.txt RSS
Aufbewahrung & amtliche Originalquelle
- Übernommene Metadaten bleiben soweit betrieblich verfügbar abrufbar. Korrekturen und
Löschungen sind möglich; externe Dokumente können verschwinden. Eine unbegrenzte
Aufbewahrung wird nicht zugesagt. Das bisherige Feld
infinite_historybleibt aus Kompatibilitätsgründen vorhanden und istfalse. - Massgebend ist die von der zuständigen Behörde bezeichnete amtliche Publikation oder das Dossier. Nicht jeder Datensatz hat ein PDF. JSON, harmonisiertes XML, Titel und Beschreibungen sind die Darstellung dieses Aggregators, keine amtliche Fassung.
/changesfolgt der ersten Übernahmezeitingested_at. Es ist kein vollständiges Änderungs- oder Löschprotokoll. Aktualisierungen, die diesen Zeitpunkt erhalten, werden nicht erneut gemeldet; wichtige Datensätze separat abgleichen.- Maschinenformate: alle Datumsangaben sind ISO 8601 (
YYYY-MM-DD, Zeitstempel mit Zeitzone). Nur die Website-Anzeige nutztDD.MM.YYYY.
Auth & Rate-Limits
Zugriff ist ohne Anmeldung möglich. Ein kostenloser Key hebt das Limit an — mehr braucht es nicht.
| Limit | Header | |
|---|---|---|
| Anonym (pro IP) | 120 Requests / Stunde | X-RateLimit-Limit, -Remaining, -Reset; bei 429 zusätzlich Retry-After |
| Mit Key | 5000 Requests / Stunde |
Key mitgeben als HTTP-Header: Authorization: Bearer bg_<key>.
Key unten anfordern (Double-Opt-in per E-Mail, wird genau einmal angezeigt).
Quickstart
Startpunkt für Agenten: /llms-full.txt (vollständige Referenz, agent-optimiert) oder /api/docs (Swagger). Filterbeispiele sind direkt nutzbar; Platzhalter für API-Key, Datensatz-ID und Cursor ersetzen Sie durch Werte aus Ihrer eigenen Antwort.
curl — Liste, Filter, Cursor
# List + filter: energy/heating permits in canton Zürich matching "Wärmepumpe"
curl -s "https://baugesucheschweiz.switchli.ch/api/v1/publications?canton=ZH&category=energie_heizung&q=W%C3%A4rmepumpe&limit=5"
# With a free key (5000 req/h instead of 120):
curl -s -H "Authorization: Bearer bg_your_key_here" \
"https://baugesucheschweiz.switchli.ch/api/v1/publications?canton=ZH&limit=5"
# Follow the cursor to the next page: take next_cursor from the response above,
# pass it back as &cursor=... — keyset pagination (no OFFSET).
curl -s "https://baugesucheschweiz.switchli.ch/api/v1/publications?canton=ZH&limit=5&cursor=NEXT_CURSOR_FROM_PREVIOUS_RESPONSE"
# One full record (JSON), incl. links to the official PDF/XML:
curl -s "https://baugesucheschweiz.switchli.ch/api/v1/publications/d22d21f6-e361-4655-bd1d-8c2350863cdb"
Python — urllib (no dependencies)
import json
import urllib.parse
import urllib.request
BASE = "https://baugesucheschweiz.switchli.ch/api/v1"
# API_KEY = "bg_your_key_here" # optional: raises the rate limit to 5000/h
def get(path, **params):
url = f"{BASE}{path}?" + urllib.parse.urlencode({k: v for k, v in params.items() if v})
req = urllib.request.Request(url, headers={"Accept": "application/json"})
# req.add_header("Authorization", "Bearer " + API_KEY) # uncomment with a key
with urllib.request.urlopen(req, timeout=15) as r:
return json.load(r)
# Filtered search
page = get("/publications", canton="ZH", category="energie_heizung", q="Wärmepumpe", limit=5)
print(page["total"], "matches")
for item in page["items"]:
print(item["publication_date"], item["municipality"]["name"], "-", item["title"][:70])
# Paginate every match with the keyset cursor
cursor = ""
while True:
page = get("/publications", canton="ZH", category="energie_heizung", limit=50, cursor=cursor)
for item in page["items"]:
pass # ... process item (bgch.v1 dict)
cursor = page["next_cursor"]
if not cursor:
break
JavaScript — fetch
const BASE = "https://baugesucheschweiz.switchli.ch/api/v1";
// const API_KEY = "bg_your_key_here"; // optional: 5000 req/h
async function search(params) {
const qs = new URLSearchParams(params).toString();
const res = await fetch(`${BASE}/publications?${qs}`, {
headers: {
"Accept": "application/json",
// "Authorization": `Bearer ${API_KEY}`, // uncomment with a key
},
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
const page = await search({ canton: "ZH", category: "energie_heizung", q: "Wärmepumpe", limit: 5 });
console.log(page.total, "matches");
for (const item of page.items) {
console.log(item.publication_date, item.municipality.name, item.title);
}
// Next page: search({ canton: "ZH", limit: 50, cursor: page.next_cursor })
MCP-Server (für KI-Agenten)
Der differenzierende Teil: ein Model-Context-Protocol-Server über
Streamable HTTP unter https://baugesucheschweiz.switchli.ch/mcp. Agenten (z. B. Claude) verbinden
sich direkt und rufen Tools auf — ohne eigenen API-Client zu schreiben.
| Tool | Zweck |
|---|---|
search_baugesuche | Volltext-/Filtersuche (Kanton, Kategorie, Gemeinde, Datum) → bgch.v1-Datensätze. |
get_baugesuch | Ein vollständiger Datensatz per ID, inkl. Links zur amtlichen PDF/XML. |
get_coverage | Abgedeckte Kantone, Zahlen, ältester/neuester Datensatz, Aufbewahrung & Quellenhinweis. |
Verbindung (Claude Desktop / Agent-Config), stateless — keine Session nötig:
{
"mcpServers": {
"baugesuche": {
"type": "streamable-http",
"url": "https://baugesucheschweiz.switchli.ch/mcp"
}
}
}
Roher JSON-RPC-Aufruf über Streamable HTTP (Antwort ist Server-Sent-Events; die
JSON-RPC-Nutzlast steht in der data:-Zeile):
curl -s -X POST "https://baugesucheschweiz.switchli.ch/mcp" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"search_baugesuche",
"arguments":{"query":"Wärmepumpe","canton":"ZH","limit":3}}}'
Kostenlosen API-Key anfordern
Optional — nur nötig, wenn 120 Requests/Stunde nicht reichen. Sie erhalten eine Bestätigungs-E-Mail (Double-Opt-in); der Key wird danach genau einmal angezeigt. Wir speichern nur den SHA-256-Hash.
Endpunkte & weiterführende Links
| Endpunkt | Zweck |
|---|---|
GET /api/v1/meta | Coverage, Taxonomie, Zahlen, Schema-/Docs-/MCP-URLs — hier starten. |
GET /api/v1/publications | Gefilterte, keyset-paginierte Liste (bgch.v1). |
GET /api/v1/publications/{id} | Ein Datensatz als JSON (.xml harmonisiert, /original.xml amtliches Passthrough). |
GET /api/v1/changes?since=… | Inkrementeller Sync über ingested_at für Agenten/Mirrors. |
POST /api/v1/keys | Kostenloser Key (Double-Opt-in per E-Mail). |
/api/docs | Interaktive Swagger-Dokumentation. |
/api/v1/openapi.json | OpenAPI-3-Schema (Codegen). |
/mcp | MCP-Server (Streamable HTTP, POST) für Agenten — Details & Beispiel oben. |
/llms-full.txt | Vollständige agent-optimierte Referenz (Plain Text). |
/feed.xml | RSS, unterstützt dieselben Filter-Parameter. |
Kanton-Codes
ZH Zürich · BE Bern · LU Luzern · UR Uri · SZ Schwyz · OW Obwalden · NW Nidwalden · GL Glarus · ZG Zug · FR Freiburg · SO Solothurn · BS Basel-Stadt · BL Basel-Landschaft · SH Schaffhausen · AR Appenzell Ausserrhoden · AI Appenzell Innerrhoden · SG St. Gallen · GR Graubünden · AG Aargau · TG Thurgau · TI Tessin · VD Waadt · VS Wallis · NE Neuenburg · GE Genf · JU Jura.
Abdeckung: ZH ist von Gesetzes wegen vollständig; AG fehlt bewusst (nicht über amtsblattportal.ch publiziert).
Live-Zahlen pro Kanton: /api/v1/meta.
Kategorie-Codes (statische Taxonomie, multi-label)
energie_heizung Energie & Heizung · solar_pv Solar & PV · neubau_wohnen Neubau Wohnen · umbau_sanierung Umbau & Sanierung · abbruch Abbruch · kleinbauten Kleinbauten · gewerbe_industrie Gewerbe & Industrie · landwirtschaft Landwirtschaft · aussenanlagen_infrastruktur Aussenanlagen & Infrastruktur · sonstiges Sonstiges.