prospex
Se connecter

L'API REST Zefix: points d'accès, authentification, identifiants

12 min de lecture

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 API

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 à [email protected]. 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.

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.

Consulter la spécification 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 12 août 2026, la spécification indiquait la version 2.7.2.3 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.3 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 consultations d'entreprises renvoient 404 quand aucune fiche n'existe. Les routes IDE et CH-ID renvoient un tableau à un élément, tandis que la route EHRA-ID renvoie un objet. Normalisez la réponse avant de la 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

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


def format_uid(value: str) -> str:
    uid = value.strip().upper()
    if PRINTED_UID.fullmatch(uid):
        return uid
    if match := NORMALISED_UID.fullmatch(uid):
        return f"CHE-{match.group(1)}.{match.group(2)}.{match.group(3)}"
    raise ValueError(f"Invalid Swiss UID: {value!r}")


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

        if response.status_code == 404:
            return None
        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 isinstance(data, list) and data else data

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

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 imprimée.

Acceptez les deux formes à la frontière et convertissez la forme normalisée avant de construire le chemin de requête. La fonction format_uid ci-dessus valide l'entrée et lève une exception sur les identifiants mal formés avant tout appel à l'API.

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.

Quand garder l'EHRA-ID

  • 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 EHRA-ID tout en partageant l'IDE de son siège. Vérifiez comment les succursales apparaissent dans vos données 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.

La recherche par nom

/company/search est un POST qui prend un corps CompanySearchQuery. 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.

Pour le volume, passez par 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. Pour paginer, utilisez 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.

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.

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.

Préférences de cookies

Les cookies nécessaires fonctionnent toujours. Les deux autres sont actifs sauf si vous les désactivez.