Zefix-API: Zugang, alle Endpunkte und eine Abfrage ohne Login

Zefix fasst die Einträge aller 26 kantonalen Handelsregister in einem eidgenössischen Index zusammen. Bekannt ist Zefix vor allem durch die Firmensuche auf zefix.admin.ch. Über die REST-API können Sie Firmen anhand ihrer UID oder EHRA-ID abrufen oder nach Firmennamen suchen. Sie liefert auch Beziehungsdaten und tägliche Handelsregisterpublikationen. Der Zugang ist kostenlos. Die Zugangsdaten erhalten Sie auf Anfrage beim Bundesamt für Justiz.

Verwenden Sie REST für gezielte Abfragen und Beziehungsdaten. Für die Verarbeitung grosser Teile des Registers eignet sich der weiter unten beschriebene LINDAS-Datensatz.

Zefix-API-Zugangsdaten anfordern

Alle Endpunkte setzen HTTP-Basic-Authentifizierung voraus, in der OpenAPI-Spezifikation als Zefix-Credentials bezeichnet. Anfragen ohne Authorization-Header liefern 401, auch Firmenabfragen und Suchen.

Benutzername und Passwort erhalten Sie beim Bundesamt für Justiz über zefix@bj.admin.ch. Stellen Sie sich kurz vor und beschreiben Sie Ihr Vorhaben sowie die voraussichtliche Anzahl der Anfragen. Hinterlegen Sie Benutzername und Passwort beim Erstellen des HTTP-Clients für die HTTP-Basic-Authentifizierung.

Sobald die Zugangsdaten da sind, prüft eine einzige Anfrage, ob sie funktionieren:

curl -u "$ZEFIX_USER:$ZEFIX_PASSWORD" \
  https://www.zefix.admin.ch/ZefixPublicREST/api/v1/company/uid/CHE444420929

Die Antwort ist ein JSON-Array mit einer Firma, hier der Baumberger Bau AG in Koppigen. Bis die Zugangsdaten eintreffen, beantwortet der LINDAS-Datensatz dieselbe Abfrage ohne Login.

Die Dokumentation nennt kein Rate Limit. Wir halten von uns aus einen Mindestabstand von 0.5 Sekunden zwischen zwei Anfragen ein und wiederholen fehlgeschlagene Anfragen bei 429 und 5xx mit exponentiell wachsenden Wartezeiten (Backoff). Dieser Anfragerhythmus hat in unserem Produktivbetrieb keine Drosselung ausgelöst. Damit bleibt das Anfragevolumen moderat, solange kein offizielles Limit veröffentlicht ist.

Swagger und die OpenAPI-Spezifikation

Zefix veröffentlicht eine OpenAPI-3.1-Spezifikation für die REST-API. Die Spezifikation im JSON-Format und die Swagger-Oberfläche sind online verfügbar. Am 16. Oktober 2026 wies die Spezifikation API-Version 2.7.2.4 aus.

Prüfen Sie vor einer Anpassung Ihrer Anbindung die aktuellen Endpunkte und Feldnamen sowie die zulässigen Enum-Werte und Validierungsregeln.

Daneben gibt es eine Integrationsumgebung. Dort können Sie die Authentifizierung und das Format der Identifikatoren testen sowie erfolgreiche Antworten und die Fehlerbehandlung prüfen.

Basis-URL und Endpunkte

Die Basis-URL lautet https://www.zefix.admin.ch/ZefixPublicREST, die Endpunkte liegen unter /api/v1. Version 2.7.2.4 stellt diese zehn Endpunkte bereit:

PfadMethodeAntwort
/company/uid/{id}GETFirmendatensatz in einem Array mit einem Element
/company/ehraid/{id}GETFirmendatensatz als Objekt
/company/chid/{id}GETFirmendatensatz in einem Array mit einem Element
/company/searchPOSTGefundene Firmendatensätze
/legalFormGETRechtsformen mit ihren Codes
/registryOfCommerceGETDie kantonalen Registerämter
/registryOfCommerce/byBfsCommunityId/{id}GETDas für eine Gemeinde zuständige Amt
/communityGETPolitische Gemeinden mit BFS-Nummern
/sogc/{id}GETEine SHAB-Publikation
/sogc/bydate/{date}GETAlle SHAB-Publikationen eines Tages

Die UID- und CH-ID-Routen liefern ein Array mit einem Element; passt keine Firma, liefern sie ein leeres Array mit Status 200. Die EHRA-ID-Route liefert ein Objekt, bei einer unbekannten Nummer 404. Vereinheitlichen Sie beide Antwortformen vor der Weiterverarbeitung.

Eine vollständige UID-Abfrage

Das folgende Beispiel akzeptiert beide UID-Formate und vereinheitlicht sie. Bei vorübergehenden Fehlern wiederholt es die Anfrage und liest anschliessend den Firmendatensatz aus dem Array:

import re
import time

import httpx

UID = re.compile(r"CHE-?(\d{3})\.?(\d{3})\.?(\d{3})", re.IGNORECASE)


def normalise_uid(value: str) -> str:
    if match := UID.fullmatch(value.strip()):
        return "CHE" + "".join(match.groups())
    raise ValueError(f"Invalid Swiss UID: {value!r}")


def company_by_uid(client: httpx.Client, uid: str) -> dict | None:
    api_uid = normalise_uid(uid)
    for attempt in range(3):
        response = client.get(f"/company/uid/{api_uid}")

        if response.status_code == 429 or response.status_code >= 500:
            if attempt == 2:
                response.raise_for_status()
            time.sleep(2**attempt)
            continue

        response.raise_for_status()
        data = response.json()
        return data[0] if data else None

    raise RuntimeError("Unreachable")


with httpx.Client(
    base_url="https://www.zefix.admin.ch/ZefixPublicREST/api/v1",
    auth=httpx.BasicAuth(USERNAME, PASSWORD),
    headers={"Accept": "application/json"},
    timeout=30.0,
) as client:
    company = company_by_uid(client, "CHE444420929")

Diese Funktionen stehen auch in unserer Open-Source-Bibliothek zefix-parser zur Verfügung. Sie installieren sie mit pip install zefix-parser[http]. Die Bibliothek vereinheitlicht UID-Formate, wiederholt fehlgeschlagene Anfragen und liest Firmendatensätze aus den Arrays. Sie wandelt Antworten in typisierte Dataclasses um und liest auch den weiter unten beschriebenen LINDAS-Datensatz über dieselbe Schnittstelle. Ihre Parser lassen sich einzeln importieren, sodass bereits gespeicherte Antworten auch ohne die optionalen HTTP-Abhängigkeiten verarbeitet werden können. Die Dokumentation beschreibt beide Clients.

UID-Format für die Abfrage

Die Schweizer Unternehmens-Identifikationsnummer wird offiziell mit Trennzeichen geschrieben: CHE-444.420.929. In normalisierter Form lautet sie CHE444420929. SHAB-Publikationen verwenden die normalisierte Form, die auch häufig in internen Datensätzen gespeichert wird. Die Route /company/uid/{id} erwartet die normalisierte Form: Auf CHE-444.420.929 antwortet sie mit 200 und einer leeren Liste, genau wie auf eine UID, die es nicht gibt.

Im August 2026 akzeptierte die Route nur die Schreibweise mit Trennzeichen. Das erwartete Format kann sich also ohne Ankündigung ändern. Akzeptieren Sie beide Formen an der Schnittstelle und entfernen Sie die Trennzeichen, bevor Sie den Anfragepfad zusammensetzen. Die Funktion normalise_uid oben validiert die Eingabe und löst bei ungültigen Identifikatoren bereits vor dem API-Aufruf eine Exception aus. Kommt für eine UID, die sicher existiert, eine leere Antwort zurück, versuchen Sie die andere Form.

Antwortfelder einer Firmenabfrage

Angaben zu Identität, Status, Adresse und Kapital stehen auf der obersten Ebene der Antwort. Beziehungen wie Zweigniederlassungen und Übernahmen sind Arrays von Firmenverweisen. Wir verwenden die folgenden Zefix-Felder:

  • name, ehraid, uid, chid: Name und Identifikatoren der Firma.
  • legalSeat und legalSeatId, address, canton: Rechtssitz und Adresse der Firma.
  • status: ACTIVE, CANCELLED, BEING_CANCELLED. Filtern oder kennzeichnen Sie gelöschte Einträge, bevor Sie den Datensatz weiterverarbeiten.
  • capitalNominal und die zugehörige Währung. Lesen Sie den Wert über Decimal(str(value)) ein. Damit vermeiden Sie die Rundungsfehler von float.
  • deletionDate: gesetzt, wenn der Eintrag aus dem aktiven Register entfernt wurde.
  • cantonalExcerptWeb: die URL zum Auszug des kantonalen Registers, dem beglaubigten Dokument.
  • oldNames: frühere Namen mit einer Reihenfolgenummer zum Abgleich mit der Namenshistorie in Ihren eigenen Daten.
  • headOffices, furtherHeadOffices, branchOffices, hasTakenOver, wasTakenOverBy, auditCompanies: je eine Liste von Firmenverweisen mit Name, EHRA-ID und meistens einer UID.

Die Arrays mit Firmenbeziehungen erhalten Sie über REST. Speichern Sie die EHRA-ID jedes Verweises, damit er über /company/ehraid/{id} aufgelöst werden kann. Behandeln Sie wasTakenOverBy als Registerbeziehung. Prüfen Sie die zugehörige Publikation, bevor Sie das Ereignis als Übernahme einordnen.

Wie EHRA-ID und UID zusammenhängen

  • Die UID (uid) ist die Nummer, unter der eine Rechtseinheit in der gesamten Schweizer Verwaltung geführt wird: Steuern, Mehrwertsteuer, Zoll, Sozialversicherungen und Handelsregister greifen darauf zu. Sie ist öffentlich, steht auf Rechnungen und ist der übliche Join-Schlüssel zwischen Datensätzen.
  • Die EHRA-ID (ehraid) ist eine vom Eidgenössischen Amt für das Handelsregister vergebene Ganzzahl. Sie identifiziert einen einzelnen Registereintrag.

Die LINDAS-URIs von Unternehmen verwenden die EHRA-ID: https://register.ld.admin.ch/zefix/company/{EHRA-ID}. Auch die Arrays mit Firmenbeziehungen enthalten EHRA-IDs. Speichern Sie das Feld, wenn Sie Hauptsitz-, Zweigniederlassungs- oder Übernahmeverweise verfolgen wollen.

Eine Zweigniederlassung hat eine eigene UID und eine eigene EHRA-ID, und ihr Hauptsitz führt sie unter branchOffices. Eine UID kann trotzdem mehrere EHRA-IDs haben: Ein Unternehmen mit zwei Sitzen, etwa die Nestlé S.A. in Cham und Vevey, hat einen Eintrag pro Sitz. Prüfen Sie furtherHeadOffices, bevor Sie einen Datensatz pro UID erzwingen.

Die REST-Antwort liefert beide Identifikatoren. Speichern Sie beide, damit die Zuordnung beim Datenimport erhalten bleibt.

Suche nach Firmennamen: der company/search-Endpunkt

/company/search erwartet eine POST-Anfrage mit einem CompanySearchQuery-Objekt im Request-Body. Code für die ältere ZefixREST-API nennt dieselbe Suche firm/search; in PublicREST gibt es keine Route unter diesem Namen. Folgende Parameter stehen zur Verfügung:

FeldTypHinweise
nameStringPflichtfeld mit mindestens drei Zeichen. Sucht am Anfang des Namens; * dient als Platzhalter.
legalFormIdIntegerDie interne Rechtsform-ID, 1 bis 999.
legalFormUidStringDer öffentliche vierstellige Code aus eCH-0097.
registryOfCommerceIdIntegerID eines kantonalen Handelsregisteramts.
legalSeatIdIntegerBFS-Nummer einer Gemeinde.
cantonStringZweistelliges Kantonskürzel.
activeOnlyBooleanBeschränkt die Ergebnisse auf aktive Einträge.
response = client.post(
    "/company/search",
    json={"name": "Migros", "canton": "ZH", "activeOnly": True},
)
response.raise_for_status()
candidates = response.json()

Die Ortsfilter schliessen sich gegenseitig aus. Verwenden Sie pro Anfrage nur einen der Parameter registryOfCommerceId, legalSeatId oder canton.

Der Namensabgleich beginnt am Anfang des Firmennamens. Eine Suche nach Migros findet Migros Bank AG. Für Genossenschaft Migros Zürich braucht es einen vorangestellten Platzhalter. Der Endpunkt bietet keine Paginierung mit Offset, Limit oder Cursor. Grenzen Sie die Suche möglichst genau ein und filtern Sie die Treffer anschliessend lokal.

Prüfen Sie bei Treffern einer Namenssuche anhand von UID und Rechtssitz, ob es sich um die gesuchte Firma handelt. Kontrollieren Sie auch den Status, bevor Sie einen Datensatz übernehmen.

IDs den Rechtsformen, Gemeinden und Ämtern zuordnen

/legalForm, /registryOfCommerce und /community liefern kompakte Referenzlisten, die sich selten ändern. Mit diesen Listen können Sie die numerischen IDs in Firmen- und Suchantworten den jeweiligen Bezeichnungen zuordnen. Wir halten jede Liste einen Tag im Cache und lösen die IDs lokal auf. Ein Firmendatensatz enthält eine legalSeatId und eine Rechtsform-ID. In der Gemeindeliste finden Sie zur legalSeatId den Ortsnamen und Kanton. Die Rechtsformliste liefert zur zweiten ID die Bezeichnung, beispielsweise «Aktiengesellschaft», und den zugehörigen eCH-Code.

/registryOfCommerce/byBfsCommunityId/{id} zeigt, welches kantonale Amt die Einträge einer bestimmten Gemeinde führt. Diese Zuordnung brauchen Sie für den beglaubigten kantonalen Auszug.

Tägliche SHAB-Publikationen einlesen

/sogc/bydate/{date} erwartet ein Datum im Format 2026-08-12 und liefert jede Publikation des Schweizerischen Handelsamtsblatts dieses Tages, jeweils zusammen mit dem Kurzdatensatz der betroffenen Firma.

Eine Publikation enthält ihre sogcId, das publizierende kantonale Amt und dessen Kanton, Nummer und Datum des Tagesregisters, den formatierten message-Text und eine Liste von mutationTypes. mutationTypes ermöglicht es, Kapitalerhöhungen und Adressänderungen in einer Pipeline unterschiedlich zu verarbeiten, ohne den juristischen Text zu parsen. /sogc/{id} ruft eine Publikation anhand ihrer Nummer ab, wenn Sie die ID gespeichert haben und sie erneut lesen wollen.

Um Änderungen laufend zu erfassen, fragen Sie die Route einmal pro Kalendertag ab und speichern das Datum des zuletzt vollständig verarbeiteten Tages. Deduplizieren Sie Publikationen über die sogcId. Holen Sie nach einem Ausfall die fehlenden Tage nach. Speichern Sie auch Tage ohne Publikationen als abgeschlossen.

So entsteht ein Protokoll der im SHAB veröffentlichten Registerereignisse. Das ist effizienter, als jeden Firmendatensatz auf Änderungen hin abzufragen.

Ohne Zugangsdaten oder für grosse Datenmengen: LINDAS

REST eignet sich für gezielte Abfragen zu einer Firma, einem Identifikator oder einem Datum sowie für die Beziehungsfelder von Zefix. Mit LINDAS können Sie grosse Teile des Registers verarbeiten. Der SPARQL-Datensatz enthält wie die REST-API Identitäts- und Adressfelder sowie zusätzlich den Zweckartikel. Der Entitätstyp heisst admin:ZefixOrganisation, und jede Entität hat einen stabilen URI der Form https://register.ld.admin.ch/zefix/company/{EHRA-ID}.

Die oben aufgeführten Arrays mit Firmenbeziehungen sind über die REST-API verfügbar. Bei der Verarbeitung grosser Datenmengen können Sie die Firmendaten aus LINDAS beziehen und bei Bedarf die Beziehungen über REST ergänzen.

Fragen Sie die Daten unter https://ld.admin.ch/query per SPARQL ab. Der Endpunkt braucht kein Konto und überbrückt damit auch die Wartezeit, bis die Zefix-Zugangsdaten eintreffen. Diese Abfrage entspricht der UID-Abfrage aus dem REST-Beispiel:

PREFIX schema: <http://schema.org/>
PREFIX admin: <https://schema.ld.admin.ch/>

SELECT ?company ?name ?locality WHERE {
  ?company a admin:ZefixOrganisation ;
           schema:legalName ?name ;
           schema:identifier ?id .
  ?id schema:name "CompanyUID" ;
      schema:value "CHE444420929" .
  OPTIONAL { ?company schema:address/schema:addressLocality ?locality . }
}

Speichern Sie sie als uid.rq und senden Sie sie mit curl -H "Accept: text/csv" --data-urlencode query@uid.rq https://ld.admin.ch/query. Die Antwort ist eine Kopfzeile und eine CSV-Zeile: der Firmen-URI mit der EHRA-ID 1702823, Baumberger Bau AG, Koppigen.

Um das ganze Register zu verarbeiten, paginieren Sie per Keyset über den URI statt mit OFFSET. Rufen Sie die Daten in Blöcken ab und berücksichtigen Sie dabei jeweils nur URIs, die in der Sortierreihenfolge nach dem zuletzt verarbeiteten URI liegen. Eine leere Seite beendet den Lauf.

Für einen KI-Assistenten stellt unser Open-Source-MCP-Server swissco dieselben Daten bereit: LINDAS und das SHAB als schreibgeschützte Tools für UID-Abfrage, Namenssuche und Publikationen. Auch er braucht keine Zugangsdaten. In Claude Code genügt claude mcp add swissco -- uvx swissco-mcp.

Grenzen der API

Firmenabfragen beschreiben den aktuellen Registerzustand. Um Änderungen einzelner Felder nachzuvollziehen, müssen Sie regelmässig Momentaufnahmen speichern. Die API bietet dafür keinen modifiedSince-Filter oder Webhook.

Für veröffentlichte Registerereignisse lesen Sie /sogc/bydate/{date} täglich ein. Das erspart es, das ganze Register abzufragen, um eine kleine Zahl von Änderungen zu finden. Der Leitfaden zur SHAB-API beschreibt die eigene API des Amtsblatts. Zuschläge der öffentlichen Beschaffung verweisen auf das Anbieterprofil auf simap.ch, und dieses enthält meist die UID, über die sich der Zuschlag mit einem Zefix-Eintrag verknüpfen lässt; wie Sie sie abrufen, zeigt der Leitfaden zur SIMAP-Schnittstelle.

Zefix liefert Angaben zu Firmenidentität, Status, Adresse, Kapital und Registerbeziehungen. Einstellungsaktivität, Website-Änderungen, Marken und Presseberichterstattung kommen aus anderen Quellen. Schweizer Unternehmensdaten: Quellen und ihre Grenzen stellt diese Datenquellen vor.

Geschrieben von

Semion Sidorenko

Semion Sidorenko ist Gründer und CEO von Prospex. Von Data Engineering bis zur Machine-Learning-Forschung hat er fünfzehn Jahre damit verbracht, Unternehmen beim Ausbau ihrer Datenplattformen zu helfen. Vor der Gründung von Prospex arbeitete er als Machine-Learning-Ingenieur an der EPFL und als unabhängiger Data Engineering Consultant für Schweizer Unternehmen.

LinkedInGitHubsemion.sidorenko.ch