ediverse Explore the platform

Spotlight PEPPOL BIS Billing 3.0 The EU e-invoicing mandate is here — France Sept 2026, Belgium Jan 2026, Germany 2025.

France — PPF central directory

The Public Invoicing Portal central directory is the single resolution service letting any issuing PDP find the relevant receiving PDP, its preferred format, and its signing certificate, given a SIREN/SIRET.

Role of the central directory

The central directory is the critical element of the French decentralised 5-corner model (see the CTC 5-corner page). It combines the role of a PEPPOL SMP+SML and of a business registry:

  • Recipient PDP resolution: for a given SIREN/SIRET, returns the registered PDP identifier, its AS4 endpoint, and the recipient's preferred invoicing format.
  • Official business registry: holds administrative information about an in-scope business (legal name, address, NAF code, intra-Community VAT number, active/deregistered status) consolidated from INSEE's SIRENE base and enriched with invoicing data.
  • Certificate registry: stores the signing certificate of the receiving PDP, letting the issuing PDP verify AS4 acknowledgements without relying on a third-party CA.
  • Source of in-scope checks: a French economic actor not present in the directory (or with EXEMPT status) means out of scope — the issuing PDP must fall back to e-reporting (declaration instead of inter-PDP invoice).

Data model

A partner record is a versioned JSON object identified by SIREN. Full example payload returned by GET /v1/partner/802145795:

json partner-record.json
{
  "siren": "802145795",
  "siret": "80214579500024",
  "denomination": "Atelier Numerique SAS",
  "address": {
    "street": "12 rue de la Faisanderie",
    "postalCode": "75116",
    "city": "Paris",
    "countryCode": "FR"
  },
  "ape": "6201Z",
  "tvaIntracom": "FR62802145795",
  "registeredPdp": {
    "pdpId": "PDP-FR-007",
    "name": "Plateforme Demat Acme",
    "endpoint": "https://pdp-acme.fr/as4/inbox",
    "as4PartyType": "iso6523-actorid-upis",
    "as4PartyId": "0009:80214579500024"
  },
  "acceptedFormats": [
    "urn:cen.eu:en16931:2017",
    "urn:factur-x.eu:1p0:en16931",
    "urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100",
    "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
  ],
  "preferredFormat": "urn:factur-x.eu:1p0:en16931",
  "signingCertificate": {
    "issuer": "CN=PPF Issuer CA, O=AIFE, C=FR",
    "serial": "0A:1B:2C:3D:4E:5F",
    "notAfter": "2027-12-31T23:59:59Z"
  },
  "lifecycle": {
    "createdAt": "2026-06-15T09:22:11Z",
    "updatedAt": "2026-08-30T17:45:00Z",
    "status": "ACTIVE"
  }
}
Field Type Description Required
sirenstring(9)9-digit SIREN, legal entity identifierYes
siretstring(14)14-digit SIRET, primary establishment identifierYes
denominationstringOfficial legal name (SIRENE source)Yes
addressobjectHeadquarters postal address (street, ZIP, city, ISO 3166-1 country)Yes
apestring(5)NAF rev. 2 code (Main Activity Exercised)Recommended
tvaIntracomstringIntra-Community VAT number, FR + key + SIRENIf liable for VAT
registeredPdpobjectDefault registered PDP (id, name, AS4 endpoint, party type/id)Yes (for inbound)
acceptedFormatsarrayList of accepted profile URNs (EN 16931, Factur-X EN16931, CII, UBL)Yes
preferredFormatstringURN of the preferred format to optimise recipient experienceRecommended
signingCertificateobjectX.509 certificate of the receiving PDP (issuer, serial, notAfter)Yes (for inbound)
lifecycle.status enum ACTIVE, SUSPENDED, EXEMPT, RADIATED Yes

Onboarding and self-registration

Two registration channels are defined by the AIFE specifications:

  1. Self-registration via the PPF web portal: the business logs into impots.gouv.fr with its pro-account credentials, picks its destination PDP, declares accepted formats, and electronically signs the record. Ideal for an SME or micro-business without PDP integration on the IT side.
  2. Registration via API from an accredited PDP: the PDP submits a POST /v1/partner on the business's behalf with a proof of mandate (OAuth token delegated by the business via the FranceConnect+ Pro procedure). Ideal for mid-caps and large enterprises managed industrially by their PDP.

In both cases, registration is validated by a DGFiP workflow (real-time SIRENE verification + anti-duplicate check) and activated typically after 30 seconds to 2 minutes. The intermediate status is PENDING_VALIDATION.

REST API + OAuth 2.0

The API exposes 8 main endpoints. Every call requires an OAuth 2.0 access token issued via the client_credentials flow (PDPs are the only OAuth clients; ERPs go through their PDP).

Authentication — obtain an access token

bash oauth-token.sh
curl -X POST https://annuaire.ppf.gouv.fr/oauth2/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=PDP-FR-007" \
  -d "client_secret=$PPF_CLIENT_SECRET" \
  -d "scope=annuaire.read annuaire.subscribe"

# Response:
# {
#   "access_token": "eyJhbGciOi...",
#   "token_type": "Bearer",
#   "expires_in": 3600,
#   "scope": "annuaire.read annuaire.subscribe"
# }

Typical scopes: annuaire.read (read partners), annuaire.write (registration, PDP only), annuaire.subscribe (webhook subscriptions).

GET /v1/partner/<siren>

bash get-partner.sh
curl -X GET "https://annuaire.ppf.gouv.fr/v1/partner/802145795" \
  -H "Authorization: Bearer $PPF_ACCESS_TOKEN" \
  -H "Accept: application/json" \
  -H "If-None-Match: \"v3-1730289302\""

# Possible responses:
# 200 OK -> partner body + ETag, Cache-Control: max-age=86400
# 304 Not Modified -> local cache still valid, do not refetch
# 404 Not Found -> business not registered or not in scope
# 410 Gone -> business deregistered, do not route to this address

The If-None-Match header with the ETag returned by a previous call enables 304 Not Modified responses: this is the lazy-invalidation mechanism complementing webhooks.

bash search-partner.sh
curl -X GET "https://annuaire.ppf.gouv.fr/v1/partner?denomination=cooperative&cursor=eyJpZCI6MTAwfQ&limit=100" \
  -H "Authorization: Bearer $PPF_ACCESS_TOKEN"

# Response:
# {
#   "results": [ { "siren": "521452014", ... }, ... ],
#   "pageInfo": {
#     "hasNextPage": true,
#     "endCursor": "eyJpZCI6MjAwfQ",
#     "pageSize": 100
#   }
# }

Pagination is opaque cursor-based: the client reuses the endCursor returned by the previous page as-is. This avoids inconsistent page jumps if the dataset changes concurrently (business deregistered during pagination, for instance).

Cache, TTL and invalidation webhooks

AIFE specifications prescribe a local cache on the PDP side with a default TTL of 24h. The risk without a cache is twofold: central API saturation (multiplied by the number of invoices) and an RTT latency hop per invoice (harmful to the contractual client SLA).

Cache invalidation is event-driven via the PPF webhook system. A PDP subscribes via POST /v1/subscriptions with an HTTPS callback endpoint and a shared HMAC secret. Emitted events include partner.created, partner.updated, partner.suspended, partner.radiated. Example received event:

json webhook-event.json
{
  "eventType": "partner.updated",
  "eventTimestamp": "2026-09-12T11:04:23Z",
  "eventId": "evt_2026091200004523",
  "schemaVersion": "PPF-1.2",
  "subject": {
    "siren": "802145795",
    "siret": "80214579500024"
  },
  "changes": [
    "registeredPdp.endpoint",
    "preferredFormat"
  ],
  "newVersion": "v4-1731060123",
  "ttlInvalidate": true
}
  1. HMAC-SHA256 signature: every webhook is signed via the X-PPF-Signature header. A PDP that does not verify the signature accepts forged invalidations.
  2. Idempotence: each event carries an opaque eventId. PPF may re-emit events on timeout: handle them idempotently (deduplicate by eventId).
  3. Propagation delay: the AIFE target is under 60 seconds between the directory change and reception by every subscribed PDP.
  4. Callback failure handling: exponential backoff up to 24h, then automatic unsubscribe and operator notification. The PDP must manually re-subscribe after recovery.