API Zefix: identifiants, points d'accès et alternative sans compte

Zefix rassemble les fiches des 26 registres cantonaux du commerce en un index fédéral. La plupart des gens le rencontrent sous la forme d'un champ de recherche sur zefix.admin.ch. Son API REST permet de consulter des entreprises par IDE ou EHRA-ID et de lancer des recherches par nom. Elle expose aussi les données de relations et les publications quotidiennes du registre du commerce. L'accès est gratuit, mais l'Office fédéral de la justice doit d'abord délivrer des identifiants.

Utilisez REST pour des consultations ciblées et les données de relations. Pour un parcours en masse du registre, utilisez le jeu de données LINDAS décrit plus bas.

Obtenir les identifiants de l'API Zefix

Chaque point d'accès exige une authentification HTTP Basic, nommée Zefix-Credentials dans la spécification OpenAPI. Les requêtes sans en-tête Authorization renvoient 401, y compris les consultations d'entreprises et les recherches.

Le nom d'utilisateur et le mot de passe se demandent à l'Office fédéral de la justice en écrivant à zefix@bj.admin.ch. Présentez votre organisation et votre projet. Indiquez aussi le volume prévu. Utilisez le nom d'utilisateur et le mot de passe comme identifiants HTTP Basic. Configurez-les une fois lors de la construction du client HTTP.

Dès réception des identifiants, une seule requête confirme qu'ils fonctionnent:

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

La réponse est un tableau JSON contenant une entreprise, ici Baumberger Bau AG à Koppigen. En attendant les identifiants, le jeu de données LINDAS répond à la même consultation sans compte.

La documentation n'annonce aucune limite de débit. Nous nous imposons un intervalle minimal de 0,5 seconde entre deux requêtes et réessayons les réponses 429 et 5xx avec un recul exponentiel. Ce rythme n'a pas déclenché de limitation dans notre usage en production. Il maintient aussi un trafic raisonnable dans ce cadre.

La spécification Swagger / OpenAPI

Zefix publie une spécification OpenAPI 3.1 pour l'API REST. La spécification brute et l'interface Swagger sont disponibles en ligne. Au 16 octobre 2026, la spécification indiquait la version 2.7.2.4 de l'API.

Consultez-la pour les points d'accès et noms de champs à jour. Vérifiez les valeurs d'énumération et les règles de validation avant de mettre à jour une intégration.

Il existe aussi un environnement d'intégration. Utilisez-le pour tester l'authentification et le formatage des identifiants. Vérifiez-y aussi les réponses valides et la gestion des erreurs.

URL de base et points d'accès

Le serveur est https://www.zefix.admin.ch/ZefixPublicREST et les opérations vivent sous /api/v1. La version 2.7.2.4 publie ces dix opérations:

CheminMéthodeRéponse
/company/uid/{id}GETFiche entreprise dans un tableau à un élément
/company/ehraid/{id}GETFiche entreprise en objet
/company/chid/{id}GETFiche entreprise dans un tableau à un élément
/company/searchPOSTFiches de résultats de recherche
/legalFormGETLes formes juridiques et leurs codes
/registryOfCommerceGETLes offices cantonaux du registre
/registryOfCommerce/byBfsCommunityId/{id}GETL'office qui couvre une commune
/communityGETLes communes politiques et leurs numéros OFS
/sogc/{id}GETUne publication de la Feuille officielle
/sogc/bydate/{date}GETToutes les publications d'un jour

Les routes IDE et CH-ID renvoient un tableau à un élément, et un tableau vide avec le statut 200 quand aucune entreprise ne correspond. La route EHRA-ID renvoie un objet, et 404 pour un numéro inconnu. Normalisez les deux formes de réponse avant de les transmettre en aval.

Consultation complète par IDE

L'exemple suivant accepte un IDE dans les deux formats et le normalise. Il réessaie en cas d'erreur transitoire et déplie le tableau à un élément:

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")

Nous publions ce même traitement sous forme de bibliothèque open source, zefix-parser. Installez-la avec pip install zefix-parser[http]. Elle couvre la normalisation de l'IDE, la politique de réessai et le déballage du tableau à un seul élément, convertit les réponses en dataclasses typées et lit le jeu de données LINDAS décrit plus bas par la même interface. Ses parseurs s'importent seuls, donc les réponses que vous avez déjà stockées se traitent sans l'extra HTTP. La documentation décrit les deux clients.

Formater les IDE pour la consultation

Le numéro suisse d'identification des entreprises a une forme imprimée canonique, CHE-444.420.929, et une forme normalisée compacte, CHE444420929. Les publications FOSC et les bases de données internes utilisent souvent la forme normalisée. La route /company/uid/{id} attend la forme normalisée: interrogée avec CHE-444.420.929, elle répond 200 avec une liste vide, comme pour un IDE qui n'existe pas.

En août 2026, la route n'acceptait que la forme imprimée: le format attendu peut donc changer sans préavis. Acceptez les deux formes à la frontière et retirez la ponctuation avant de construire le chemin de requête. La fonction normalise_uid ci-dessus valide l'entrée et lève une exception sur les identifiants mal formés avant tout appel à l'API. Si un IDE dont vous savez qu'il existe renvoie une réponse vide, essayez l'autre forme.

Champs de la réponse entreprise

Identité, statut, adresse et capital sont des champs de premier niveau. Les relations comme les succursales et les reprises sont des tableaux de références. Voici les champs que nous lisons sous les noms utilisés par Zefix:

  • name, ehraid, uid, chid: l'identité.
  • legalSeat et legalSeatId, address, canton: où elle siège.
  • status: ACTIVE, CANCELLED, BEING_CANCELLED. Filtrez ou étiquetez les entités radiées avant de transmettre la fiche en aval.
  • capitalNominal et sa monnaie. À analyser via Decimal(str(value)), jamais via float.
  • deletionDate: rempli quand l'entité a été retirée du registre actif.
  • cantonalExcerptWeb: l'URL de l'extrait du registre cantonal, qui est le document authentique.
  • oldNames: les noms précédents avec un numéro d'ordre, ce qui permet le rapprochement d'historique de noms dans vos propres données.
  • headOffices, furtherHeadOffices, branchOffices, hasTakenOver, wasTakenOverBy, auditCompanies: chacun une liste de références portant un nom, un EHRA-ID et le plus souvent un IDE.

Les tableaux de relations justifient le choix de REST pour ce type de consultation. Conservez l'EHRA-ID de chaque référence pour pouvoir la résoudre via /company/ehraid/{id}. Traitez wasTakenOverBy comme une relation de registre. Vérifiez la publication associée avant de qualifier l'événement d'acquisition.

L'EHRA-ID et son lien avec l'IDE

  • L'IDE (uid) est le numéro que toute l'administration suisse emploie pour une entité juridique: impôts, TVA, douane, assurances sociales et registre du commerce s'y réfèrent. Il est public, imprimé sur les factures, et sert de clé de jointure habituelle entre jeux de données.
  • L'EHRA-ID (ehraid) est le numéro de ligne du registre lui-même, un entier attribué par l'office fédéral du registre du commerce. Il identifie une inscription au registre.

Les URI LINDAS des entreprises utilisent l'EHRA-ID: https://register.ld.admin.ch/zefix/company/{EHRA-ID}. Les tableaux de relations de Zefix portent aussi des EHRA-ID. Conservez le champ si vous prévoyez de suivre les références de siège, de succursale ou de reprise.

Une succursale a son propre IDE et son propre EHRA-ID, et son siège la liste sous branchOffices. Un IDE peut malgré tout porter plusieurs EHRA-ID: une société inscrite à deux sièges, comme Nestlé S.A. à Cham et à Vevey, a une inscription par siège. Vérifiez furtherHeadOffices avant d'imposer une ligne par IDE.

Stockez les deux. La réponse REST fournit les deux identifiants et peut alimenter la correspondance lors de l'ingestion.

Recherche par nom: le point d'accès company/search

/company/search est un POST qui prend un corps CompanySearchQuery. Le code écrit pour l'ancienne API ZefixREST appelle cette recherche firm/search; PublicREST n'a aucune route de ce nom. Le jeu complet de paramètres:

ChampTypeRemarques
namechaîneObligatoire, trois caractères au minimum. Correspond au début du nom, et * sert de joker.
legalFormIdentierL'identifiant interne de forme juridique, de 1 à 999.
legalFormUidchaîneLe code public à quatre caractères d'eCH-0097.
registryOfCommerceIdentierUn office cantonal.
legalSeatIdentierUne commune, par son numéro OFS.
cantonchaîneL'abréviation à deux lettres.
activeOnlybooléenRestreint les résultats aux inscriptions actives.
response = client.post(
    "/company/search",
    json={"name": "Migros", "canton": "ZH", "activeOnly": True},
)
response.raise_for_status()
candidates = response.json()

Les filtres de localisation s'excluent mutuellement. Renseignez un seul filtre de localisation dans chaque requête.

La correspondance de nom commence au début du nom de l'entreprise. Une recherche sur Migros trouve Migros Bank AG. Pour inclure Genossenschaft Migros Zürich, ajoutez un joker en tête. Le point d'accès renvoie tous les résultats dans une seule réponse. Gardez la requête précise et filtrez les candidats renvoyés en local.

Une recherche par nom fournit une liste de candidats à valider. Comparez l'IDE et le siège juridique. Vérifiez ensuite le statut avant de retenir une fiche.

Résoudre formes juridiques, communes et registres

/legalForm, /registryOfCommerce et /community renvoient des listes de référence compactes qui changent rarement. Elles permettent de rendre lisibles les identifiants numériques des réponses entreprise et recherche. Nous gardons chaque liste en cache pour la journée et résolvons les identifiants en local. Une fiche d'entreprise vous donne un legalSeatId et un identifiant de forme juridique. Vous obtenez le nom de lieu et son canton dans la liste des communes, puis la forme juridique et son code eCH dans la liste correspondante.

/registryOfCommerce/byBfsCommunityId/{id} répond à la question de savoir quel office cantonal détient les inscriptions d'une commune donnée, ce qui compte dès que vous voulez l'extrait cantonal authentique.

Intégrer les publications FOSC quotidiennes

/sogc/bydate/{date} prend une date 2026-08-12 et renvoie toutes les publications de la Feuille officielle suisse du commerce de ce jour-là, chacune accompagnée de la fiche courte de l'entreprise concernée.

Une publication porte son sogcId, l'office cantonal qui l'a publiée et son canton, le numéro et la date du journal quotidien, le texte formaté message, et une liste de mutationTypes. La liste structurée mutationTypes indique directement le type de mutation au pipeline. Il peut ainsi appliquer des traitements distincts à une augmentation de capital et à un changement d'adresse à partir des codes fournis. /sogc/{id} permet de retrouver une publication par son numéro quand vous avez stocké l'identifiant et voulez la relire.

Pour suivre les changements, interrogez la route une fois par date calendaire et stockez la dernière date traitée. Dédupliquez les publications par sogcId. Rejouez les dates manquées après une panne, et laissez les jours sans publication avancer le point de contrôle.

Vous obtenez ainsi un journal des événements du registre publiés dans la FOSC, avec une requête par jour.

Sans identifiants ou pour les gros volumes: LINDAS

Utilisez REST quand vous partez d'une entreprise, d'un identifiant ou d'une date, ou quand vous avez besoin des champs de relations de Zefix. Utilisez LINDAS quand vous devez parcourir une grande partie du registre. Son jeu de données SPARQL recouvre les champs d'identité et d'adresse de l'API REST et inclut aussi le texte du but social. Le type d'entité est admin:ZefixOrganisation et chaque entité a un URI stable de la forme https://register.ld.admin.ch/zefix/company/{EHRA-ID}.

Pour les tableaux de relations listés ci-dessus, la source reste REST. Un pipeline en masse peut collecter sa population de base sur LINDAS, puis enrichir par REST les entreprises pour lesquelles ces relations sont nécessaires.

Interrogez les données à https://ld.admin.ch/query en SPARQL. Le point d'accès ne demande aucun compte, ce qui permet aussi de travailler pendant l'attente des identifiants Zefix. Cette requête reprend la consultation par IDE de l'exemple REST:

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 . }
}

Enregistrez-la sous uid.rq et envoyez-la avec curl -H "Accept: text/csv" --data-urlencode query@uid.rq https://ld.admin.ch/query. La réponse tient en un en-tête et une ligne CSV: l'URI de l'entreprise terminé par l'EHRA-ID 1702823, Baumberger Bau AG, Koppigen.

Pour parcourir tout le registre, paginez avec la clé de l'URI: sélectionnez les URI supérieurs au dernier traité, récupérez les champs de ce lot, et arrêtez quand une page revient vide.

Pour donner à un assistant IA accès aux mêmes données, notre serveur MCP swissco, open source, expose LINDAS et la FOSC sous forme d'outils en lecture seule: consultation par IDE, recherche par nom et publications. Il ne demande pas d'identifiants non plus. Dans Claude Code, claude mcp add swissco -- uvx swissco-mcp suffit à l'enregistrer.

Limites de l'API

Les consultations d'entreprises décrivent l'état actuel du registre. Pour obtenir un historique au niveau des champs, créez vos propres instantanés. Les mécanismes incrémentaux comme un filtre modifiedSince ou un webhook sont absents de l'API.

Pour les événements publiés du registre, intégrez /sogc/bydate/{date} chaque jour. Cela évite d'interroger tout le registre pour trouver un petit nombre de changements. La Feuille officielle a d'ailleurs sa propre API, sujet du guide de l'API FOSC. Les adjudications de marchés publics renvoient au profil du soumissionnaire sur simap.ch, qui porte le plus souvent son IDE et permet de relier l'adjudication à une fiche Zefix; le guide de l'API simap.ch montre comment les lire.

Zefix couvre l'identité, le statut, l'adresse, le capital et les relations de registre d'une entreprise. Les données sur le recrutement, les changements de site web, les marques et la couverture de presse viennent d'autres sources. Où trouver les données d'entreprises suisses cartographie ces jeux de données.

Écrit par

Semion Sidorenko

Semion Sidorenko est le fondateur et CEO de Prospex. De l'ingénierie des données à la recherche en apprentissage automatique, il a passé quinze ans à aider des entreprises à faire grandir leurs plateformes de données. Avant de fonder Prospex, il a été ingénieur en apprentissage automatique à l'EPFL et consultant indépendant en ingénierie des données pour des entreprises suisses.

LinkedInGitHubsemion.sidorenko.ch