PPF Directory Line Instance Lookup
Purpose of Use: This endpoint is a live proxy to the PPF Annuaire API. When called, Docnova immediately forwards the request to the PPF's external /ligne-annuaire/id-instance:{idInstance} endpoint, returns the raw PPF response, and does not cache or store the result. The caller receives a real-time snapshot of the directory line as it currently exists in the national PPF Annuaire.
The PPF Annuaire (Portail Public de Facturation Directory) is France's central registry of all VAT-registered companies and their associated Plateformes Agréées, also known as approved e-invoicing platforms. Every company participating in the French e-invoicing mandate must have at least one ligne d'annuaire or directory line entry that specifies:
- Which PA (Plateforme Agréée) the company is connected to, and via which channel
- The company's addressing granularity (
SIREN,SIRET,SUFFIXE, orCODE_ROUTAGE) - The routing and addressing identifiers needed to deliver e-invoices to the company
- Validity dates, effect start and end dates, and historisation metadata
An idInstance is a unique numeric identifier assigned by the PPF to each version of a directory line entry. Because a company's annuaire entry can change over time, for example when switching platforms or updating routing codes, each historical version is preserved and assigned its own idInstance.
This endpoint is used for the following purposes:
- Precise version lookup: Retrieve a specific historical version of a directory line using its immutable
idInstance, even after the entry has been superseded by a newer version. - Annuaire data verification: Verify that a directory line known to Docnova still matches the live PPF Annuaire record for the same instance number. This is used in onboarding diagnostics and reconciliation.
- Platform and routing detail retrieval: Fetch the full
plateforme,etablissement,uniteLegale, andcodeRoutagedetail blocks that are needed to construct valid Peppol / PPF delivery addresses for the target company. - Support and audit use cases: Support teams use this endpoint to inspect the exact PPF record for a given instance, diagnose routing failures, and confirm validity dates.
🔄 Live PPF proxy — no caching: This endpoint makes a real-time call to the PPF Annuaire API on every request. The response reflects the current state of the PPF directory, not a Docnova-stored snapshot. Availability and latency depend on the PPF Annuaire API.
Server-Side Flow
| Step | Process | Description |
|---|---|---|
| 1 | Authentication | The R-Auth JWT is validated by the Spring Security filter chain. The authenticated user principal is extracted. |
| 2 | Input validation | idInstance is checked to be non-blank. A blank value throws a validation error and returns 400. |
| 3 | PPF availability check | If PPF integration is disabled in the Docnova configuration, the service returns null immediately and maps the response to 404 or 503, depending on environment configuration. |
| 4 | External PPF call | Docnova builds the URL /ligne-annuaire/id-instance:{idInstance} and makes an authenticated GET request to the PPF Annuaire API using a cached Bearer token stored in Redis. If the PPF returns 401, Docnova invalidates the cached token, re-authenticates, and retries the request once. |
| 5 | PPF 404 handling | If the PPF returns 404, meaning the instance was not found, Docnova returns null, and the response maps to 404. |
| 6 | Response | Returns HTTP 200 OK with the full AnnuaireLigneAnnuaireResponse JSON object mapped from the PPF response. |
Endpoint Information
| Property | Value |
|---|---|
| URL | /annuaire/FR/directory-line/instance/{idInstance} |
| Method | GET |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authorization | R-Auth header (JWT token) |
| Integration Type | Live PPF Proxy |
Example Request
curl --location 'https://api-fr-stage.docnova.ai/annuaire/FR/directory-line/instance/{idInstance}' \
--header 'Accept: */*' \
--header 'R-Auth: <jwt-token>'
This endpoint has no query parameters and no request body. The only inputs are the
idInstancepath variable and the authentication token.
Request Parameters
Header Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| R-Auth | string (JWT) | Yes | User session JWT token. Sent without a Bearer prefix. Signed with HS512; sub carries the encrypted user ID, claim carries authorization data, and userType holds CLIENT or ADMIN. |
| Accept | string | No | */* or application/json. Defaults to JSON if omitted. |
Path Parameters
| Parameter | Type | Required | Format / Example | Description |
|---|---|---|---|---|
| idInstance | string (numeric) | Yes | 1013330 | The PPF-assigned unique numeric instance identifier of the directory line entry to retrieve. Assigned by the PPF when a ligne d'annuaire is created or updated. Each historical version of a directory line has a distinct idInstance. Must be non-blank; numeric string format is expected. No UUID format is required. |
Responses
200 - Successful Response
Returns HTTP 200 OK with an AnnuaireLigneAnnuaireResponse object. The structure is nested: top-level addressing fields are accompanied by embedded plateforme, uniteLegale, etablissement, historisation, and codeRoutage objects.
{
"identifiantAdressage": "123456789",
"matriculePlateforme": "0001",
"identifiantRoutage": "0009:0001",
"siren": "123456789",
"siret": "12345678900014",
"suffixeAdressage": null,
"dateFinEffet": null,
"dateFinEffective": null,
"historisation": {
"idInstance": 1013330,
"dateDebutEffet": "2026-01-01",
"dateDefinition": "2025-12-20T09:00:00Z",
"creePar": "DOCNOVA_PA",
"masque": false
},
"plateforme": {
"typePlateforme": "PA",
"matriculePlateforme": "0001",
"raisonSocialePlateforme": "Melasoft SAS",
"nomCommercialPlateforme": "Docnova",
"contactOuUrlPlateforme": "https://docnova.ai",
"statutPlateforme": "ACTIF"
},
"uniteLegale": {
"siren": "123456789",
"raisonSociale": "ACME FRANCE SAS",
"typeEntite": "PM",
"etatAdministratif": "A",
"diffusible": "O"
},
"etablissement": {
"siret": "12345678900014",
"siren": "123456789",
"denomination": "ACME FRANCE SAS - SIEGE",
"typeEtablissement": "SIEGE",
"diffusible": "O",
"etatAdministratif": "A",
"adresse": {
"ligneAdresse1": "10 RUE DE LA PAIX",
"ligneAdresse2": null,
"ligneAdresse3": null,
"codePostal": "75001",
"localite": "PARIS",
"codePays": "FR",
"libellePays": "France",
"subDivisionPays": null
},
"donneesB2gComplementaires": null
},
"codeRoutage": null
}
Response Body — Top-Level Fields
| Field | Type | Nullable | Description |
|---|---|---|---|
| identifiantAdressage | string | Yes | The primary addressing identifier of the company in the PPF Annuaire. Contains the SIREN (9 digits) when maille is SIREN, SIRET (14 digits) when maille is SIRET, or the routing code value for CODE_ROUTAGE. |
| matriculePlateforme | string | Yes | PPF registration code of the Plateforme Agréée that handles this company's e-invoices. Used as the network address of the PA in Peppol routing. 9999 = company has not registered with any PA and is using the PPF default. Any other value = company is connected to a private PA. |
| identifiantRoutage | string | Yes | Full routing identifier in the format {schemeId}:{value}, for example 0009:0001. Used by the PPF to route incoming e-invoices to the correct PA endpoint. |
| siren | string (9) | Yes | The 9-digit SIREN of the company this directory line belongs to. |
| siret | string (14) | Yes | The 14-digit SIRET of the specific establishment, if this entry is registered at SIRET granularity. null for SIREN-level entries. |
| suffixeAdressage | string | Yes | Suffix appended to the SIRET for sub-unit identification. Populated only when the annuaire maille is SUFFIXE. |
| dateFinEffet | LocalDate | Yes | The planned end date of this directory line's validity. null if the entry is open-ended and still active. |
| dateFinEffective | LocalDate | Yes | The actual effective end date as confirmed by the PPF. May differ from dateFinEffet if the closure was processed at a different time. |
| historisation | object | Yes | Version and audit metadata assigned by the PPF to this specific instance. See historisation below. |
| plateforme | object | Yes | Full detail of the Plateforme Agréée associated with this directory line. See plateforme below. |
| uniteLegale | object | Yes | Legal entity (SIREN-level) details of the company. See uniteLegale below. |
| etablissement | object | Yes | Establishment (SIRET-level) details including address and B2G configuration. See etablissement below. |
| codeRoutage | object | Yes | Routing code detail block. Populated only when the annuaire maille is CODE_ROUTAGE. null for SIREN, SIRET, and SUFFIXE entries. See codeRoutage below. |
historisation — Version & Audit Metadata
| Field | Type | Nullable | Description |
|---|---|---|---|
| idInstance | integer | No | The PPF-assigned unique instance number of this directory line version. Matches the idInstance supplied in the request path. |
| dateDebutEffet | LocalDate | Yes | The date from which this directory line version became effective in the PPF. |
| dateDefinition | OffsetDateTime | Yes | The exact date-time when this instance was defined, created, or updated in the PPF Annuaire. ISO 8601 with timezone offset. |
| creePar | string | Yes | Identifier of the actor, PA matricule or PPF internal identifier, that created this instance. |
| masque | boolean | Yes | If true, this directory line has been hidden or masked in the PPF Annuaire. A masked entry is not visible to other PAs for routing purposes. |
plateforme — Associated Plateforme Agréée
| Field | Type | Nullable | Description |
|---|---|---|---|
| typePlateforme | string | Yes | Platform type code. Typically PA (Plateforme Agréée) or PPF (Portail Public de Facturation itself). |
| matriculePlateforme | string | Yes | The PPF-assigned registration number of the platform. Used as the routing endpoint identifier in e-invoice transmission. |
| raisonSocialePlateforme | string | Yes | Legal company name of the platform operator. |
| nomCommercialPlateforme | string | Yes | Commercial or brand name of the platform, for example Docnova. |
| contactOuUrlPlateforme | string | Yes | Contact email address or URL of the platform for support or integration queries. |
| statutPlateforme | string | Yes | Administrative status of the platform in the PPF registry. Common values: ACTIF (active), SUSPENDU (suspended), FERME (closed). |
uniteLegale — Legal Entity (SIREN Level)
| Field | Type | Nullable | Description |
|---|---|---|---|
| siren | string (9) | Yes | 9-digit SIREN of the legal entity. |
| raisonSociale | string | Yes | Legal company name registered with INSEE. |
| typeEntite | string | Yes | Entity type: PM (Personne Morale / legal person) or PP (Personne Physique / natural person). |
| etatAdministratif | string | Yes | Administrative status from INSEE: A (Actif / active) or C (Cessé / ceased). |
| diffusible | string | Yes | INSEE diffusion flag: O (diffusible / public) or N (non-diffusible / private). Non-diffusible entities have restricted access in public directories. |
etablissement — Establishment (SIRET Level)
| Field | Type | Nullable | Description |
|---|---|---|---|
| siret | string (14) | Yes | 14-digit SIRET of the establishment. |
| siren | string (9) | Yes | Parent SIREN of the establishment. |
| denomination | string | Yes | Establishment name or designation. May include branch suffix, for example - SIEGE. |
| typeEtablissement | string | Yes | Type of establishment: SIEGE (registered head office) or SECONDAIRE (secondary establishment). |
| diffusible | string | Yes | INSEE diffusion flag: O or N. |
| etatAdministratif | string | Yes | Administrative status: A (active) or F (fermé / closed). |
| adresse | object | Yes | Postal address of the establishment. See etablissement.adresse fields below. |
| donneesB2gComplementaires | object | Yes | B2G (Business-to-Government) supplementary data. null for purely B2B companies. See donneesB2gComplementaires below. |
etablissement.adresse — Postal Address
| Field | Type | Nullable | Description |
|---|---|---|---|
| ligneAdresse1 | string | Yes | First address line, including street number and name. |
| ligneAdresse2 | string | Yes | Second address line, for example building, floor, or additional location information. |
| ligneAdresse3 | string | Yes | Third address line for additional details. |
| codePostal | string | Yes | French postal code, 5 digits. |
| localite | string | Yes | City or locality name. |
| codePays | string (2) | Yes | ISO 3166-1 alpha-2 country code, for example FR. |
| libellePays | string | Yes | Full country name in French. |
| subDivisionPays | string | Yes | Country subdivision code (ISO 3166-2). Rare; mostly null for French addresses. |
etablissement.donneesB2gComplementaires — B2G Supplementary Data
| Field | Type | Nullable | Description |
|---|---|---|---|
| gestionEngagementJuridique | boolean | Yes | Whether legal commitment management is enabled for this entity in the B2G context. |
| gestionStatutMiseEnPaiement | boolean | Yes | Whether payment status management is active. |
| gestionCodeService | boolean | Yes | Whether service code management is enabled. |
| moaUniquement | boolean | Yes | If true, this entity operates as buyer (MOA — Maître d'Ouvrage) only in B2G flows. |
| gestionEngagementJuridiqueOuService | boolean | Yes | Combined flag indicating whether legal commitment or service code management is enabled. |
| moa | boolean | Yes | Whether this entity is designated as MOA (project owner / buyer) in the B2G procurement flow. |
codeRoutage — Routing Code Detail (CODE_ROUTAGE Maille Only)
| Field | Type | Nullable | Description |
|---|---|---|---|
| identifiantRoutage | string | Yes | The routing code identifier assigned to this sub-unit. |
| typeIdentifiantRoutage | string | Yes | Type of the routing identifier, also known as the scheme. |
| libelleCodeRoutage | string | Yes | Human-readable label for the routing code. |
| gestionEngagementJuridique | boolean | Yes | B2G legal commitment flag at routing code level. |
| etatAdministratif | string | Yes | Administrative status of this routing code: A (active) or F (closed). |
| adresse | object | Yes | Postal address associated with this routing code. Same structure as etablissement.adresse. |
Enum Values
FrancePpfMaille — Annuaire Addressability Granularity
Determines which of the nested objects is populated and which top-level identifier is used.
| Value | identifiantAdressage Contains | Populated Nested Object | Description |
|---|---|---|---|
| SIREN | 9-digit SIREN | uniteLegale | Company is registered at SIREN level. All invoices addressed to this company, regardless of establishment, are routed to the same PA. |
| SIRET | 14-digit SIRET | etablissement | Company is registered at establishment level. Different SIRET numbers may route to different PAs. |
| SUFFIXE | SIRET + suffix | etablissement + suffixeAdressage | Sub-unit of an establishment identified by an additional suffix. Used for large organizations with complex internal routing. |
| CODE_ROUTAGE | routing code value | codeRoutage | Custom routing code; used by large corporate groups where neither SIREN nor SIRET granularity is sufficient. |
All error responses share the following structure:
{
"errorMessage": "<human-readable message>",
"errorType": "<error type key>",
"errorTitle": "<HTTP status name>",
"status": 404,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/annuaire/FR/directory-line/instance/1013330"
}
400 - Bad Request
Returned when the idInstance path variable is present but empty or blank.
{
"errorMessage": "idInstance must not be blank",
"errorType": "BAD_REQUEST",
"errorTitle": "BAD_REQUEST",
"status": 400,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/annuaire/FR/directory-line/instance/"
}
Condition: The idInstance path variable is present but empty or blank, for example /instance/ or /instance/ .
Server behavior: FranceAnnuaireApiService.validateNotBlank() throws IllegalArgumentException; RestExceptionHandler maps it to 400.
401 - Unauthorized
Returned when the R-Auth header is missing, malformed, or the JWT token is expired.
{
"errorMessage": "Not authorized for this action",
"errorType": "NOT_AUTHORITY",
"errorTitle": "UNAUTHORIZED",
"status": 401,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/annuaire/FR/directory-line/instance/1013330"
}
Condition: The R-Auth header is missing, malformed, or the JWT exp claim has passed.
Server behavior: Spring Security filter chain rejects the request before the controller is reached.
404 - Not Found
Returned when the PPF Annuaire API returns 404.
{
"errorMessage": "Not Found",
"errorType": "NOT_FOUND",
"errorTitle": "NOT_FOUND",
"status": 404,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/annuaire/FR/directory-line/instance/1013330"
}
Condition: The PPF Annuaire API returned 404, meaning no directory line exists for the given idInstance, or the instance number has never been assigned by the PPF.
Server behavior: FranceAnnuaireApiService.doGetAttempt() receives a 404 from PPF and returns null; the controller's toResponse(null) maps to a 404 HTTP response.
500 - Internal Server Error
Returned when an unexpected exception occurs while communicating with the PPF Annuaire API.
{
"errorMessage": "An unexpected error occurred",
"errorType": "RUNTIME_ERROR",
"errorTitle": "INTERNAL_SERVER_ERROR",
"status": 500,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/annuaire/FR/directory-line/instance/1013330"
}
Condition: An unexpected exception occurred while communicating with the PPF Annuaire API, such as network timeout, malformed PPF response, or an unhandled HTTP error status from the PPF.
Server behavior: The try/catch in doGetAttempt() catches the exception and rethrows it as a RuntimeException; RestExceptionHandler maps it to 500.
503 - Service Unavailable
Returned when the PPF Annuaire integration is disabled in the Docnova server configuration.
{
"errorMessage": "PPF integration is currently unavailable",
"errorType": "SERVER_ERROR",
"errorTitle": "SERVICE_UNAVAILABLE",
"status": 503,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/annuaire/FR/directory-line/instance/1013330"
}
Condition: The PPF Annuaire integration is disabled in the Docnova server configuration (config.isEnabled() = false). This typically happens in maintenance or staging environments where the PPF connection is intentionally turned off.
Server behavior: The service returns null immediately without calling PPF; response mapping returns 404 or 503, depending on environment configuration.