API-Dokumentation
Die KonkursRadar-API liefert Insolvenzmeldungen in der Schweiz als strukturierte Daten: pro Tag oder Zeitraum, filterbar nach Verfahrenstyp, mit Firma, Amt, Kanton und Aktenzeichen. Einfaches HTTPS und JSON, auf Wunsch CSV.
Zuletzt aktualisiert: 2026-09-29
Zugang anfragen
Schlüssel vergeben wir von Hand. Schreiben Sie uns kurz, was Sie bauen möchten und mit welchem Volumen Sie rechnen, dann ist der Zugang in der Regel innert eines Werktags aktiv.
Einführung
Die Schweizer Konkursämter veröffentlichen jeden Schritt eines Konkurses im Schweizerischen Handelsamtsblatt (SHAB): die Konkurseröffnung, den Schuldenruf, den Kollokationsplan, die Einstellung mangels Aktiven, den Schluss des Verfahrens und rund ein halbes Dutzend weitere Meldungstypen. Das Amtsblatt ist dafür gemacht, Meldungen einzeln und in vier Sprachen zu lesen. Einen Filter nach Verfahrensstand gibt es nicht, und die Meldungen einer Firma sind nicht miteinander verknüpft.
Die API schliesst diese Lücke. Wir erfassen jede neue Konkursmeldung des SHAB (Rubrik KK), normalisieren Meldungstyp, Konkursamt, Kanton und UID und liefern alles als JSON oder CSV. Kreditversicherer, Inkassofirmen, Konkursverwalter, Anwaltskanzleien und Journalisten speisen damit ihre eigenen Systeme.
Alle Anfragen gehen an https://konkursradar.ch/api/v1. Die API spricht ausschliesslich HTTPS und antwortet mit JSON oder CSV. Ein SDK ist nicht zwingend: Jede Sprache, die eine HTTP-Anfrage senden kann, genügt. Die Beispiele auf dieser Seite verwenden curl, Python und Node.
Der API-Zugang gehört zu einem KonkursRadar-Abonnement mit aktivierter API. Die Konditionen richten sich nach Volumen und Einsatzzweck und werden individuell vereinbart.
Zugang
Eine Selbstregistrierung gibt es bewusst nicht. Wir schalten Schlüssel von Hand frei, weil Insolvenzdaten Personendaten enthalten können und wir wissen möchten, wofür eine Integration gedacht ist. In der Praxis heisst das: eine kurze Nachricht und ein Werktag.
Nutzen Sie das Kontaktformular oder schreiben Sie an [email protected] und nennen Sie vier Dinge:
- Was Sie bauen möchten, in zwei oder drei Sätzen.
- Welche Verfahrenstypen und Kantone Sie benötigen.
- Grob, wie viele Anfragen oder geprüfte Firmen pro Monat anfallen.
- Ob Sie Webhooks empfangen können oder lieber abfragen.
Danach erhalten Sie einen persönlichen Schlüssel, der sofort auf allen Endpunkten funktioniert, die Ihr Vertrag abdeckt. Ein Schlüssel gehört zu einem Markt: Ein auf konkursradar.ch ausgestellter Schlüssel funktioniert auf konkursradar.ch, nicht auf den Domains anderer Länder.
Authentifizierung
Jede Anfrage trägt den Schlüssel im Header X-API-Key. Alternativ akzeptiert die API denselben Schlüssel als Bearer-Token im Header Authorization, was für Werkzeuge praktisch ist, die nur diesen Header kennen.
X-API-Key: YOUR_API_KEY
# equivalent
Authorization: Bearer YOUR_API_KEY
Ohne Schlüssel antwortet die API mit 401 missing_api_key. Ein unbekannter oder deaktivierter Schlüssel, oder einer, dessen Abonnement abgelaufen ist, liefert 403 invalid_api_key. Der Grund steht immer im Feld error der Antwort.
Behandeln Sie den Schlüssel wie ein Passwort: Verwenden Sie ihn nur serverseitig, nie im Frontend-Code und nie in einem öffentlichen Repository. Wenn ein Schlüssel abfliesst, melden Sie uns das, wir sperren ihn sofort und stellen einen neuen aus.
Schnellstart
Die häufigste Anfrage ist zugleich die einfachste: alle Meldungen eines Tages, wahlweise auf einige Verfahrenstypen eingegrenzt. Ein Aufruf, keine Paginierung.
curl -H "X-API-Key: $KONKURS_API_KEY" \
"https://konkursradar.ch/api/v1/filings?date=2026-09-28&types=bankruptcy-opening,kk03"
Ohne Datum liefert die API den gestrigen Tag. Damit wird ein täglicher Job trivial: Ein Cron-Eintrag am Morgen holt die Meldungen von gestern und schreibt sie in Ihr System.
Für einen historischen Abgleich gehen Sie den Zeitraum in Fenstern von höchstens 31 Tagen durch:
import os, datetime, requests
API = "https://konkursradar.ch/api/v1"
HEAD = {"X-API-Key": os.environ["KONKURS_API_KEY"]}
# Backfill a quarter in 31-day windows, then keep running daily.
start, end = datetime.date(2026, 7, 1), datetime.date(2026, 9, 28)
day = start
while day <= end:
stop = min(day + datetime.timedelta(days=30), end)
r = requests.get(API + "/filings", headers=HEAD, params={
"date_from": day.isoformat(),
"date_to": stop.isoformat(),
"types": "bankruptcy-opening,kk03",
}, timeout=60)
r.raise_for_status()
body = r.json()
if body.get("truncated"):
raise RuntimeError("narrow the window, 10,000 row ceiling reached")
for f in body["filings"]:
print(f["date"], f["case_number"], f["name"])
day = stop + datetime.timedelta(days=1)
Endpunkte im Überblick
| Methode | Pfad | Zweck |
|---|---|---|
| GET | /v1/filings | Meldungen für einen Tag oder Zeitraum, filterbar nach Verfahrenstyp, als JSON oder CSV. Heute live. |
| GET | /v1/types | Verfahrenstypen dieses Marktes mit Schlüssel, Codes und Aliasen. |
| GET | /v1/companies | Firmen suchen, die in mindestens einer Meldung vorkommen. |
| GET | /v1/companies/{number} | Firmenprofil mit aktuellem Insolvenzstatus. |
| GET | /v1/companies/{number}/filings | Alle Meldungen einer Firma in chronologischer Reihenfolge. |
| GET | /v1/companies/{number}/financials | Veröffentlichte Kennzahlen aus den Jahresrechnungen. |
| GET | /v1/practitioners | Zuständige Konkursämter suchen. |
| GET | /v1/practitioners/{id} | Ein Konkursamt mit aktiven Verfahren. |
| POST | /v1/check | Bis zu 500 Kunden oder Lieferanten in einem Aufruf prüfen. |
| GET | /v1/watchlist | Beobachtete Firmen auflisten. |
| POST | /v1/watchlist | Eine Firma zur Watchlist hinzufügen. |
| DELETE | /v1/watchlist/{id} | Eine Firma von der Watchlist entfernen. |
| POST | /v1/webhooks | Einen Endpunkt für Push-Benachrichtigungen registrieren. |
| GET | /v1/stats | Aggregierte Zahlen nach Tag, Monat, Kanton oder Verfahrenstyp. |
| GET | /v1/regions | Gültige Werte für den Kantonsfilter. |
| GET | /v1/account | Schlüssel, Vertragsumfang, Limits und aktuelle Nutzung. |
Pfade sind relativ zu https://konkursradar.ch/api. Die vollständige Adresse des ersten Endpunkts lautet also https://konkursradar.ch/api/v1/filings. Der Endpunkt für Meldungen ist produktiv; die übrigen Endpunkte folgen denselben Konventionen für Schlüssel, Fehler und Limits und werden je Vertrag freigeschaltet.
Meldungen abrufen
GET /v1/filings ist der Kern der API. Der Endpunkt liefert jede Meldung, deren Datum in den gewünschten Zeitraum fällt, die neueste zuerst.
| Parameter | Format | Beschreibung |
|---|---|---|
| date | YYYY-MM-DD | Ein einzelner Tag. Hat Vorrang vor date_from und date_to. |
| date_from | YYYY-MM-DD | Beginn eines Zeitraums, inklusive. Wird nur date_from angegeben, gilt dieser eine Tag. |
| date_to | YYYY-MM-DD | Ende eines Zeitraums, inklusive. Wird nur date_to angegeben, gilt dieser eine Tag. Höchstens 31 Tage inklusive beider Enden. Liegt date_from nach date_to, antwortet die API mit 400 bad_range, statt zu raten. |
| types | csv | Kommagetrennte Liste von Verfahrenstypen: Gruppenschlüssel, Alias oder Rohcode, ohne Beachtung der Gross- und Kleinschreibung. Ohne Angabe gelten alle Typen. Siehe nächster Abschnitt. |
| format | json | csv | json (Standard) oder csv. |
Ohne date, date_from und date_to ist der Zeitraum der gestrige Tag.
Antwort
| Feld | Typ | Beschreibung |
|---|---|---|
| date_from | string | Effektiver Beginn des Zeitraums. |
| date_to | string | Effektives Ende des Zeitraums. |
| types | string[] | Die Gruppenschlüssel, die nach Auflösung von Aliasen und Codes ausgeliefert wurden. |
| count | integer | Anzahl der Meldungen im Array. |
| filings | object[] | Die Meldungen, siehe Meldungsobjekt. |
| truncated | boolean | Nur vorhanden, und dann true, wenn die Antwort die Obergrenze von 10 000 Zeilen erreicht hat. Grenzen Sie Zeitraum oder Typen ein und fragen Sie erneut ab. |
{
"date_from": "2026-09-28",
"date_to": "2026-09-28",
"types": ["proceedings-suspended", "bankruptcy-opening"],
"count": 57,
"filings": [
{
"date": "2026-09-28",
"type": "Konkurseröffnung",
"type_code": "KK01",
"name": "Beispiel Holzbau AG",
"address": "Industriestrasse 12, 8404 Winterthur",
"court": "Konkursamt Winterthur",
"case_number": "KK01-0000312845",
"region": "ZH",
"notice": "Konkurseröffnung: Beispiel Holzbau AG. Entscheiddatum: 2026-09-25. Publikation: 2026-09-28."
}
]
}
Ein Zeitraum kommt immer am Stück zurück: Dieser Endpunkt kennt keine Paginierung. Die Zeilen sind nach Datum sortiert, die neuesten zuerst, und innerhalb eines Tages nach interner ID, ebenfalls die neuesten zuerst. Dieselbe Anfrage in Node, clientseitig auf einen Kanton gefiltert:
const url = new URL("https://konkursradar.ch/api/v1/filings");
url.searchParams.set("date_from", "2026-09-01");
url.searchParams.set("date_to", "2026-09-28");
url.searchParams.set("types", "bankruptcy-opening");
const res = await fetch(url, {
headers: { "X-API-Key": process.env.KONKURS_API_KEY },
});
if (!res.ok) throw new Error((await res.json()).error);
const { count, filings } = await res.json();
const local = filings.filter((f) => f.region === "ZH");
console.log(count, "filings,", local.length, "in ZH");
Verfahrenstypen
Die SHAB-Rubrik für Konkurse kennt zwölf Meldungstypen, KK01 bis KK12. Der Parameter types akzeptiert den Gruppenschlüssel, den Code selbst (kk01) oder einen deutschen Alias, ohne Beachtung der Gross- und Kleinschreibung und durch Komma getrennt.
| Schlüssel | Code | Bedeutung |
|---|---|---|
| bankruptcy-opening | KK01 | Konkurseröffnung Aliase: kk01, konkurseroeffnung, opening |
| call-for-claims | KK02 | Schuldenruf Aliase: kk02, schuldenruf, claims |
| proceedings-suspended | KK03 | Einstellung des Konkursverfahrens Aliase: kk03, einstellung, suspension |
| schedule-of-claims | KK04 | Kollokationsplan und Inventar Aliase: kk04, kollokationsplan, inventar |
| distribution-list | KK05 | Verteilungsliste und Schlussrechnung Aliase: kk05, verteilungsliste, schlussrechnung |
| proceedings-closed | KK06 | Schluss des Konkursverfahrens Aliase: kk06, schluss, closure |
| bankruptcy-revoked | KK07 | Widerruf des Konkurses Aliase: kk07, widerruf, revocation |
| property-auction | KK08 | Konkursamtliche Grundstücksteigerung Aliase: kk08, grundstuecksteigerung, steigerung, auction |
| encumbrance-schedule | KK09 | Lastenverzeichnisse Aliase: kk09, lastenverzeichnis, lastenverzeichnisse |
| dissolution-revoked | KK10 | Aufhebung Auflösungsentscheid Aliase: kk10, aufhebung-aufloesungsentscheid, aufhebung |
| foreign-bankruptcy-recognition | KK11 | Anerkennung eines ausländischen Konkurses (Art. 166 ff. IPRG) Aliase: kk11, anerkennung, iprg-anerkennung |
| foreign-bankruptcy-waiver | KK12 | Verzicht auf die Durchführung eines IPRG-Konkursverfahrens (Art. 174a IPRG) Aliase: kk12, verzicht, iprg-verzicht |
Das Feld type enthält die amtliche deutsche Bezeichnung des Meldungstyps, type_code den SHAB-Code KK01 bis KK12. Ein unbekannter Wert in types liefert 400 bad_type zusammen mit allowed_types, der vollständigen Liste der akzeptierten Werte. Agenten und Skripte sollten diese Liste auslesen, statt zu raten.
Das Meldungsobjekt
| Feld | Typ | Beschreibung |
|---|---|---|
| date | string | Datum der Meldung, YYYY-MM-DD: das jüngste datierte Ereignis des Falls, das nicht in der Zukunft liegt. Der Datumsfilter arbeitet auf diesem Feld. |
| type | string | Lesbare Bezeichnung des Verfahrenstyps. |
| type_code | string | Maschinenschlüssel des Verfahrenstyps. Verwenden Sie dieses Feld für die Verarbeitung, es ändert sich nicht. |
| name | string | Name der Schuldnerin bzw. des Schuldners wie veröffentlicht, inklusive Rechtsform (AG, GmbH, Genossenschaft ...). |
| address | string | null | Sitzadresse in einer Zeile, z. B. Industriestrasse 12, 8404 Winterthur. |
| court | string | null | Konkursamt, das die Meldung veröffentlicht hat; bei der Anerkennung ausländischer Konkurse nach IPRG das Konkursgericht. |
| case_number | string | SHAB-Publikationsnummer, z. B. KK01-0000312845. Pro Meldung eindeutig. |
| region | string | null | Kanton als zweistelliges Kürzel, z. B. ZH, BE, VD. |
| notice | string | null | Der amtliche SHAB-Titel (auf Deutsch, sofern vorhanden, sonst in der Sprache des veröffentlichenden Kantons) samt Entscheiddatum und Publikationsdatum. |
Eine Zeile ist eine SHAB-Meldung. Ein Konkurs erzeugt mehrere: Konkurseröffnung, Schuldenruf, Kollokationsplan, Verteilungsliste, Schluss des Verfahrens. Gruppieren Sie nach UID, um das Verfahren einer Firma zu verfolgen; jede Meldung hat ihre eigene case_number.
Alle Textfelder sind UTF-8. Namen geben wir so weiter, wie die Quelle sie veröffentlicht. Felder, die die Quelle nicht liefert, sind null, nie eine leere Vermutung. Fälle ohne verwertbares Datum lassen sich keinem Tag zuordnen und werden nicht ausgeliefert. Ihr Client sollte unbekannte Felder ignorieren, denn es können neue Felder hinzukommen.
CSV-Export
Mit format=csv liefert die API dieselben Zeilen als CSV-Datei: Kopfzeile, Komma als Trennzeichen, UTF-8, Content-Type: text/csv; charset=utf-8. Die Datei kommt mit Content-Disposition: attachment und einem Dateinamen, der den Zeitraum enthält.
curl -H "X-API-Key: $KONKURS_API_KEY" \
-OJ "https://konkursradar.ch/api/v1/filings?date_from=2026-09-01&date_to=2026-09-28&format=csv"
# saved as filings_2026-09-01_2026-09-28.csv
date,type,type_code,name,address,court,case_number,region,notice
2026-09-28,Konkurseröffnung,KK01,Beispiel Holzbau AG,"Industriestrasse 12, 8404 Winterthur",Konkursamt Winterthur,KK01-0000312845,ZH,"Konkurseröffnung: Beispiel Holzbau AG. Entscheiddatum: 2026-09-25. Publikation: 2026-09-28."
Die Spalten entsprechen genau den Feldern des Meldungsobjekts, in derselben Reihenfolge. Felder mit Kommas stehen in Anführungszeichen. Excel öffnet die Datei korrekt über „Daten, aus Text/CSV“ mit UTF-8-Kodierung; ein einfacher Doppelklick kann je nach Systemeinstellung Umlaute und Akzente verstümmeln.
Firmen
Meldungen betreffen Fälle, die meisten Anwendungen drehen sich aber um Firmen. GET /v1/companies durchsucht jede Firma, die in mindestens einer Meldung vorkommt, nach Name, Registernummer, Ort, Kanton oder Status.
curl -G -H "X-API-Key: $KONKURS_API_KEY" \
https://konkursradar.ch/api/v1/companies \
--data-urlencode "q=Beispiel Holzbau AG" \
-d region=ZH -d limit=20
Listen-Endpunkte liefern Seiten mit höchstens 100 Einträgen und einem Cursor:
{
"object": "list",
"data": [ { "company_number": "CHE-123.456.789", "object": "company", "...": "..." } ],
"has_more": true,
"next_cursor": "eyJpZCI6MTQ4MzkyMDV9"
}
Solange has_more auf true steht, übergeben Sie next_cursor als Parameter cursor der nächsten Anfrage. Ein Cursor bleibt 24 Stunden gültig.
Das Firmenobjekt
{
"company_number": "CHE-123.456.789",
"object": "company",
"name": "Beispiel Holzbau AG",
"status": "bankruptcy",
"address": "Industriestrasse 12, 8404 Winterthur",
"region": "ZH",
"industry": "Construction",
"first_filing": "2026-09-01",
"last_filing": "2026-09-28",
"filings_count": 2,
"url": "https://konkursradar.ch/company/CHE-123.456.789"
}
| Feld | Typ | Beschreibung |
|---|---|---|
| company_number | string | Schweizer UID, z. B. CHE-123.456.789. |
| name | string | Name gemäss der jüngsten Meldung. |
| status | string | Aktueller Stand, abgeleitet aus der jüngsten Meldung. Eine praxisnahe Zusammenfassung, keine rechtliche Würdigung. |
| address | string | null | Sitzadresse. |
| region | string | null | Kanton, dieselben Werte wie bei den Meldungen. |
| industry | string | null | Branche nach unserer Klassifikation, sofern sie sich bestimmen lässt. |
| first_filing | string | Datum der ersten bekannten Meldung. |
| last_filing | string | Datum der jüngsten Meldung. |
| filings_count | integer | Anzahl der Meldungen, die mit dieser Firma verknüpft sind. |
| url | string | Öffentliche Firmenseite auf konkursradar.ch. |
GET /v1/companies/{number}/filings liefert alle Meldungen einer Firma, die älteste zuerst, in derselben Form wie /v1/filings. So erhalten Sie die vollständige Historie, ohne selbst nach dem Namen suchen zu müssen.
Finanzkennzahlen
Schweizer Unternehmen müssen ihre Jahresrechnung nicht veröffentlichen, ausgenommen börsenkotierte Gesellschaften und Banken. GET /v1/companies/{number}/financials gibt es, damit die Schnittstelle über alle Märkte hinweg einheitlich bleibt, für die meisten Schweizer Firmen liefert sie aber eine leere Liste statements.
{
"company_number": "CHE-123.456.789",
"currency": "CHF",
"statements": [
{
"period_end": "2025-03-31",
"total_assets": 1840000,
"net_assets": -212000,
"current_liabilities": 1395000,
"cash": 18400,
"employees": 23
},
{
"period_end": "2024-03-31",
"total_assets": 2105000,
"net_assets": 164000,
"current_liabilities": 1210000,
"cash": 96100,
"employees": 31
}
]
}
Kennzahlen schätzen wir nie. Wenn Sie ein Bonitätsbild zu Schweizer Firmen brauchen, kombinieren Sie den Konkursstatus aus dieser API mit dem Aktienkapital und der Registerhistorie aus dem Handelsregister.
Verfahrensführende
In der Schweiz werden Konkurse von den kantonalen Konkursämtern abgewickelt, gelegentlich durch eine ausseramtliche Konkursverwaltung. GET /v1/practitioners listet diese Ämter mit Kanton und Fallzahl; GET /v1/practitioners/{id} liefert ein Amt mit seinen offenen Verfahren.
curl -G -H "X-API-Key: $KONKURS_API_KEY" \
https://konkursradar.ch/api/v1/practitioners \
-d city=Winterthur -d limit=10
{
"id": "prc_2Pw6Nc8Tf",
"object": "practitioner",
"name": "Konkursamt Winterthur",
"firm": "Kanton Zürich",
"city": "Winterthur",
"active_cases": 41,
"total_cases": 318,
"last_appointment": "2026-09-28",
"url": "https://konkursradar.ch/practitioners/"
}
Typischer Einsatz: Ein Gläubiger möchte wissen, wohin er seine Forderung richten muss. Das Firmenprofil nennt das zuständige Konkursamt, der Endpunkt für Verfahrensführende ergänzt Adresse und Fallzahl.
Gegenparteiprüfung
POST /v1/check prüft eine ganze Liste von Kunden oder Lieferanten in einem Aufruf. Sie senden Ihre eigene Referenz und alles, was Sie über die Firma wissen: Name, Ort oder Registernummer. Die API gibt für jeden Eintrag einen Treffer und den Insolvenzstatus zurück.
curl https://konkursradar.ch/api/v1/check \
-H "X-API-Key: $KONKURS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"since": "2024-01-01",
"items": [
{ "ref": "D-10023", "name": "Beispiel Holzbau AG", "city": "Winterthur" },
{ "ref": "D-10024", "company_number": "CHE-234.567.890" },
{ "ref": "D-10025", "name": "Seeblick Gastro GmbH" }
]
}'
{
"checked": 3,
"hits": 1,
"results": [
{
"ref": "D-10023",
"match": "exact",
"company_number": "CHE-123.456.789",
"status": "bankruptcy",
"last_filing": { "date": "2026-09-28", "type_code": "KK01", "case_number": "KK01-0000312845" }
},
{ "ref": "D-10024", "match": "none" },
{ "ref": "D-10025", "match": "ambiguous", "candidates": 2 }
]
}
| match | Bedeutung |
|---|---|
| exact | Die Registernummer stimmt, oder Name und Ort passen eindeutig. |
| probable | Der Name passt nach Normalisierung (Rechtsform, Schreibweise), der Ort ist plausibel. Bitte prüfen Sie den Treffer, bevor Sie darauf handeln. |
| ambiguous | Mehrere Firmen kommen infrage. Die Antwort enthält die Zahl der Kandidaten; ergänzen Sie den Ort oder die Registernummer. |
| none | Keine Meldung im Zeitraum. Das ist eine gute Nachricht, aber keine Bonitätsbewertung. |
Ein Aufruf nimmt bis zu 500 Einträge entgegen. since begrenzt die Suche auf Meldungen ab diesem Datum, der Standard sind drei Jahre zurück. Für grössere Portfolios empfehlen wir die Watchlist: einmal prüfen, danach nur noch Änderungen erhalten.
Watchlist
Die Watchlist macht aus einer einmaligen Prüfung eine laufende Überwachung. Sie fügen Firmen hinzu, und sobald zu einer davon eine neue Meldung erscheint, erhalten Sie per Webhook ein Ereignis watchlist.match.
curl https://konkursradar.ch/api/v1/watchlist \
-H "X-API-Key: $KONKURS_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "company_number": "CHE-123.456.789", "ref": "D-10023" }'
{
"id": "wl_Q7m2Lx9Pd",
"object": "watchlist_entry",
"ref": "D-10023",
"company_number": "CHE-123.456.789",
"name": "Beispiel Holzbau AG",
"created_at": "2026-09-29T08:12:44Z",
"last_match": null
}
Auch Firmen, die nie insolvent waren, lassen sich beobachten. Der Eintrag wartet dann auf die erste Meldung, genau darin liegt der Sinn. Ihre eigene Referenz in ref kommt in jedem Ereignis zurück, sodass Sie einen Treffer ohne zusätzliche Abfrage Ihrer Kundennummer zuordnen können.
GET /v1/watchlist listet alle Einträge mit dem Datum des letzten Treffers auf, DELETE /v1/watchlist/{id} entfernt einen. Dieselbe Watchlist sehen Sie in Ihrem KonkursRadar-Dashboard; Änderungen werden in beide Richtungen synchronisiert.
Webhooks
Statt abzufragen, können Sie sich Ereignisse zustellen lassen. Registrieren Sie einen HTTPS-Endpunkt und wählen Sie die Ereignisse, wahlweise mit einem Filter auf Verfahrenstypen und Kantone.
curl https://konkursradar.ch/api/v1/webhooks \
-H "X-API-Key: $KONKURS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/hooks/insolvency",
"events": ["watchlist.match", "filing.published"],
"filter": { "types": ["bankruptcy-opening"], "region": ["ZH", "BE"] }
}'
| Ereignis | Wann |
|---|---|
| filing.published | Eine neue Meldung passt zu Ihrem Filter. Trifft kurz nach dem täglichen Import ein, meist am Morgen. |
| watchlist.match | Eine neue Meldung betrifft eine Firma auf Ihrer Watchlist. |
| stats.daily_ready | Die Tageszahlen des Vortags sind vollständig. |
{
"id": "evt_5Tg8Nw2Ka",
"type": "watchlist.match",
"created_at": "2026-09-29T06:05:11Z",
"data": {
"watchlist_entry": { "id": "wl_Q7m2Lx9Pd", "ref": "D-10023" },
"filing": {
"date": "2026-09-28",
"type": "Konkurseröffnung",
"type_code": "KK01",
"name": "Beispiel Holzbau AG",
"court": "Konkursamt Winterthur",
"case_number": "KK01-0000312845",
"region": "ZH"
}
}
}
Jeder Aufruf ist signiert. Der Header X-Webhook-Signature enthält einen Zeitstempel und einen HMAC-SHA256 über Zeitstempel und rohen Body, berechnet mit dem Geheimnis, das Sie bei der Registrierung erhalten.
X-Webhook-Signature: t=1790661911,v1=7f2c1d9a4b6e8035c1f7a29d4e5b0c8371a6d2f94e8b3c07a15d9e2f6b4c8a01
import hashlib, hmac, os, time
from flask import Flask, request, abort
app = Flask(__name__)
SECRET = os.environ["WEBHOOK_SECRET"].encode()
@app.post("/hooks/insolvency")
def hook():
header = request.headers.get("X-Webhook-Signature", "")
parts = dict(p.split("=", 1) for p in header.split(",") if "=" in p)
signed = parts.get("t", "") + "." + request.get_data(as_text=True)
expected = hmac.new(SECRET, signed.encode(), hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, parts.get("v1", "")):
abort(400)
if abs(time.time() - int(parts["t"])) > 300:
abort(400) # replay protection
event = request.get_json()
if event["type"] == "watchlist.match":
ref = event["data"]["watchlist_entry"]["ref"]
print("Customer", ref, "has a new insolvency filing")
return "", 204
Antworten Sie innerhalb von zehn Sekunden mit einem 2xx-Status. Schlägt das fehl, versuchen wir es mit wachsenden Abständen über 24 Stunden erneut, insgesamt achtmal. Ereignisse können doppelt eintreffen, verwenden Sie deshalb die id des Ereignisses, um Duplikate zu verwerfen.
Statistiken
GET /v1/stats liefert Zahlen statt einzelner Meldungen. Das ist der Endpunkt für Dashboards, Berichte und Journalismus, denn Sie müssen nicht Tausende Zeilen herunterladen und selbst zählen.
curl -G -H "X-API-Key: $KONKURS_API_KEY" \
https://konkursradar.ch/api/v1/stats \
-d date_from=2026-07-01 -d date_to=2026-09-28 \
-d group_by=month,region -d types=bankruptcy-opening
{
"date_from": "2026-07-01",
"date_to": "2026-09-28",
"group_by": ["month", "region"],
"rows": [
{ "month": "2026-07", "region": "ZH", "count": 118 },
{ "month": "2026-07", "region": "BE", "count": 342 },
{ "month": "2026-08", "region": "ZH", "count": 104 }
],
"total": 3187
}
group_by akzeptiert day, week, month, region, type und industry, bis zu zwei gleichzeitig. types funktioniert wie bei /v1/filings. Anders als bei den Meldungen darf der Zeitraum bis zu 24 Monate umfassen.
Unsere Zahlen zählen Meldungen, nicht Verfahren. Sie liegen früher vor als die Jahreszahlen des Bundesamts für Statistik (BFS), sind mit diesen aber nicht identisch, weil das BFS eröffnete Verfahren zählt.
Referenzdaten
GET /v1/types liefert die Verfahrenstypen dieses Marktes genau wie in der Tabelle oben: Schlüssel, Bezeichnung, Codes und Aliase. GET /v1/regions liefert die gültigen Kantonswerte in der Schreibweise der Meldungen. Beides ändert sich selten und darf einen Tag lang zwischengespeichert werden.
GET /v1/account zeigt Ihren Vertragsumfang, die aktiven Limits und den Verbrauch im laufenden Monat.
Fehler
Fehler kommen als JSON mit passendem HTTP-Status zurück. Das Feld error ist maschinenlesbar und stabil, message erklärt das Problem für Menschen und kann sich ändern.
{
"error": "range_too_large",
"message": "Range exceeds the 31-day maximum per request."
}
| error | HTTP | Bedeutung |
|---|---|---|
| bad_date | 400 | Ein Datum hat nicht das Format YYYY-MM-DD. |
| bad_range | 400 | date_from liegt nach date_to. |
| range_too_large | 400 | Zeitraum länger als 31 Tage. |
| bad_format | 400 | format ist weder json noch csv. |
| bad_type | 400 | Unbekannter Wert in types. Die Antwort enthält zusätzlich allowed_types. |
| invalid_request | 400 | Anderer ungültiger Parameter oder fehlerhafter JSON-Body. |
| missing_api_key | 401 | Kein Schlüssel gesendet. |
| invalid_api_key | 403 | Schlüssel unbekannt, deaktiviert, für einen anderen Markt ausgestellt oder Abonnement abgelaufen. |
| insufficient_scope | 403 | Der Schlüssel ist für diesen Endpunkt nicht freigeschaltet. |
| not_found | 404 | Firma, Verfahrensführung oder Watchlist-Eintrag unbekannt. |
| rate_limited | 429 | Zu viele Anfragen, siehe Limits. |
| server_error | 500 | Fehler auf unserer Seite. Versuchen Sie es nach kurzer Wartezeit erneut und melden Sie uns, wenn er bestehen bleibt. |
| country_not_enabled | 501 | Die Daten-API ist für diesen Markt noch nicht freigeschaltet. |
{
"error": "bad_type",
"message": "Unknown filing type(s): konkurs.",
"allowed_types": ["bankruptcy-opening", "kk01", "konkurseroeffnung", "opening", "call-for-claims", "kk02", "schuldenruf", "..."]
}
{
"error": "country_not_enabled",
"message": "The data API is not available for Switzerland yet."
}
Limits
| Wert | Limit |
|---|---|
| 120 / min | Anfragen pro Minute und Schlüssel. Auf Anfrage höher. |
| 31 | Maximale Tage pro Anfrage auf /v1/filings, beide Enden inklusive. /v1/stats erlaubt 24 Monate. |
| 10000 | Maximale Zeilen pro Antwort auf /v1/filings. Darüber trägt die Antwort truncated: true. |
| 100 | Maximale Einträge pro Seite bei Listen-Endpunkten. |
| 500 | Maximale Einträge pro Aufruf auf /v1/check. |
| 10000 | Beobachtete Firmen pro Konto im Standardvertrag. |
| 5 | Registrierte Webhook-Endpunkte pro Konto. |
Die Antworten tragen den aktuellen Stand des Ratenlimits in ihren Headern. Überschreiten Sie es, erhalten Sie 429 rate_limited und einen Header Retry-After in Sekunden.
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 117
X-RateLimit-Reset: 1790661960
Retry-After: 12
Versionierung
Die Hauptversion ist Teil des Pfads (/v1/). Innerhalb einer Hauptversion nehmen wir nur additive Änderungen vor: neue Endpunkte, neue optionale Parameter, neue Felder in Antworten. Ihr Client sollte unbekannte Felder deshalb ignorieren, statt daran zu scheitern.
Änderungen, die bestehende Integrationen brechen könnten, gibt es nur in einer neuen Hauptversion. Die vorherige Version läuft dann mindestens zwölf Monate weiter, und wir informieren jede Schlüsselinhaberin und jeden Schlüsselinhaber vorher per E-Mail. Das Versionsdatum steht im Antwort-Header X-API-Version.
X-API-Version: 2026-09-01
Datenquellen und Aktualität
Einzige Quelle für die Meldungen ist das Schweizerische Handelsamtsblatt (SHAB), herausgegeben vom Staatssekretariat für Wirtschaft (SECO). Wir ergänzen keine Meldungen aus anderen Quellen und verändern deren Inhalt nicht. UIDs werden der Meldung entnommen und gegen das UID-Register geprüft.
Das SHAB erscheint an Werktagen. Neue Meldungen liefern wir in der Regel am nächsten Morgen aus. Das Feld date ist das jüngste datierte Ereignis der Meldung, das nicht in der Zukunft liegt, meist das Publikationsdatum.
Die Zuordnung von Meldungen zu Firmen ist automatisiert. Mit einer Registernummer ist sie zuverlässig; ohne (sehr häufige Namen, Einzelfirmen) sind Fehler möglich. Darum unterscheidet die Gegenparteiprüfung zwischen exact und probable.
Datenschutz und zulässige Nutzung
SHAB-Meldungen sind öffentlich, können aber Personendaten enthalten, vor allem bei Einzelfirmen. Ihre Verwendung unterliegt dem Schweizer Datenschutzgesetz (DSG) und, bei Kundinnen und Kunden in der EU, der DSGVO.
Bitte bilden Sie Berichtigungen und Löschungen in Ihren eigenen Systemen nach. Ein regelmässiger Abgleich über den Zeitraum, den Sie speichern, genügt: Was die API nicht mehr liefert, sollte auch nicht mehr in Ihrer Datenbank stehen.
Erlaubt sind Kreditrisiko, Forderungsmanagement, Lieferantenprüfung, Rechtsberatung, Forschung und Journalismus. Nicht erlaubt sind der Weiterverkauf der Rohdaten und automatisierte Entscheidungen über natürliche Personen, die sich allein auf diese Daten stützen. Ein Auftragsbearbeitungsvertrag ist auf Anfrage erhältlich.
Support
Fragen zur Integration, höheren Limits oder zusätzlichen Feldern: [email protected] oder das Kontaktformular. Bei technischen Problemen nennen Sie bitte den Zeitpunkt der Anfrage und die ersten Zeichen Ihres Schlüssels, dann finden wir die Anfrage sofort in den Logs.
Wenn Sie KI-Agenten anbinden möchten, statt HTTP-Clients zu schreiben: Dieselben Daten stehen über einen Model-Context-Protocol-Server bereit, dokumentiert unter MCP-Server. Beide teilen sich Schlüssel, Limits und Vertrag.
Zugang anfragen
Schlüssel vergeben wir von Hand. Schreiben Sie uns kurz, was Sie bauen möchten und mit welchem Volumen Sie rechnen, dann ist der Zugang in der Regel innert eines Werktags aktiv.