L'annuaire national
L'annuaire national est le référentiel de la réforme, tenu par le PPF (Portail Public de Facturation) opéré par l'AIFE (Agence pour l'informatique financière de l'État) : il associe chaque SIREN ou SIRET français à la plateforme qui reçoit ses factures électroniques. Tant qu'une entreprise n'y est pas inscrite avec Scribee comme plateforme de réception, ses factures ne peuvent pas lui être adressées par la réforme. Cette page couvre les deux faces de l'annuaire : consulter l'adressage de n'importe quelle entreprise française avant de la facturer, et inscrire, modifier ou masquer les lignes d'annuaire de vos propres entreprises.
Ce que Scribee fait pour vous
- Renseigne les champs réglementaires de chaque ligne : le SIREN (celui de la fiche entreprise), la plateforme de réception (l'immatriculation de Scribee) et le qualifiant du code de routage. Vous ne fournissez que la maille d'adressage et les dates d'effet.
- Contrôle la forme de votre demande avant transmission - champs obligatoires, dates à J+1, cohérence interne - et refuse en
422immédiat ce qu'il peut décider seul. Les règles de l'annuaire lui-même restent arbitrées par le PPF : un202ne préjuge pas de leur respect, et un rejet différé reste possible. - Ordonne les demandes quand une ligne référence un code de routage nouveau : l'annuaire exige que le code soit inscrit avant la ligne, Scribee soumet les deux dans cet ordre.
- Publie en parallèle l'adressage inscrit sur le réseau Peppol, sans appel supplémentaire de votre part.
- Sert vos consultations depuis la copie de l'annuaire que Scribee maintient : la lecture répond immédiatement, sans dépendre de la disponibilité du PPF à chaque requête.
Des écritures asynchrones par conception
L'annuaire national est un registre externe : Scribee ne peut pas y écrire de façon synchrone. Chaque écriture (POST, PATCH, DELETE) répond donc 202 Accepted avec un change_request_id - la demande est enregistrée localement et mise en file, ni transmise ni appliquée au moment de la réponse. Vous observez le résultat en relistant les lignes de l'entreprise : la ligne créée ou modifiée y apparaît une fois la demande traitée.
Types d'événement et statuts
Chaque ligne porte un type d'événement (event_kind), fixé à la création et immuable ensuite :
event_kind | Libellé | Origine |
|---|---|---|
regular | Régulier | Une inscription (POST) crée toujours une ligne de ce type |
masking | Masquage | Résulte d'une demande de masquage (DELETE, étape 5) |
Le statut d'inscription d'une ligne se lit dans ses dates d'effet - la date de fin est exclusive, une ligne cesse d'être en vigueur le jour même de sa effective_to_on :
| Statut | Libellé | Condition |
|---|---|---|
upcoming | À venir | effective_from_on est postérieure à aujourd'hui |
in_force | En vigueur | effective_from_on est atteinte et effective_to_on est absente ou future |
ended | Terminée | effective_to_on est aujourd'hui ou passée |
Étape 1 : consulter l'annuaire avant d'émettre
Cet appel est une lecture : il ne crée rien et ne transmet rien vers l'extérieur - le scope read suffit. Il retourne les lignes d'annuaire en vigueur à la date du jour pour un SIREN ou un SIRET - exactement un des deux paramètres, jamais les deux.
curl "https://app.scribee.tech/api/v1/workspaces/YOUR_WORKSPACE_ID/france/pid/directory_lookups?siret=12345678900012" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
{
"data": [
{
"directory_identifier": "FR000000001",
"peppol_addressing_value": "FR000000001",
"siren": "123456789",
"siret": "12345678900012",
"suffix_code": null,
"routing_code_identifier": null,
"routing_code_qualifier": null,
"nature_label": "D",
"disclosure_status": "Diffusible",
"directory_line_status": "Enabled",
"sales_prospecting_forbidden": false
}
],
"meta": {
"current_page": 1,
"per_page": 20,
"total_pages": 1,
"total_count": 1
}
}
Ces onze champs constituent la réponse pour tout appelant.
peppol_addressing_value est l'adresse à laquelle la ligne achemine réellement, et c'est celle qu'il faut retenir pour adresser un document. Elle vaut directory_identifier quand l'annuaire en a attribué un ; sinon elle est composée à partir de la maille de la ligne (SIREN, SIREN_SUFFIXE, SIREN_SIRET ou SIREN_SIRET_CODEROUTAGE). La distinction compte : directory_identifier est légitimement null sur une ligne dont l'annuaire compose l'adresse, si bien qu'un appelant qui ne lit que ce champ conclut « pas d'adresse » pour un destinataire parfaitement joignable. peppol_addressing_value porte donc une adresse là où directory_identifier est vide. Il vaut lui-même null dans un seul cas, et c'est délibéré : quand la ligne ne résout vers aucune adresse exploitable. directory_identifier n'est validé nulle part - l'import écrit ce que le PPF envoie - donc il peut porter un texte qui n'est pas un identifiant Peppol. Plutôt que de publier une adresse vers laquelle rien ne peut acheminer, et que vous enregistreriez pour voir ensuite le dépôt refusé, ce champ vaut alors null. Traitez null comme « cette ligne n'est pas adressable », pas comme « champ absent ».
C'est la valeur à écrire dans directory_routing_identifier sur la fiche client ou sur la facture (voir Cycle de vie). directory_identifier reste inchangé et continue de porter exactement ce qu'il portait : le champ n'est pas remplacé, il est complété. nature_label porte ici le code réglementaire Annexe 3 DT-7-2, "D" (Définition, une ligne à laquelle une facture peut être adressée) : la consultation ne retournant que des lignes de type regular, l'autre valeur "M" (Masquage) ne s'y présente pas. Ce champ ne porte pas la même valeur qu'à l'étape 3, où il restitue la maille d'adressage de la ligne ; ici, la maille se lit sur siret, suffix_code et routing_code_identifier, jamais sur nature_label. disclosure_status vaut le plus souvent "Diffusible", "Partiellement diffusible", "Refus de prospection" ou null : Scribee le dérive de sa copie locale de l'unité légale ou de l'établissement du destinataire, et retourne null quand cette copie est absente ou ne porte pas l'information. La liste n'est pas close : une valeur non vide que Scribee ne sait pas traduire est retournée telle quelle, plutôt que remplacée par null. Traitez le champ comme une chaîne libre destinée à l'affichage, avec un cas null et un cas par défaut. La liste est paginée (page, per_page) et se filtre par routing_code_identifier quand le destinataire route ses factures par service.
directory_line_status restitue le statut réglementaire de la ligne (AFNOR XP Z12-013 §6.2.2) à la date as_of (aujourd'hui par défaut) pour tout appelant, à une exception près : pour une Plateforme Agréée utilisant include_history (détaillé plus bas), as_of n'entre pas dans ce calcul, qui reste toujours ancré sur la date du jour. Il vaut "Enabled" (en vigueur et pas sur le matricule par défaut du PPF), "Disabled" (en vigueur mais toujours sur le matricule par défaut du PPF, faute de plateforme de réception assignée), ou null quand la fin d'effet confirmée de la ligne - le plus tôt entre effective_to_on et effective_to_confirmed_on, ce dernier détaillé plus bas - est atteinte ou dépassée à cette date. La valeur "Upcoming" (pas encore en vigueur) n'existe que pour une Plateforme Agréée utilisant le paramètre include_history : sans lui, la consultation ne retourne jamais de ligne à venir, quel que soit l'appelant, et directory_line_status ne peut donc pas valoir "Upcoming" non plus. Réservés au même cas Plateforme Agréée avec include_history, deux autres null sont possibles : la ligne à venir est encore sur le matricule par défaut du PPF - une combinaison que le référentiel ne code pas - ou la ligne remontée est déjà terminée, le même calcul que le premier cas null mais rendu visible ici parce que include_history lève la fenêtre de dates qui l'aurait normalement exclue de la réponse. Le champ lui-même est renvoyé à tout appelant.
sales_prospecting_forbidden (XP Z12-013 §6.2.3) est un booléen dérivé de disclosure_status : true quand celui-ci vaut "Refus de prospection", false dans tous les autres cas, y compris quand disclosure_status est null. Renvoyé à tout appelant.
Les intégrateurs opérant en marque blanche comme Plateforme Agréée reçoivent six champs supplémentaires, portant leur réponse à dix-sept champs - platform_registry_number, platform_registry_qualifier, effective_from_on, effective_to_on, effective_to_confirmed_on et instance_number. effective_to_confirmed_on (DT-7-3-3, la date de fin effective au sens du PPF) peut être antérieure à effective_to_on ; c'est la plus proche des deux qui fait basculer directory_line_status à null (voir plus haut). Ces intégrateurs disposent aussi du paramètre include_history, qui leur est réservé : il lève la fenêtre de dates de la consultation et retourne les lignes quelles que soient leurs dates d'effet, sans lever les deux autres filtres - les lignes masquées et les lignes de type masking restent exclues dans tous les cas.
as_of déplace la fenêtre de consultation à une autre date - la réponse reste les lignes en vigueur à cette date-là, ce n'est pas un historique. Il est honoré pour tout appelant, sauf une Plateforme Agréée utilisant include_history (voir plus haut) : pour elle, as_of n'est pas pris en compte du tout, y compris pour une valeur invalide, et la consultation répond 200 comme si le paramètre n'avait pas été fourni. En dehors de ce cas, une valeur invalide (format non ISO 8601, date inexistante, ou année hors des bornes de la colonne DATE de la base) est traitée différemment selon votre statut : un appelant standard reçoit un repli silencieux sur la date du jour, la consultation répond 200 comme si as_of n'avait pas été fourni ; une Plateforme Agréée sans include_history reçoit un 422 (voir Erreurs et cas limites), parce que pour elle as_of doit être honoré et une valeur invalide ne peut pas être silencieusement ignorée.
Une réponse data vide signifie qu'aucune ligne en vigueur ne correspond aux filtres fournis - l'identifiant recherché, mais aussi le routing_code_identifier quand vous en envoyez un : l'entité peut exister sans porter ce code de routage. Ce n'est pas la même chose que « l'entreprise n'a aucune ligne » : une recherche par SIRET ne remonte pas une entrée enregistrée au seul SIREN, qui couvre pourtant l'entité légale entière. Relancez la recherche sur le SIREN avant de conclure.
Étape 2 : inscrire une entreprise dans l'annuaire
Cet appel enregistre une demande d'inscription et la transmet à l'annuaire national : la ligne qui en résulte est visible de toutes les plateformes de la réforme. Tant qu'elle est À venir, elle se masque avec le DELETE de l'étape 5 ; une fois En vigueur, elle se clôt en fixant sa date de fin (étape 4). L'entreprise est une fiche de votre workspace (Entreprises et établissements) et doit disposer d'un mandat actif.
curl -X POST https://app.scribee.tech/api/v1/companies/YOUR_COMPANY_ID/france/pid/entries \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"entry": {
"siret": "12345678900012",
"effective_from_on": "2026-09-01"
}
}'
{
"data": {
"change_request_id": 99
}
}
Réponse 202 : la demande est enregistrée, pas encore appliquée - relistez les lignes (étape 3) pour observer le résultat. effective_from_on doit être au moins J+1. La maille d'adressage se choisit par les champs fournis : rien (la ligne porte le SIREN seul), siret (un établissement), suffix_code avec le SIREN seul, ou siret plus routing_code_identifier pour router par service. La maille retenue fixe le nature_label de la ligne créée, que l'étape 3 restitue : "Etablissement" dès qu'un siret est fourni, "Suffixe" pour une ligne portant un suffix_code sans siret, et "Unite legale" pour une ligne au SIREN seul. Le SIREN lui-même et la plateforme de réception ne se fournissent pas : Scribee les fixe depuis la fiche entreprise et sa propre immatriculation.
Étape 3 : suivre la demande et lire les lignes
GET /api/v1/companies/{company_id}/france/pid/entries liste les lignes de l'entreprise, de la plus récente à la plus ancienne (sort_by : created_at, effective_from_on ou effective_to_on ; sort_order : asc ou desc).
curl https://app.scribee.tech/api/v1/companies/YOUR_COMPANY_ID/france/pid/entries \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Réponse abrégée aux champs utiles ici :
{
"data": [
{
"id": 512,
"siren": "123456789",
"siret": "12345678900012",
"routing_code_identifier": null,
"event_kind": "regular",
"effective_from_on": "2026-09-01",
"effective_to_on": null,
"directory_identifier": "FR000000001",
"masked": false
}
],
"meta": {
"current_page": 1,
"per_page": 20,
"total_pages": 1,
"total_count": 1
}
}
La ligne issue de l'étape 2 apparaît ici une fois la demande traitée par l'annuaire. Une ligne se lit aussi à l'unité, sans passer par l'entreprise : GET /api/v1/france/pid/entries/{id} - ce chemin sert notamment à relire une ligne masquée, que la liste n'affiche plus.
Étape 4 : modifier une ligne
Cet appel enregistre une demande de modification et la transmet à l'annuaire national ; la réponse est un 202 avec change_request_id, comme à l'étape 2. Il ne porte que sur la date de fin de validité de la ligne : fixez effective_to_on (au moins J+1, la date de fin est exclusive) pour mettre fin à une ligne En vigueur, ou envoyez-la à null pour l'effacer - Scribee transmet alors une dateFinEffet explicitement nulle à l'annuaire, et la date de fin de validité qu'il stocke est effacée une fois la demande traitée. Le masquage passe par le DELETE de l'étape 5, jamais par une modification.
:::danger effective_to_on est le seul attribut transmis à l'annuaire
effective_to_on (DT-7-3-2) est le seul attribut que cette API transmet à l'annuaire ; l'Annexe 3 V1.8 DG-7 autorise également la modification du matricule de la plateforme de réception (DT-7-6) sur une ligne pas encore en vigueur, ce que cette API ne prend pas encore en charge. Tout autre attribut envoyé dans entry est refusé : la requête répond 422 avec "code": "invalid_argument", la ligne n'est pas touchée et aucune demande de modification n'est créée. Le refus porte sur les clés envoyées, y compris une clé de valeur vide ou inconnue de l'API. Sont ainsi refusés siren, siret, suffix_code, routing_code_identifier, routing_code_qualifier, platform_registry_number, platform_registry_qualifier, nature_label, presence_reason et effective_from_on, que les versions précédentes acceptaient en 202 avant de les ignorer, ainsi que event_kind, qui n'a jamais eu d'effet ici. Pour corriger une maille d'adressage, mettez fin à la ligne existante avec effective_to_on puis créez-en une nouvelle (étape 2).
:::
curl -X PATCH https://app.scribee.tech/api/v1/companies/YOUR_COMPANY_ID/france/pid/entries/512 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"entry": {
"effective_to_on": "2026-12-31"
}
}'
Pour effacer une fin de validité déjà fixée, envoyez la même date à null :
{
"entry": {
"effective_to_on": null
}
}
Une fois la demande traitée par l'annuaire, la relecture de la ligne (étape 3) restitue la nouvelle effective_to_on - null si vous l'avez effacée.
Une ligne masquée ne se modifie plus.
Étape 5 : masquer une ligne à venir
Cet appel enregistre une demande de masquage et la transmet à l'annuaire national : la ligne est retirée de la publication active sans que son historique soit effacé. Le masquage ne vise qu'une ligne À venir - la réglementation de l'annuaire le réserve aux lignes pas encore en vigueur ; une ligne En vigueur se clôt par sa date de fin (étape 4), et l'appel répond 403 sur une telle ligne.
curl -X DELETE https://app.scribee.tech/api/v1/companies/YOUR_COMPANY_ID/france/pid/entries/512 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
{
"data": {
"change_request_id": 101
}
}
Réponse 202. Une fois le masquage répercuté, la ligne porte "masked": true, sort de la liste de l'entreprise et reste lisible à l'unité sur GET /api/v1/france/pid/entries/{id}. Le scope write suffit ; un token portant uniquement le scope destroy fonctionne aussi.
Ce qui se passe ensuite
- La demande transmise est traitée par l'annuaire national ; relistez les lignes de l'entreprise pour observer l'inscription, la modification ou le masquage. Le
change_request_ididentifie chaque demande dans vos échanges avec votre contact Scribee. - L'approbation d'un mandat couvrant la réception de factures est le prérequis à l'activation de l'annuaire pour l'entreprise concernée, et peut la déclencher : quand l'entrée remplit les conditions, l'approbation enclenche une activation en tâche de fond. Elle n'est pas garantie pour autant - relistez les lignes de l'entreprise pour constater leur état, et adressez-vous à votre contact Scribee si l'activation n'apparaît pas (Mandats de facturation électronique).
- Une fois la ligne En vigueur, les factures que vos fournisseurs émettent via la réforme sont adressées à Scribee et apparaissent dans votre workspace : Factures fournisseurs.
Erreurs et cas limites
422 : paramètre de consultation invalide
La consultation exige exactement un identifiant - siren ou siret, ni aucun ni les deux :
{
"error": "unprocessable_entity",
"code": "invalid_argument",
"message": "La validation a échoué",
"details": {
"base": ["un seul paramètre parmi siren ou siret doit être fourni"]
}
}
Un format invalide produit "le siren doit contenir exactement 9 chiffres" ou "le siret doit contenir exactement 14 chiffres" au même format.
422 : as_of invalide (Plateforme Agréée)
Réservé aux Plateformes Agréées sans include_history : un appelant standard, ou une Plateforme Agréée utilisant include_history, reçoit toujours un 200 pour un as_of invalide - repli silencieux sur la date du jour pour l'appelant standard, as_of étant simplement ignoré dans le cas include_history (voir Étape 1). Une Plateforme Agréée sans include_history reçoit ce 422 à la place, parce que as_of doit être honoré pour elle :
{
"error": "unprocessable_entity",
"code": "invalid_argument",
"message": "La validation a échoué",
"details": {
"base": ["invalid date"]
}
}
Ce message est celui, non traduit, du parseur de date sous-jacent - un écart volontaire au français des autres erreurs de cette page. La même réponse couvre un format non ISO 8601 et une date inexistante.
422 : demande d'écriture refusée
Les règles de l'annuaire sont vérifiées avant transmission ; la cause est dans details :
{
"error": "unprocessable_entity",
"code": "validation_failed",
"message": "La validation a échoué",
"details": {
"base": ["Date d'effet doit être au moins J+1 (demain ou plus tard)"]
}
}
Autres causes fréquentes, au même format : "SIRET la racine (9 premiers chiffres) doit correspondre au SIREN" quand le SIRET fourni ne descend pas du SIREN de la fiche entreprise, et "Code suffixe ne peut pas être renseigné lorsqu'un SIRET est présent" quand les deux mailles sont mélangées. Corrigez la demande et rejouez l'appel.
422 : attribut non modifiable (PATCH)
Une modification qui porte sur autre chose que effective_to_on est refusée avant toute transmission, et aucune demande n'est enregistrée :
{
"error": "unprocessable_entity",
"code": "invalid_argument",
"message": "effective_to_on (DT-7-3-2) est le seul attribut que cette API transmet à l'annuaire ; l'Annexe 3 V1.8 DG-7 autorise également le matricule de la plateforme de réception (DT-7-6) sur une ligne pas encore en vigueur, ce que cette API ne prend pas encore en charge. Retirez : nature_label, presence_reason",
"details": {
"nature_label": ["ne peut pas être modifié sur une ligne d'annuaire existante"],
"presence_reason": ["ne peut pas être modifié sur une ligne d'annuaire existante"]
}
}
details est indexé par attribut refusé, et message les reprend dans l'ordre où vous les avez envoyés. Retirez ces clés du corps et rejouez l'appel.
403 : mandat requis
Les écritures (POST, PATCH, DELETE) exigent sur l'entreprise un mandat à l'état active dont la période contractuelle couvre le jour de l'appel :
{
"error": "forbidden",
"message": "Un mandat actif est requis pour gérer l'annuaire de cette entreprise."
}
Les deux bornes ne jouent pas de la même façon : start_date compte le jour même, donc un mandat qui commence aujourd'hui autorise déjà ces écritures alors qu'un mandat qui commence demain les refuse encore ; end_date, elle, ne compte pas le jour même, donc un mandat dont l'end_date tombe aujourd'hui les refuse déjà. Un mandat approuvé mais dont la période n'a pas commencé produit donc exactement ce 403, au même titre qu'une entreprise sans aucun mandat.
Le mandat s'obtient et s'approuve via Mandats de facturation électronique.
403 : accès à l'annuaire non activé ou scope insuffisant
L'accès à l'annuaire est activé par Scribee sur votre workspace selon votre offre ; tant qu'il ne l'est pas, les endpoints de cette page répondent :
{
"error": "forbidden",
"message": "Vous n'êtes pas autorisé à effectuer cette action"
}
Le même corps répond à un token sans le scope requis (write pour POST et PATCH ; write ou destroy pour DELETE). Si vos scopes sont corrects, demandez l'activation de l'annuaire à votre contact Scribee. Sur la consultation, un workspace non rattaché à votre client OAuth répond 403 avec "L'application n'a pas accès à cet espace de travail" (Votre premier appel).
Ce contrôle d'activation est le dernier de la chaîne. Sur les écritures, un company_id hors du périmètre de votre application répond 404 et une entreprise sans mandat actif répond 403 avec le message de mandat ci-dessus, avant même que l'activation ne soit vérifiée ; sur la consultation, le rattachement du workspace est vérifié en premier. Ne concluez donc pas de l'absence de ce message que l'annuaire est activé : corrigez d'abord l'erreur signalée, puis rejouez l'appel.
404 Not Found
L'entreprise ou la ligne n'existe pas, ou appartient à un workspace hors du périmètre de votre application :
{
"error": "not_found",
"message": "La ressource demandée est introuvable"
}
400 Bad Request : page au-delà de la dernière
Les deux listes de cette page sont paginées et répondent 400 au-delà de la dernière page, comme partout ailleurs : Conventions de l'API.
Pages liées
- Entreprises et établissements - créer les fiches entreprise que vous inscrivez dans l'annuaire
- Factures fournisseurs - recevoir les factures une fois l'inscription en vigueur
- Référence API : consulter l'annuaire national
- Référence API : lister les lignes d'annuaire d'une entreprise
- Référence API : inscrire une ligne d'annuaire