<!-- llms-full.txt de FacturX API : llms.txt puis le texte des pages essentielles, lu sur les pages servies.
     Pages sources : /llms.txt, /docs/agents, /docs/integration-convert-json-erp, /docs, /errors, /methodologie, /pricing. -->

# FacturX API

> API REST qui génère des Factur-X PDF/A-3 EN16931 (XML CII embarqué) depuis les données de facture JSON de votre ERP, contrôle le fichier produit et explique les erreurs EN16931 par leur règle (BR-…). Brique technique pour éditeurs ERP verticaux, intégrateurs de logiciels de gestion (Dolibarr, Axelor, ERP métier custom) et logiciels métiers sectoriels cloud-native qui préparent leurs flux facturants France 2026 sans devenir Plateforme Agréée eux-mêmes.

## Contrat machine de l'API

- Contrat OpenAPI de référence : https://api.facturxapi.com/openapi.json (le contrat servi par l'API elle-même)
- URL de base de l'API : https://api.facturxapi.com
- Authentification : en-tête `X-API-Key` ; clé gratuite sur https://facturxapi.com/api-key
- /scan est une page web de diagnostic public gratuit (https://facturxapi.com/scan), pas un point d'accès d'API : il n'existe pas de route `/api/v1/scan` dans le contrat de l'API.

## Premier appel (fichier d'essai public)

Fichier d'essai : https://facturxapi.com/demo/facturx-valid-basic.xml (XML CII Factur-X EN16931 de démonstration, données et identifiants fictifs). Appel de contrôle, avec une clé obtenue sur https://facturxapi.com/api-key :

```
curl -X POST https://api.facturxapi.com/api/v1/validate \
  -H "X-API-Key: $FACTURX_API_KEY" \
  -F "file=@./facturx-valid-basic.xml;type=application/xml"
```

La réponse est du JSON (`valid`, `issues`, `target`). La cible de validation s'applique selon les pays du document ou selon le paramètre `validation_target` (`en16931` ou `france_2026`) : lire `target.executed` dans la réponse. Constat du 04/11/2026 sur l'environnement de test, appel ci-dessus sans `validation_target` : HTTP 200, cible `france_2026` exécutée (`target.status` : `verified`), profil EN16931, `valid: true`, 0 erreur et 0 avertissement. Ce résultat porte sur les contrôles exécutés (EN16931 et France CTC) : il ne vaut pas acceptation par une Plateforme Agréée. La clé se crée sur la page ci-dessus par une personne.

## API endpoints

Chemins publiés par le contrat OpenAPI de l'API, relatifs à l'URL de base https://api.facturxapi.com :

- [POST /api/v1/validate](https://api.facturxapi.com/api/v1/validate): Validation XSD + Schematron EN16931
- [POST /api/v1/convert](https://api.facturxapi.com/api/v1/convert): données ERP complètes (invoice_data JSON) ou PDF → XML CII ou Factur-X PDF/A-3 avec XML embarqué, contrôlé pour la cible demandée ; sources XML CII (BASIC/EN16931) et UBL prises en charge selon le contrat du déploiement
- [POST /api/v1/extract](https://api.facturxapi.com/api/v1/extract): Factur-X PDF → XML CII + JSON exploitable
- [POST /api/v1/repair](https://api.facturxapi.com/api/v1/repair): XML CII → corrections déterministes prises en charge, diff et validation après correction (repairSuccessful=true seulement si une correction est appliquée et la cible vérifiée)
- [GET /api/v1/integration-contract](https://api.facturxapi.com/api/v1/integration-contract): Contrat d'intégration ERP public (source de vérité, lecture seule)
- [GET /meta](https://api.facturxapi.com/meta): Métadonnées publiques de l'API (source de vérité)
- [GET /health](https://api.facturxapi.com/health): Contrôle de santé du service (base de données et dérive de schéma)
- [GET /healthz](https://api.facturxapi.com/healthz): Vivacité du processus, sans sonder les dépendances externes
- [POST /api/v1/trial/integration/start](https://api.facturxapi.com/api/v1/trial/integration/start): ancien essai Integration, retiré ; utiliser le flux de clé API Sandbox

## Agents (MCP) et SDK

- Serveur MCP officiel, publié sur PyPI : `pip install facturx-mcp` (version 0.1.2), puis `facturx-mcp` (transport stdio par défaut, ou `--transport streamable-http`) avec `FACTURX_API_KEY` (`FACTURX_BASE_URL` est facultative depuis la 0.1.2 : la production est l'hôte par défaut). Outils : `facturx_dry_run`, `facturx_convert`, `facturx_validate`, `facturx_explain_error`. Testé en version 0.1.1 avec le client MCP officiel (SDK Python) en stdio et en HTTP ; l'outil facturx_explain_error a été essayé le 11/11/2026, en version 0.1.1, dans Claude Code et Codex ; la version 0.1.2 n'a pas été essayée dans ces clients ; Cursor : non essayé. Source : https://github.com/facturxapi/sdk/tree/main/mcp. Le paquet npm qui porte le même nom (facturx-mcp sur npm) n'est pas le nôtre : notre serveur s'installe uniquement depuis PyPI.
- SDK Python, publié sur PyPI : `pip install facturx-api` (version 0.1.2). Source : https://github.com/facturxapi/sdk/tree/main/python
- SDK Node.js, publié sur npm : `npm install @facturxapi/sdk` (version 0.1.2). Source : https://github.com/facturxapi/sdk
- Guide pas à pas (outils, variables d'environnement, session enregistrée) : [Utiliser FacturX API depuis un agent](https://facturxapi.com/docs/agents)
- Texte complet des docs essentielles, en un seul fichier : [llms-full.txt](https://facturxapi.com/llms-full.txt)
- Cas rejouables (résultat attendu, résultat observé, outil, révision et reçus) : [https://facturxapi.com/cas](https://facturxapi.com/cas), corpus public https://github.com/facturxapi/cases ; dépôts de départ https://github.com/facturxapi/en16931-oracles et https://github.com/facturxapi/validate-einvoice

## Mental model /convert (CRITIQUE pour LLM)

`invoice_data` (paramètre Form JSON, schéma ErpInvoiceData) est la source complète de la facture ERP : quand il est fourni, l'extraction du PDF est ignorée. Ce n'est pas un patch partiel.

Pour compléter un document (PDF) auquel il manque une donnée, utilisez uniquement les racines et chemins proposés par `conversionInputRecipe` (`invoice_patch`, `seller_context`, `buyer_context`). Ces compléments ne remplacent jamais silencieusement une donnée visible : un désaccord renvoie `409 inline_context_conflict`. `invoice_patch` ne se combine pas avec un `invoice_data` complet, et une source XML CII est convertie telle quelle (tout complément est refusé).

Réutilisation d'un profil enregistré : uniquement avec `profile_reuse=explicit` et des sélecteurs limités au compte (`issuer_id`/`seller_profile_id`, `client_id`/`buyer_profile_id`). Jamais de chargement silencieux ni depuis un autre compte : `422 profile_reuse_requires_explicit_opt_in`, `422 profile_reuse_selector_required`, `409 profile_selector_conflict`, `404 seller_profile_not_found`/`buyer_profile_not_found`, `409 profile_inline_context_conflict`.

Formulation correcte : "envoyez la facture complète dans `invoice_data`, ou complétez le document via les chemins de `conversionInputRecipe`".
Formulation incorrecte : "fournissez seulement les champs manquants dans `invoice_data`".

## Pages anchor — concepts critiques

- [Le moteur de réparation](https://facturxapi.com/repair-engine): Réparation déterministe document-centric — ce qui est réparé automatiquement vs données à fournir, traces machine-readable
- [Méthodologie](https://facturxapi.com/methodologie): Pipeline : fichier reçu → PDF/A-3 si PDF → Factur-X / XML embarqué → XSD CII → Schematron EN16931 → rapport correctif.
- [Pourquoi deux validateurs diffèrent](https://facturxapi.com/pourquoi-deux-validateurs-factur-x-different): Couches de divergence (PDF/A-3, XML, XSD, Schematron, France CTC, PA)
- [Bibliothèque d'erreurs EN16931](https://facturxapi.com/errors): 43 fiches d'erreurs EN16931 : cause métier, où regarder, exemple minimal et correction concrète.
- [France CTC vs EN16931](https://facturxapi.com/france-ctc-en16931): Différences de périmètre entre socle européen et contrôles France 2026
- [Réforme facturation électronique 2026-2027](https://facturxapi.com/reforme-facturation-electronique-2026-2027): Veille contextuelle
- [Pourquoi une API ?](https://facturxapi.com/pourquoi-une-api): Argumentaire brique vs PA tout-en-un
- [Avoir Factur-X invalide](https://facturxapi.com/avoir-factur-x-invalide): Distinguer correction déterministe et donnée ERP manquante
- [Pour intégrateurs ERP](https://facturxapi.com/integrateurs): Landing dédiée intégrateurs ERP (Dolibarr, Axelor, ERP métier custom) et ESN métier

## Réponses directes aux questions d'intégration

- Générer un Factur-X depuis un JSON ERP : [JSON ERP vers Factur-X PDF/A-3 ou XML CII](https://facturxapi.com/docs/integration-convert-json-erp) — `POST /api/v1/convert` avec un `invoice_data` complet
- Valider un Factur-X EN16931 en ligne : [Diagnostic /scan](https://facturxapi.com/scan) (page web gratuite) ; par API : `POST /api/v1/validate`
- Factur-X en Python : [Intégration Python](https://facturxapi.com/integrations/python) · [Générer et valider un XML EN16931 en Python](https://facturxapi.com/blog/python-facturx-generer-valider-xml-en16931)
- Factur-X en Node.js : [Intégration Node.js](https://facturxapi.com/integrations/nodejs) · autres intégrations : [PHP](https://facturxapi.com/integrations/php), [.NET](https://facturxapi.com/integrations/dotnet), [Laravel](https://facturxapi.com/integrations/laravel), [Symfony](https://facturxapi.com/integrations/symfony), [Dolibarr](https://facturxapi.com/integrations/dolibarr)
- Bibliothèque open source ou API : [Build vs buy](https://facturxapi.com/blog/build-vs-buy-validateur-facturx-api-cout)
- Plateforme Agréée ou API Factur-X : [FacturX API n'est pas une Plateforme Agréée](https://facturxapi.com/blog/facturx-api-pas-plateforme-agreee-validation-documentaire) · [Pourquoi une API ?](https://facturxapi.com/pourquoi-une-api)
- Comprendre une erreur BR-* : [Bibliothèque d'erreurs](https://facturxapi.com/errors) · [Catalogue des erreurs BR EN16931](https://facturxapi.com/blog/catalogue-erreurs-br-en16931-facturx) · exemple [BR-CO-16](https://facturxapi.com/blog/erreur-br-co-16-montant-du-paiement)
- Obligations 2026 pour un éditeur de logiciel : [Guide technique développeurs](https://facturxapi.com/blog/facturation-electronique-2026-guide-technique-developpeurs) · [Réforme 2026-2027](https://facturxapi.com/reforme-facturation-electronique-2026-2027)

## Blog

- [Valider EN16931 / Factur-X dans GitHub Actions](https://facturxapi.com/blog/valider-ci-github-actions): Action `facturxapi/validate-einvoice@v1`, XSLT ConnectingEurope 1.3.16 (CII et UBL), codes BR-*.
- [Pourquoi deux validateurs divergent](https://facturxapi.com/blog/pourquoi-deux-validateurs-divergent): versions Schematron, agrégation des `warning`, point de comparaison ITB 16/16, calendrier FNFE-MPE V1.4.0 du 30 juin 2026.

## Pricing

- Sandbox: 100 factures traitées offertes les 14 premiers jours, puis 10 factures traitées/mois, sans carte bancaire
- Launch: 39€/mois, 100 factures traitées par mois, souscription en ligne, TVA non applicable, art. 293 B du CGI
- Scale: 149€/mois, 500 factures traitées par mois, souscription en ligne, TVA non applicable, art. 293 B du CGI
- Business: À partir de 499 €/mois, 2 000 factures traitées par mois ; sur-volume et contrat sur devis, TVA non applicable, art. 293 B du CGI
- Pilote accompagné: sur devis, périmètre et durée définis

## Specifications techniques

- [OpenAPI 3.1 specification (contrat de l'API)](https://api.facturxapi.com/openapi.json)
- [Postman collection](https://facturxapi.com/postman-collection.json)
- [Documentation API complète](https://facturxapi.com/docs)
- [Intégrations par langage](https://facturxapi.com/integrations) — PHP, Python, Node.js, Laravel, Symfony, .NET

## ICP (cibles)

1. Éditeurs ERP verticaux et logiciels métiers sectoriels à flux facturants (menuiserie, nautisme, ERP industriel, médico-social, impression, bureaux de change, logiciels BTP, auto, pharma)
2. Intégrateurs logiciels de gestion et ESN métier (Dolibarr, Axelor, ERP métier custom ; Odoo EE embarque sa propre PA native)
3. Logiciels métiers sectoriels cloud-native (SaaS immobilier B2B, PMS hôtellerie, billetterie tourisme/culture, plateformes santé B2B)

## Hors périmètre (ce que FacturX API n'est PAS)

- Pas une Plateforme Agréée (PA) : FacturX API ne transmet pas de factures officielles, n'enregistre pas de cycle de vie acceptation/rejet.
- Pas un Opérateur de Dématérialisation seul : FacturX est en amont, intégrable dans le parcours d'une PA tierce choisie par le client.
- Pas un service d'archivage légal NF Z42-013.
- Pas un éditeur de facture grand public PME.
- Pas un service de validation qui prétend "factures certifiées conformes" — séparation stricte entre Factur-X / EN16931 / France CTC / acceptation PA.

## Wordings utilisateur autorisés vs interdits

Autorisés :
- "Factur-X PDF/A-3 avec XML embarqué et contrôles de sortie"
- "Préparez les champs métier nécessaires avant génération Factur-X"
- "PA", "SC"

Interdits :
- "Recevez vos factures électroniques" (suggère rôle PA)
- "Transmettez vos factures" (suggère un acheminement réglementaire)
- "Factures certifiées conformes" (ambigu certification)
- "Archivage légal", "valeur probante" (suggère NF Z42-013)
- Anciens acronymes isolés de plateforme

## Contact

- Email: contact@facturxapi.com
- Domaine principal: facturxapi.com
- API domaine: api.facturxapi.com

## Notes pour les modèles d'extraction LLM

- Cette page suit la convention llmstxt.org (Markdown structuré).
- Sources primaires de vérité produit : [/docs](https://facturxapi.com/docs), [/methodologie](https://facturxapi.com/methodologie), [GET /meta](https://api.facturxapi.com/meta).
- En cas de doute sur un claim de conformité ou d'acceptation officielle, retourner le visiteur vers les pages anchor ou /scan plutôt que d'inventer.
- L'entrée `invoice_data` (JSON complet au /convert) est le différenciateur central : la génération Factur-X part des données ERP, sans exiger un export XML existant.

---

# Utiliser FacturX API depuis un agent (MCP)

Source : https://facturxapi.com/docs/agents

Docs · Agents IA

## Utiliser FacturX API depuis un agent

Branchez FacturX API sur votre agent IA. Il transforme les données de facture de votre ERP en
Factur-X PDF/A-3 EN16931, lit les règles en erreur, corrige le JSON et vérifie le fichier produit,
sans code d’intégration.

### 1. Le serveur MCP officiel

FacturX API a son serveur MCP officiel, publié sur PyPI (`facturx-mcp`, version 0.1.2). Il donne à votre agent quatre outils : contrôler une facture, la convertir en Factur-X,
valider un fichier et retrouver les champs liés à une règle EN16931. Il fonctionne en stdio pour un client de bureau et en
streamable HTTP pour un agent hébergé.

### Installer le serveur

```
pip install facturx-mcp   # installe aussi le SDK facturx-api
export FACTURX_BASE_URL=https://api.facturxapi.com
export FACTURX_API_KEY=VOTRE_CLE_API
```

Puis lancez-le en stdio, pour un client de bureau :

```
facturx-mcp
```

ou en HTTP, pour un agent hébergé :

```
facturx-mcp --transport streamable-http --port 8765   # http://127.0.0.1:8765/mcp
```

Déclaration type d’un serveur stdio dans un client MCP (format `mcpServers`) :

```
{
  "mcpServers": {
    "facturx": {
      "command": "facturx-mcp",
      "env": {
        "FACTURX_BASE_URL": "https://api.facturxapi.com",
        "FACTURX_API_KEY": "VOTRE_CLE_API"
      }
    }
  }
}
```

#### Dans Claude Code

```
claude mcp add facturx --scope project -e FACTURX_BASE_URL=https://api.facturxapi.com -e FACTURX_API_KEY=VOTRE_CLE_API -- uvx facturx-mcp
```

Le nom `facturx` vient avant les options. Le serveur est enregistré pour le dossier du projet ; `claude mcp list` l’affiche alors « Pending approval ».

#### Dans Codex

```
codex mcp add facturx --env FACTURX_BASE_URL=https://api.facturxapi.com --env FACTURX_API_KEY=VOTRE_CLE_API -- uvx facturx-mcp
```

Ces deux commandes lancent le serveur avec `uvx` : il faut `uv` installé. Remplacez `VOTRE_CLE_API` par votre clé.

Essayé le 11/11/2026, avec la version 0.1.1 du serveur, dans Claude Code 2.1.322 et Codex CLI 0.167.0 avec l’outil facturx_explain_error. Les outils qui demandent une clé (facturx_dry_run, facturx_convert, facturx_validate) ont été essayés le 06/11/2026, avec la version 0.1.1, avec le client MCP officiel en Python. La version 0.1.2 n’a pas été essayée dans ces clients. Cursor : non essayé.

Notre serveur s’installe uniquement depuis PyPI. Le paquet npm qui porte le même nom (`facturx-mcp` sur npm)
n’est pas le nôtre.

Sans agent, les mêmes appels existent en SDK : `pip install facturx-api` (Python) et
`npm install @facturxapi/sdk` (Node.js), version 0.1.2. Sources :
[github.com/facturxapi/sdk](https://github.com/facturxapi/sdk).

### 2. Obtenir une clé

Créez une clé Sandbox sur [/api-key](https://facturxapi.com/api-key), sans carte
bancaire. Le serveur lit deux variables d’environnement, une seule est obligatoire :

FACTURX_API_KEY Votre clé API (en-tête `X-API-Key`).

FACTURX_BASE_URL Facultative depuis la 0.1.2 : la production (`https://api.facturxapi.com`) est l’hôte par défaut ; obligatoire en 0.1.1.

### 3. Les quatre outils exposés

Chaque description dit à l’agent quand appeler l’outil, ce qu’il renvoie et ce qu’il consomme. Le
serveur indique aussi l’ordre : contrôle d’abord, conversion seulement quand le contrôle répond ready.

Outil | Ce qu’il fait | Ce qu’il consomme |
`facturx_dry_run` (invoice, validation_target?, output?)
| Contrôle le JSON de facture complet avant toute génération. Renvoie ready (vrai seulement quand generationReadiness.status vaut « ready »), le détail de ce qui bloque, request_id et idempotency_key. Ce qu’il consomme : Aucune facture décomptée.
| Aucune facture décomptée. |
`facturx_convert` (invoice, out_dir, validation_target?, output?, idempotency_key?)
| Génère factur-x.pdf (PDF/A-3 avec XML embarqué) et factur-x.xml dans out_dir. Renvoie chemins, tailles, SHA-256, la cible et son statut, et l’idempotency_key. Ce qu’il consomme : 1 facture du quota. Relancé avec la même idempotency_key après une coupure, l’appel n’est pas facturé deux fois.
| 1 facture du quota. Relancé avec la même idempotency_key après une coupure, l’appel n’est pas facturé deux fois. |
`facturx_validate` (file_path, validation_target?)
| Valide un Factur-X PDF ou un XML CII présent sur le disque. Renvoie valid, validationStatus, le profil, la cible et les dix premières erreurs. Ce qu’il consomme : 1 facture du quota par rapport rendu, que le fichier soit valide ou non. Un appel refusé (clé, format, quota atteint) ou interrompu par une erreur technique de notre côté n’est pas décompté.
| 1 facture du quota par rapport rendu, que le fichier soit valide ou non. Un appel refusé (clé, format, quota atteint) ou interrompu par une erreur technique de notre côté n’est pas décompté. |
`facturx_explain_error` (code_or_rule)
| Donne, pour une règle EN16931 ou des règles françaises (BR-CO-15…), un terme métier (BT-1…) ou un chemin JSON (totals.gross…), les champs concernés, BT, règle, XPath CII, exigence, lus dans le contrat d’intégration public. Ce qu’il consomme : Sans clé API.
| Sans clé API. |

### 4. Une session d’agent, du JSON ERP au PDF vérifié

Les réponses des outils ci-dessous sont celles d’une session enregistrée le 6 novembre 2026 sur
l’environnement de test (valeurs exactes, sorties abrégées).

- Vous (demande d’exemple)
Voici l’export JSON de la facture X08-DEMO-001 de notre ERP. Produis le Factur-X EN16931 dans ./out et vérifie-le.

- Agent → facturx_explain_error

```
{ "code_or_rule": "BR-CO-15" }
```
 → 3 champs liés : totals.net (BT-109), totals.tax (BT-110), totals.gross (BT-112), lus dans GET /api/v1/integration-contract.
BR-CO-15 : total TTC = total HT + total TVA. L’agent contrôle ces trois montants de l’export avant d’appeler l’API.

- Agent → facturx_dry_run
Extrait abrégé, non exécutable

```
{ "invoice": { …facture X08-DEMO-001… } }
```
 → ready: true — generationReadiness « ready », 0 donnée bloquante.

- Agent → facturx_convert
Extrait abrégé, non exécutable

```
{ "invoice": { … }, "out_dir": "out" }
```
 → Cible en16931 vérifiée. out/factur-x.xml (4 584 octets, SHA-256 f332975e…e03c) et out/factur-x.pdf (20 624 octets).

- Agent → facturx_validate

```
{ "file_path": "out/factur-x.pdf", "validation_target": "en16931" }
```
 → valid: true — profil EN16931, 0 erreur.

- Agent
Factur-X généré dans out/factur-x.pdf : profil EN16931, cible vérifiée, 0 erreur à la validation.

#### Quand l’export ERP contient une erreur

- Quand un appel échoue, l’agent reçoit l’erreur de l’API telle quelle : status, code, api_message, request_id et idempotency_key. Il n’a pas à deviner ce qui s’est passé.
- Pour une règle (BR-…) ou un terme (BT-…), facturx_explain_error lui donne le champ JSON à corriger, son BT et, quand le contrat le donne, son emplacement dans le XML CII.
- Il corrige le JSON, relance facturx_dry_run, et ne lance facturx_convert que lorsque ready vaut true.

### Pour aller plus loin

- [Le format invoice_data (JSON ERP vers Factur-X)](https://facturxapi.com/docs/integration-convert-json-erp)
- [Le contrat d’intégration : chaque champ, son BT et sa règle](https://facturxapi.com/docs/integration-contract)
- [La bibliothèque d’erreurs](https://facturxapi.com/errors)
- [Le contrat OpenAPI](https://api.facturxapi.com/openapi.json)
- [llms.txt](https://facturxapi.com/llms.txt) et [llms-full.txt](https://facturxapi.com/llms-full.txt) pour les assistants
- [Tarifs](https://facturxapi.com/pricing)

---

# JSON ERP vers Factur-X PDF/A-3 ou XML CII

Source : https://facturxapi.com/docs/integration-convert-json-erp

Intégration ERP / GED

## Générez vos factures Factur-X depuis votre ERP — sans moteur PDF/XML à maintenir

Envoyez votre JSON de facture. L’API génère soit un PDF/A-3 Factur-X avec son XML CII embarqué, soit le XML CII seul. Elle distingue le livrable obtenu du niveau de validation réellement exécuté.

[Tester mon JSON](https://facturxapi.com/docs/integration-contract?source=erp_guide#validateur) [Voir l’exemple d’appel](https://facturxapi.com/docs/integration-convert-json-erp#curl)

Le test en direct utilise le moteur réel et affiche le niveau obtenu. Créez une clé API seulement lorsque vous êtes prêt à intégrer l’appel dans votre environnement.

### Depuis Python ou Node.js : des clients publiés

Vous n'avez pas à écrire le client HTTP : pip install facturx-api (Python) et
npm install @facturxapi/sdk (Node.js) font la simulation, la conversion et la validation.
Licence MIT ;
[PyPI](https://pypi.org/project/facturx-api/),
[npm](https://www.npmjs.com/package/@facturxapi/sdk),
[code source](https://github.com/facturxapi/sdk).
PHP, Laravel, .NET et Dolibarr : l'appel REST est décrit dans les guides
[PHP](https://facturxapi.com/integrations/php), [Laravel](https://facturxapi.com/integrations/laravel), [.NET](https://facturxapi.com/integrations/dotnet) et
[Dolibarr](https://facturxapi.com/integrations/dolibarr).

Versions 0.1.2, statut alpha. Les exemples ci-dessous appellent l'API directement : curl et Node.js.
Depuis la 0.1.2, les clients appellent par défaut la production (`https://api.facturxapi.com`) ; l'adresse se change avec `base_url` ou `FACTURX_BASE_URL`, en `https`. Python 3.10 ou plus, avec la commande `facturx` (`dry-run`, `convert`, `validate`) ;
Node.js en modules ESM, avec les types TypeScript.

### Votre ERP reste la source

Réutilisez les données structurées déjà présentes dans votre système, sans ressaisie dans un éditeur de facture séparé.

### Deux livrables au choix

Demandez le PDF/A-3 Factur-X avec son XML embarqué, ou seulement le XML CII quand votre flux n’a pas besoin de PDF.

### Des contrôles nommés

La réponse sépare la production du fichier, la validation EN16931 et les contrôles des règles françaises réellement exécutés.

### Une limite sans ambiguïté

L’API produit et contrôle le document. Elle ne le transmet pas et ne prétend pas prouver son acceptation par une Plateforme Agréée.

### Référence d’intégration

Cette page suit le contrat public `/api/v1`. Pour vérifier un champ avant intégration, ouvrez le [contrat d’intégration interactif](https://facturxapi.com/docs/integration-contract) ou consultez le [JSON /api/v1/integration-contract](https://api.facturxapi.com/api/v1/integration-contract). Si une valeur `invoice_data` est refusée avec `422 invalid_invoice_data`, corrigez le champ nommé et vérifiez la version exposée par `GET https://api.facturxapi.com/meta` (à la racine de l’hôte : `/api/v1/meta` n’existe pas). Les autres codes 422 ont leur remédiation dans la section Erreurs fréquentes. En cas de doute, transmettez au support le champ, le code retourné et la version API appelée.

### Formats à ne pas confondre

- XML CII seul : fichier XML sans conteneur PDF, demandé avec `output=xml_cii`. Avec un `invoice_data` complet, le PDF source est optionnel. Ce livrable ne doit pas être présenté comme un Factur-X.
- Factur-X PDF/A-3 : PDF lisible avec XML CII embarqué. Demandez-le avec `output=facturx_pdfa3`, ou omettez `output` puisque c’est la sortie par défaut.
- UBL en sortie : non supporté aujourd’hui par /convert (les deux sorties sont le XML CII et le Factur-X PDF/A-3). C’est un chantier séparé, même si UBL est une syntaxe EN16931 dans d’autres contextes.
- UBL en entrée : un UBL Invoice, ou CreditNote dans les mêmes limites, est accepté en entrée de /convert : avec `output=xml_cii`, l’API rend un XML CII EN16931 validé, sans PDF. Le mapping UBL → CII est strict : un champ non repris est refusé (`422 ubl_source_mapping_unsupported`, avec `unsupportedFields`) et un refus ne consomme aucune facture. Un Factur-X PDF/A-3 depuis un UBL seul n’est pas garanti : il dépend du déploiement (sinon `422 ubl_pdf_carrier_required`), à vérifier. `invoice_data` ne se combine pas avec un UBL. Un diagnostic `ubl_source_mapping_unsupported` ou un détail `unsupportedFields` relève d’une source UBL ou de son mapping, pas d’un champ `invoice_data` de ce guide. Conditions complètes : [documentation de l’API](https://facturxapi.com/docs).
- PA/SC : /convert ne réalise ni routage réglementaire, ni dépôt, ni acceptation PA.

### Premier appel : XML CII depuis votre JSON ERP

La clé API s'envoie en header `X-API-Key` (recommandé pour une clé statique ERP) ou, à l'identique, en `Authorization: Bearer <clé>` — les deux fonctionnent. Définissez votre clé API dans `FACTURX_API_KEY`, puis gardez la même clé d’idempotence uniquement pour rejouer la même requête complète. Utilisez une nouvelle clé si le fichier, le JSON, la sortie, la cible de validation, les options, un complément inline ou un sélecteur de profil enregistré (`profile_reuse`, `issuer_id`/`client_id`, `seller_profile_id`/`buyer_profile_id`) changent. Comportement vérifié en production : une requête différente sous la même clé est refusée en `409 idempotency_conflict` sans exécution ni consommation de quota ; une clé rejouée pendant le traitement répond `409 idempotency_in_progress` — attendez la fin du premier appel plutôt que de rejouer en boucle.
Ces exemples demandent les règles françaises de la facture électronique (`validation_target=france_2026`), et le JSON d’exemple porte les mentions `document_notes` PMT, PMD et AAB et des adresses électroniques du vendeur et de l’acheteur. Choisissez `en16931` seulement pour contrôler le socle européen seul : un fichier vérifié en `en16931` n’a pas évalué les contrôles des règles françaises.
Pour un flux ERP sans conteneur PDF, demandez explicitement `output=xml_cii` avec un `invoice_data` complet. Le résultat est un XML CII, pas un document Factur-X.

```
curl -X POST https://api.facturxapi.com/api/v1/convert \
  -H "Authorization: Bearer $FACTURX_API_KEY" \
  -H "Idempotency-Key: erp-fa-2026-042-xml-v1" \
  -F "output=xml_cii" \
  -F "validation_target=france_2026" \
  -F 'invoice_data={
  "invoice_number": "FA-2026-042",
  "issue_date": "2026-04-01",
  "invoice_type": "380",
  "currency": "EUR",
  "business_process": "S1",
  "document_notes": [
    {
      "subject_code": "PMT",
      "content": "Indemnite forfaitaire de recouvrement de 40 EUR due en cas de retard de paiement"
    },
    {
      "subject_code": "PMD",
      "content": "Penalites de retard exigibles selon les conditions contractuelles"
    },
    {
      "subject_code": "AAB",
      "content": "Aucun escompte pour paiement anticipe"
    }
  ],
  "seller": {
    "name": "Ma Societe SAS",
    "siret": "99999123500014",
    "vat_id": "FR09999991235",
    "electronic_address": {
      "value": "FRROUTESELLER001",
      "scheme_id": "0225"
    },
    "address": {
      "street": "10 rue de Rivoli",
      "city": "Paris",
      "postal_code": "75001",
      "country": "FR"
    }
  },
  "buyer": {
    "name": "Client SA",
    "siret": "99999245600015",
    "electronic_address": {
      "value": "FRROUTEBUYER001",
      "scheme_id": "0225"
    },
    "address": {
      "street": "20 rue de la Republique",
      "city": "Lyon",
      "postal_code": "69002",
      "country": "FR"
    }
  },
  "payer": {
    "name": "OPCO Formation SA",
    "postal_address": {
      "street": "12 rue de la Formation",
      "city": "Paris",
      "postal_code": "75008",
      "country": "FR"
    },
    "email": "facturation@opco.example",
    "electronic_address": {
      "value": "FRROUTEOPCO001",
      "scheme_id": "0225"
    }
  },
  "references": {
    "buyer_reference": "SERVICE-ACHATS",
    "purchase_order_reference": "PO-2026-0017",
    "contract_reference": "CTR-2026-04"
  },
  "totals": {
    "net": "970.00",
    "tax": "194.00",
    "gross": "1164.00",
    "prepaid_amount": "100.00",
    "rounding_amount": "0.00",
    "due": "1064.00"
  },
  "tax_breakdown": [
    {
      "rate": "20.00",
      "category": "S",
      "base": "970.00",
      "amount": "194.00"
    }
  ],
  "line_items": [
    {
      "number": "1",
      "description": "Prestation conseil",
      "quantity": "10",
      "unit": "C62",
      "unit_price": "100.00",
      "net_amount": "970.00",
      "vat_rate": "20.00",
      "vat_category": "S",
      "purchase_order_line_reference": "10",
      "gross_unit_price": "120.00",
      "price_discount": "20.00",
      "allowances": [
        {
          "amount": "50.00",
          "reason": "Remise ligne",
          "reason_code": "95"
        }
      ],
      "charges": [
        {
          "amount": "20.00",
          "reason": "Supplement urgent"
        }
      ]
    }
  ],
  "payment": {
    "due_date": "2026-05-01",
    "terms": "Paiement a 30 jours",
    "iban": "FR7630006000011234567890189"
  },
  "delivery": {
    "date": "2026-04-01",
    "address": {
      "street": "20 rue de la Republique",
      "city": "Lyon",
      "postal_code": "69002",
      "country": "FR"
    }
  },
  "invoicing_period": {
    "start_date": "2026-04-01",
    "end_date": "2026-04-30"
  }
}'
```

#### Factur-X PDF/A-3 depuis le JSON complet

Avec un invoice_data complet, /convert peut générer le Factur-X PDF/A-3 sans fichier PDF fourni : l’API rend le porteur visuel à partir des mêmes données. Si votre ERP dispose déjà d’un PDF, vous pouvez aussi le fournir comme porteur. Le PDF produit contient le XML CII embarqué. Pour un flux avec PDF existant, vous pouvez aussi essayer la conversion depuis [l’outil en ligne /convert](https://facturxapi.com/convert).

```
curl -X POST https://api.facturxapi.com/api/v1/convert \
  -H "Authorization: Bearer $FACTURX_API_KEY" \
  -H "Idempotency-Key: erp-fa-2026-042-v1" \
  -F "output=facturx_pdfa3" \
  -F "validation_target=france_2026" \
  -F 'invoice_data={
  "invoice_number": "FA-2026-042",
  "issue_date": "2026-04-01",
  "invoice_type": "380",
  "currency": "EUR",
  "business_process": "S1",
  "document_notes": [
    {
      "subject_code": "PMT",
      "content": "Indemnite forfaitaire de recouvrement de 40 EUR due en cas de retard de paiement"
    },
    {
      "subject_code": "PMD",
      "content": "Penalites de retard exigibles selon les conditions contractuelles"
    },
    {
      "subject_code": "AAB",
      "content": "Aucun escompte pour paiement anticipe"
    }
  ],
  "seller": {
    "name": "Ma Societe SAS",
    "siret": "99999123500014",
    "vat_id": "FR09999991235",
    "electronic_address": {
      "value": "FRROUTESELLER001",
      "scheme_id": "0225"
    },
    "address": {
      "street": "10 rue de Rivoli",
      "city": "Paris",
      "postal_code": "75001",
      "country": "FR"
    }
  },
  "buyer": {
    "name": "Client SA",
    "siret": "99999245600015",
    "electronic_address": {
      "value": "FRROUTEBUYER001",
      "scheme_id": "0225"
    },
    "address": {
      "street": "20 rue de la Republique",
      "city": "Lyon",
      "postal_code": "69002",
      "country": "FR"
    }
  },
  "payer": {
    "name": "OPCO Formation SA",
    "postal_address": {
      "street": "12 rue de la Formation",
      "city": "Paris",
      "postal_code": "75008",
      "country": "FR"
    },
    "email": "facturation@opco.example",
    "electronic_address": {
      "value": "FRROUTEOPCO001",
      "scheme_id": "0225"
    }
  },
  "references": {
    "buyer_reference": "SERVICE-ACHATS",
    "purchase_order_reference": "PO-2026-0017",
    "contract_reference": "CTR-2026-04"
  },
  "totals": {
    "net": "970.00",
    "tax": "194.00",
    "gross": "1164.00",
    "prepaid_amount": "100.00",
    "rounding_amount": "0.00",
    "due": "1064.00"
  },
  "tax_breakdown": [
    {
      "rate": "20.00",
      "category": "S",
      "base": "970.00",
      "amount": "194.00"
    }
  ],
  "line_items": [
    {
      "number": "1",
      "description": "Prestation conseil",
      "quantity": "10",
      "unit": "C62",
      "unit_price": "100.00",
      "net_amount": "970.00",
      "vat_rate": "20.00",
      "vat_category": "S",
      "purchase_order_line_reference": "10",
      "gross_unit_price": "120.00",
      "price_discount": "20.00",
      "allowances": [
        {
          "amount": "50.00",
          "reason": "Remise ligne",
          "reason_code": "95"
        }
      ],
      "charges": [
        {
          "amount": "20.00",
          "reason": "Supplement urgent"
        }
      ]
    }
  ],
  "payment": {
    "due_date": "2026-05-01",
    "terms": "Paiement a 30 jours",
    "iban": "FR7630006000011234567890189"
  },
  "delivery": {
    "date": "2026-04-01",
    "address": {
      "street": "20 rue de la Republique",
      "city": "Lyon",
      "postal_code": "69002",
      "country": "FR"
    }
  },
  "invoicing_period": {
    "start_date": "2026-04-01",
    "end_date": "2026-04-30"
  }
}'
```

### Exemple Node minimal

Le code ci-dessous illustre l’appel HTTP et vérifie, avant le renommage atomique, que la taille reçue correspond à `result.pdfSize` ou à la taille annoncée par le serveur de téléchargement. Ce contrôle porte sur l’intégrité du transfert, pas sur toute la structure interne du PDF. Votre intégration doit construire `invoiceData` depuis votre ERP.

```
import { createHash } from "node:crypto";
import { rename, rm, writeFile } from "node:fs/promises";

// FACTURX_OPERATION_KEY_START
function facturxOperationKey(output, target, invoiceJson, fileDigest = '') {
  const operationIdentity = createHash('sha256')
    .update([output, target, invoiceJson, fileDigest].join('\0'))
    .digest('hex');
  return `convert-${operationIdentity}`;
}
// FACTURX_OPERATION_KEY_END

const MAX_PDF_BYTES = 10 * 1024 * 1024;
const MAX_BASE64_PDF_CHARACTERS = Math.ceil(MAX_PDF_BYTES / 3) * 4;

async function downloadPdf(urlValue) {
  const url = new URL(urlValue);
  if (url.protocol !== "https:" || url.username || url.password) {
    throw new Error("L'URL de téléchargement du PDF doit être une URL HTTPS sans identifiants");
  }

  const downloadResponse = await fetch(url, { redirect: "error" });
  if (!downloadResponse.ok) {
    throw new Error(`Le téléchargement du PDF a échoué (HTTP ${downloadResponse.status})`);
  }

  const contentLength = downloadResponse.headers.get("content-length");
  if (contentLength === null) {
    throw new Error("Le serveur de téléchargement n'annonce pas la taille du PDF");
  }
  const announcedBytes = Number(contentLength);
  if (!Number.isSafeInteger(announcedBytes) || announcedBytes <= 0 || announcedBytes > MAX_PDF_BYTES) {
    throw new Error("La taille annoncée du PDF est invalide ou dépasse 10 Mo");
  }
  if (!downloadResponse.body) {
    throw new Error("Le téléchargement du PDF ne contient aucun corps de réponse");
  }

  const chunks = [];
  let receivedBytes = 0;
  const reader = downloadResponse.body.getReader();
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    receivedBytes += value.byteLength;
    if (receivedBytes > MAX_PDF_BYTES) {
      await reader.cancel();
      throw new Error("Le PDF téléchargé dépasse 10 Mo");
    }
    chunks.push(Buffer.from(value));
  }

  return { pdfBytes: Buffer.concat(chunks, receivedBytes), expectedBytes: announcedBytes };
}

function decodeInlinePdf(encodedPdf) {
  const strictBase64 = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
  if (encodedPdf.length % 4 !== 0 || !strictBase64.test(encodedPdf)) {
    throw new Error("Le PDF encodé n'est pas un base64 canonique");
  }

  const decodedPdf = Buffer.from(encodedPdf, "base64");
  if (decodedPdf.toString("base64") !== encodedPdf) {
    throw new Error("Le PDF encodé n'est pas un base64 canonique");
  }
  return decodedPdf;
}

function assertPdfIntegrity(pdfBytes, expectedBytes) {
  const header = pdfBytes.subarray(0, 8).toString("ascii");
  if (
    !Number.isSafeInteger(expectedBytes) ||
    expectedBytes <= 0 ||
    expectedBytes > MAX_PDF_BYTES ||
    pdfBytes.length !== expectedBytes ||
    !/^%PDF-(?:1\.[0-7]|2\.0)$/.test(header)
  ) {
    throw new Error("La signature ou la taille du PDF ne correspond pas au livrable annoncé");
  }
}

const invoiceData = {
  "invoice_number": "FA-2026-042",
  "issue_date": "2026-04-01",
  "invoice_type": "380",
  "currency": "EUR",
  "business_process": "S1",
  "document_notes": [
    {
      "subject_code": "PMT",
      "content": "Indemnite forfaitaire de recouvrement de 40 EUR due en cas de retard de paiement"
    },
    {
      "subject_code": "PMD",
      "content": "Penalites de retard exigibles selon les conditions contractuelles"
    },
    {
      "subject_code": "AAB",
      "content": "Aucun escompte pour paiement anticipe"
    }
  ],
  "seller": {
    "name": "Ma Societe SAS",
    "siret": "99999123500014",
    "vat_id": "FR09999991235",
    "electronic_address": {
      "value": "FRROUTESELLER001",
      "scheme_id": "0225"
    },
    "address": {
      "street": "10 rue de Rivoli",
      "city": "Paris",
      "postal_code": "75001",
      "country": "FR"
    }
  },
  "buyer": {
    "name": "Client SA",
    "siret": "99999245600015",
    "electronic_address": {
      "value": "FRROUTEBUYER001",
      "scheme_id": "0225"
    },
    "address": {
      "street": "20 rue de la Republique",
      "city": "Lyon",
      "postal_code": "69002",
      "country": "FR"
    }
  },
  "payer": {
    "name": "OPCO Formation SA",
    "postal_address": {
      "street": "12 rue de la Formation",
      "city": "Paris",
      "postal_code": "75008",
      "country": "FR"
    },
    "email": "facturation@opco.example",
    "electronic_address": {
      "value": "FRROUTEOPCO001",
      "scheme_id": "0225"
    }
  },
  "references": {
    "buyer_reference": "SERVICE-ACHATS",
    "purchase_order_reference": "PO-2026-0017",
    "contract_reference": "CTR-2026-04"
  },
  "totals": {
    "net": "970.00",
    "tax": "194.00",
    "gross": "1164.00",
    "prepaid_amount": "100.00",
    "rounding_amount": "0.00",
    "due": "1064.00"
  },
  "tax_breakdown": [
    {
      "rate": "20.00",
      "category": "S",
      "base": "970.00",
      "amount": "194.00"
    }
  ],
  "line_items": [
    {
      "number": "1",
      "description": "Prestation conseil",
      "quantity": "10",
      "unit": "C62",
      "unit_price": "100.00",
      "net_amount": "970.00",
      "vat_rate": "20.00",
      "vat_category": "S",
      "purchase_order_line_reference": "10",
      "gross_unit_price": "120.00",
      "price_discount": "20.00",
      "allowances": [
        {
          "amount": "50.00",
          "reason": "Remise ligne",
          "reason_code": "95"
        }
      ],
      "charges": [
        {
          "amount": "20.00",
          "reason": "Supplement urgent"
        }
      ]
    }
  ],
  "payment": {
    "due_date": "2026-05-01",
    "terms": "Paiement a 30 jours",
    "iban": "FR7630006000011234567890189"
  },
  "delivery": {
    "date": "2026-04-01",
    "address": {
      "street": "20 rue de la Republique",
      "city": "Lyon",
      "postal_code": "69002",
      "country": "FR"
    }
  },
  "invoicing_period": {
    "start_date": "2026-04-01",
    "end_date": "2026-04-30"
  }
};

const output = "facturx_pdfa3";
const validationTarget = "france_2026";
const invoiceJson = JSON.stringify(invoiceData);
// Une clé par opération : la même requête rejouée garde sa clé ; une autre facture, un avoir ou une correction en a une autre.
const idempotencyKey = facturxOperationKey(output, validationTarget, invoiceJson);

const form = new FormData();
form.set("output", output);
form.set("validation_target", validationTarget);
form.set("invoice_data", invoiceJson);

const response = await fetch("https://api.facturxapi.com/api/v1/convert", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.FACTURX_API_KEY}`,
    "Idempotency-Key": idempotencyKey,
  },
  body: form,
});

const responseBody = await response.json();
if (!response.ok) {
  throw new Error(JSON.stringify(responseBody));
}

const targetStatus = responseBody.target?.status;
const result = responseBody.result;
if (!["verified", "incomplete"].includes(targetStatus)) {
  throw new Error(JSON.stringify(responseBody));
}
const hasInlinePdf = typeof result?.pdf === "string" && result.pdf.length > 0;
const hasRemotePdf = typeof result?.pdfUrl === "string" && result.pdfUrl.length > 0;
if (result?.packagingPerformed !== true || hasInlinePdf === hasRemotePdf) {
  throw new Error("Le PDF Factur-X n'est pas disponible dans cette réponse");
}
if (hasInlinePdf && result.pdf.length > MAX_BASE64_PDF_CHARACTERS) {
  throw new Error("Le PDF encodé dépasse 10 Mo");
}

const finalPath = "./facture-facturx.pdf";
const temporaryPath = `${finalPath}.tmp-${process.pid}`;
const { pdfBytes, expectedBytes } = hasInlinePdf
  ? { pdfBytes: decodeInlinePdf(result.pdf), expectedBytes: result.pdfSize }
  : await downloadPdf(result.pdfUrl);
assertPdfIntegrity(pdfBytes, expectedBytes);
try {
  await writeFile(temporaryPath, pdfBytes, { flag: "wx" });
  await rename(temporaryPath, finalPath);
} finally {
  await rm(temporaryPath, { force: true });
}

if (targetStatus === "incomplete") {
  const reservations = result.validationReadiness?.frCtc?.advisories ?? responseBody.warnings ?? [];
  console.warn("Fichier généré avec réserves — à traiter avant transmission", reservations);
}
```

### JSON d’entrée

Exemple synthétique pour `invoice_data`. Il couvre les zones les plus utiles pour un premier test ERP/GED : parties, références, totaux de paiement, remises/charges, ventilation TVA, livraison, période de facturation et tarification ligne.

```
{
  "invoice_number": "FA-2026-042",
  "issue_date": "2026-04-01",
  "invoice_type": "380",
  "currency": "EUR",
  "business_process": "S1",
  "document_notes": [
    {
      "subject_code": "PMT",
      "content": "Indemnite forfaitaire de recouvrement de 40 EUR due en cas de retard de paiement"
    },
    {
      "subject_code": "PMD",
      "content": "Penalites de retard exigibles selon les conditions contractuelles"
    },
    {
      "subject_code": "AAB",
      "content": "Aucun escompte pour paiement anticipe"
    }
  ],
  "seller": {
    "name": "Ma Societe SAS",
    "siret": "99999123500014",
    "vat_id": "FR09999991235",
    "electronic_address": {
      "value": "FRROUTESELLER001",
      "scheme_id": "0225"
    },
    "address": {
      "street": "10 rue de Rivoli",
      "city": "Paris",
      "postal_code": "75001",
      "country": "FR"
    }
  },
  "buyer": {
    "name": "Client SA",
    "siret": "99999245600015",
    "electronic_address": {
      "value": "FRROUTEBUYER001",
      "scheme_id": "0225"
    },
    "address": {
      "street": "20 rue de la Republique",
      "city": "Lyon",
      "postal_code": "69002",
      "country": "FR"
    }
  },
  "payer": {
    "name": "OPCO Formation SA",
    "postal_address": {
      "street": "12 rue de la Formation",
      "city": "Paris",
      "postal_code": "75008",
      "country": "FR"
    },
    "email": "facturation@opco.example",
    "electronic_address": {
      "value": "FRROUTEOPCO001",
      "scheme_id": "0225"
    }
  },
  "references": {
    "buyer_reference": "SERVICE-ACHATS",
    "purchase_order_reference": "PO-2026-0017",
    "contract_reference": "CTR-2026-04"
  },
  "totals": {
    "net": "970.00",
    "tax": "194.00",
    "gross": "1164.00",
    "prepaid_amount": "100.00",
    "rounding_amount": "0.00",
    "due": "1064.00"
  },
  "tax_breakdown": [
    {
      "rate": "20.00",
      "category": "S",
      "base": "970.00",
      "amount": "194.00"
    }
  ],
  "line_items": [
    {
      "number": "1",
      "description": "Prestation conseil",
      "quantity": "10",
      "unit": "C62",
      "unit_price": "100.00",
      "net_amount": "970.00",
      "vat_rate": "20.00",
      "vat_category": "S",
      "purchase_order_line_reference": "10",
      "gross_unit_price": "120.00",
      "price_discount": "20.00",
      "allowances": [
        {
          "amount": "50.00",
          "reason": "Remise ligne",
          "reason_code": "95"
        }
      ],
      "charges": [
        {
          "amount": "20.00",
          "reason": "Supplement urgent"
        }
      ]
    }
  ],
  "payment": {
    "due_date": "2026-05-01",
    "terms": "Paiement a 30 jours",
    "iban": "FR7630006000011234567890189"
  },
  "delivery": {
    "date": "2026-04-01",
    "address": {
      "street": "20 rue de la Republique",
      "city": "Lyon",
      "postal_code": "69002",
      "country": "FR"
    }
  },
  "invoicing_period": {
    "start_date": "2026-04-01",
    "end_date": "2026-04-30"
  }
}
```

#### Formats attendus

- Pays : Code ISO 3166-1 alpha-2, deux lettres : « FR », « DE ». Jamais le nom du pays (« France »). Exemple : `"country": "FR"`. Champs : `seller.address.country`, `buyer.address.country`, `delivery.address.country`, `payer.postal_address.country`.

- Dates : AAAA-MM-JJ (ISO 8601) : « 2026-01-15 ». Ces champs refusent JJ/MM/AAAA et une heure. payment.due_date n’a pas ce motif à l’entrée : la conversion le refuse pourtant en 422 invalid_invoice_data s’il n’est pas une date calendaire AAAA-MM-JJ (année 1900 à 2100). Exemple : `"issue_date": "2026-01-15"`. Champs : `issue_date`, `delivery.date`, `invoice_reference_issue_date`, `vat_point_date`, `invoicing_period.start_date`, `invoicing_period.end_date`, `line_items[].period.start_date`, `line_items[].period.end_date`.

- Facture d’origine d’un avoir (BT-25) : Le numéro exact de la facture d’origine, tel qu’il y est écrit : lettres, chiffres et + - _ /, sans espace ni phrase ; 35 caractères au plus pour les règles françaises (règles BR-FR-01 et BR-FR-02). L’API accepte jusqu’à 100 caractères en entrée. Exemple : `"invoice_reference": "FA-2026-001"`. Champs : `invoice_reference`, `invoice_patch.preceding_invoice.reference`.

Un format refusé répond en erreur : voir [Lire un refus 422](https://facturxapi.com/docs#read-422-refusal) dans /docs.

#### Champs utilisables dans invoice_data

Pour explorer chaque champ avec sa règle EN16931 ou française, son XPath CII et un exemple, et pour valider un JSON en direct, ouvrez le [contrat d'intégration interactif](https://facturxapi.com/docs/integration-contract).

- Requis : champ que le schéma d’entrée exige (sans lui, l’appel est refusé en 422).
- Socle EN16931 : champ que le contrat classe au niveau EN16931 ; le contrat ne l’exige pas pour tout document, et un astérisque signale une exigence qui dépend du cas.
- Règles françaises : champ que le contrat classe au niveau des règles françaises de la facture électronique.
- Transmission (règles françaises) : champ que le contrat classe au niveau transmission ; son absence ne bloque pas la génération.
- Optionnel : hors des niveaux du contrat.
- Ces niveaux sont lus dans le contrat d’intégration, pas écrits à la main.
invoice_number +

Rôle Numéro facture

BT/BG BT-1

Requis Requis

Disponibilité Disponible

issue_date +

Rôle Date émission

BT/BG BT-2

Requis Requis

Disponibilité Disponible ; format AAAA-MM-JJ

invoice_type +

Rôle Type document

BT/BG BT-3

Requis Socle EN16931

Disponibilité Disponible

currency +

Rôle Devise

BT/BG BT-5

Requis Socle EN16931

Disponibilité Disponible

business_process +

Rôle Cadre de facturation / processus métier

BT/BG BT-23

Requis Transmission (règles françaises)

Disponibilité Disponible ; 20 codes acceptés (contrat d’intégration) ; l’exemple utilise S1, qui décrit des services seuls : choisissez le code du processus réel de votre facture

seller.name +

Rôle Nom vendeur

BT/BG BT-27

Requis Requis

Disponibilité Disponible

seller.siret +

Rôle Identifiant vendeur

BT/BG BT-29

Requis Socle EN16931

Disponibilité Disponible ; le SIREN (BT-30) est calculé pour le vendeur FR

seller.vat_id +

Rôle TVA intracom vendeur

BT/BG BT-31

Requis Socle EN16931

Disponibilité Disponible

seller.tax_registration_id +

Rôle Identifiant fiscal vendeur hors TVA

BT/BG BT-32

Requis Socle EN16931

Disponibilité Disponible pour les cas IGIC/IPSI

seller.address.street / city / postal_code / country +

Rôle Adresse postale vendeur

BT/BG BT-35 / BT-37 / BT-38 / BT-40

Requis Requis : country · Socle EN16931 : street, city, postal_code

Disponibilité Disponible pour EN16931 ; country est requis, code ISO 3166-1 alpha-2 (« FR », jamais « France »)

seller.electronic_address.value / scheme_id +

Rôle Adresse électronique vendeur

BT/BG BT-34

Requis Règles françaises : value*, scheme_id*

Disponibilité Disponible ; utilisez uniquement un identifiant de routage confirmé

buyer.name +

Rôle Nom acheteur

BT/BG BT-44

Requis Requis

Disponibilité Disponible

buyer.siret +

Rôle Identifiant acheteur

BT/BG BT-46 + BT-47 SIREN calculé

Requis Socle EN16931

Disponibilité Disponible ; le SIREN est déduit du SIRET

buyer.address.street / city / postal_code / country +

Rôle Adresse postale acheteur

BT/BG BT-50 / BT-52 / BT-53 / BT-55

Requis Requis : country · Socle EN16931 : street, city, postal_code

Disponibilité Disponible pour EN16931 ; country est requis, code ISO 3166-1 alpha-2 (« FR », jamais « France »)

buyer.electronic_address.value / scheme_id +

Rôle Adresse électronique acheteur

BT/BG BT-49

Requis Règles françaises : value*, scheme_id*

Disponibilité Disponible ; utilisez uniquement un identifiant de routage confirmé

references.buyer_reference / purchase_order_reference / contract_reference / project_reference / despatch_advice_reference / receiving_advice_reference / buyer_accounting_reference +

Rôle Références acheteur, commande, contrat, projet, avis

BT/BG BT-10 / BT-11 / BT-12 / BT-13 / BT-15 / BT-16 / BT-19

Requis Optionnel : buyer_reference, purchase_order_reference, contract_reference, project_reference, despatch_advice_reference, receiving_advice_reference, buyer_accounting_reference

Disponibilité Disponible

invoice_reference / invoice_reference_issue_date +

Rôle Facture précédente pour un avoir ou une correction

BT/BG BT-25 / BT-26 / BG-3

Requis Règles françaises : invoice_reference_issue_date · Optionnel : invoice_reference

Disponibilité Disponible pour les types 381 et 384 ; invoice_reference = le numéro exact de la facture d’origine (lettres, chiffres et + - _ /, sans espace ni phrase ; 35 caractères au plus pour les règles françaises), invoice_reference_issue_date au format AAAA-MM-JJ

document_notes[].content / subject_code +

Rôle Notes de document et mentions PMT, PMD ou AAB

BT/BG BT-22 / BT-21

Requis Socle EN16931 : subject_code · Règles françaises : content*

Disponibilité Disponible ; subject_code est optionnel, mais limité à PMT, PMD ou AAB lorsqu’il est fourni

totals.net / totals.tax / totals.gross +

Rôle Totaux HT, TVA, TTC

BT/BG BT-109 / BT-110 / BT-112

Requis Requis : net, tax, gross

Disponibilité Disponible

totals.prepaid_amount / totals.rounding_amount / totals.due +

Rôle Acompte, arrondi, net à payer

BT/BG BT-113 / BT-114 / BT-115

Requis Socle EN16931 : prepaid_amount, rounding_amount, due

Disponibilité Disponible

allowances[] / charges[] +

Rôle Remises et charges au niveau document

BT/BG BG-20 / BG-21

Requis Socle EN16931 : amount*, base_amount, reason, reason_code, vat_category, vat_rate

Disponibilité Disponible

tax_breakdown[] +

Rôle Ventilation TVA fournie par votre ERP

BT/BG BG-23

Requis Requis : rate, base, amount · Socle EN16931 : category

Disponibilité Disponible

tax_breakdown[].exemption_reason / exemption_reason_code +

Rôle Motif ou code exonération par ventilation TVA

BT/BG BT-120 / BT-121

Requis Socle EN16931 : exemption_reason_code · Optionnel : exemption_reason

Disponibilité Disponible pour toutes les catégories exonérantes (E, AE, K, G, O), y compris les mélanges — en multi-catégories, le motif par ventilation est requis

vat_exemption_reason / vat_exemption_code +

Rôle Motif ou code exonération global

BT/BG BT-120 / BT-121

Requis Socle EN16931 : vat_exemption_reason, vat_exemption_code

Disponibilité Disponible seulement si une seule catégorie exonérante le porte

line_items[] +

Rôle Lignes facture

BT/BG BG-25

Requis Requis : number, description, quantity, unit_price, net_amount, vat_rate · Socle EN16931 : vat_category · Optionnel : unit

Disponibilité Disponible

line_items[].purchase_order_line_reference / buyer_accounting_reference +

Rôle Références ligne

BT/BG BT-132 / BT-133

Requis Optionnel : purchase_order_line_reference, buyer_accounting_reference

Disponibilité Disponible

line_items[].allowances[] / charges[] +

Rôle Remises et charges de ligne

BT/BG BG-27 / BG-28

Requis Optionnel : amount, base_amount, reason, reason_code

Disponibilité Disponible dans la version API correspondant à cette documentation

line_items[].gross_unit_price (BT-148) / price_discount (BT-147) +

Rôle Prix brut et remise de prix

BT/BG BT-148 / BT-147

Requis Optionnel : gross_unit_price, price_discount

Disponibilité Disponible dans la version API correspondant à cette documentation

payment.due_date / payment.terms / payment.iban / payment.bic +

Rôle Échéance et paiement (compte crédité)

BT/BG BT-9 / BT-20 / BT-84 / BT-86

Requis Socle EN16931 : due_date, terms, iban · Optionnel : bic

Disponibilité Disponible ; due_date doit être une date calendaire AAAA-MM-JJ (année 1900 à 2100). Le schéma d’entrée n’a pas le motif des autres dates : une autre écriture répond 422 invalid_invoice_data.

payment.means_code +

Rôle Code moyen de paiement

BT/BG BT-81

Requis Socle EN16931

Disponibilité Disponible

payment.account_proprietary_id +

Rôle Identifiant de compte propriétaire (sans IBAN)

BT/BG BT-84

Requis Socle EN16931

Disponibilité Disponible : IBAN ou identifiant de compte propriétaire, au choix (CII-SR-470)

payment.account_name +

Rôle Nom du compte de paiement

BT/BG BT-85

Requis Optionnel

Disponibilité Disponible ; requiert iban ou account_proprietary_id

payment.mandate_reference +

Rôle Référence de mandat SEPA (prélèvement)

BT/BG BT-89

Requis Optionnel

Disponibilité Disponible ; cohérent seulement avec means_code 49 ou 59

payment.debtor_account_iban +

Rôle IBAN du compte débité (prélèvement acheteur)

BT/BG BT-91

Requis Socle EN16931

Disponibilité Disponible ; cohérent seulement avec means_code 49 ou 59 — ce n’est pas l’IBAN du factor

payment.creditor_sepa_identifier +

Rôle Identifiant créancier SEPA (ICS)

BT/BG BT-90

Requis Optionnel

Disponibilité Disponible ; cohérent seulement avec means_code 49 ou 59

payee.name / payee.identifier +

Rôle Bénéficiaire / factor (payee déviant du seller)

BT/BG BT-59 / BT-60 / BG-10

Requis Socle EN16931 : name* · Optionnel : identifier

Disponibilité Disponible ; le payee doit différer du seller (BR-17)

payer.name / payer.global_id / payer.legal_registration / payer.postal_address / payer.email / payer.electronic_address +

Rôle Tiers payeur distinct de l’acheteur et du bénéficiaire

BT/BG EXT-FR-FE-BG-02

Requis Règles françaises : value*, scheme_id* · Optionnel : name, value, scheme_id, country, street, city, postal_code, email

Disponibilité Disponible ; name est requis si payer est fourni ; postal_address.country est requis avec une adresse postale ; email est un contact, distinct de l’identifiant de routage electronic_address { value, scheme_id } ; la sortie effective passe au profil EXTENDED

delivery.date / delivery.address +

Rôle Livraison et adresse de livraison

BT/BG BT-72 / BG-13

Requis Socle EN16931 : date, country* · Optionnel : street, city, postal_code

Disponibilité Disponible ; date au format AAAA-MM-JJ, address.country en code ISO 3166-1 alpha-2

invoicing_period (alias accepté : billing_period) +

Rôle Période de facturation

BT/BG BG-14 / BT-73 / BT-74

Requis Socle EN16931 : start_date · Optionnel : end_date

Disponibilité Disponible ; billing_period est accepté comme alias ; start_date et end_date au format AAAA-MM-JJ

Chemin JSON | Ce que cela renseigne | BT/BG | Requis | Disponibilité |
`invoice_number` | Numéro facture | BT-1 | Requis | Disponible |
`issue_date` | Date émission | BT-2 | Requis | Disponible ; format AAAA-MM-JJ |
`invoice_type` | Type document | BT-3 | Socle EN16931 | Disponible |
`currency` | Devise | BT-5 | Socle EN16931 | Disponible |
`business_process` | Cadre de facturation / processus métier | BT-23 | Transmission (règles françaises) | Disponible ; 20 codes acceptés (contrat d’intégration) ; l’exemple utilise S1, qui décrit des services seuls : choisissez le code du processus réel de votre facture |
`seller.name` | Nom vendeur | BT-27 | Requis | Disponible |
`seller.siret` | Identifiant vendeur | BT-29 | Socle EN16931 | Disponible ; le SIREN (BT-30) est calculé pour le vendeur FR |
`seller.vat_id` | TVA intracom vendeur | BT-31 | Socle EN16931 | Disponible |
`seller.tax_registration_id` | Identifiant fiscal vendeur hors TVA | BT-32 | Socle EN16931 | Disponible pour les cas IGIC/IPSI |
`seller.address.street / city / postal_code / country` | Adresse postale vendeur | BT-35 / BT-37 / BT-38 / BT-40 | Requis : country · Socle EN16931 : street, city, postal_code | Disponible pour EN16931 ; country est requis, code ISO 3166-1 alpha-2 (« FR », jamais « France ») |
`seller.electronic_address.value / scheme_id` | Adresse électronique vendeur | BT-34 | Règles françaises : value*, scheme_id* | Disponible ; utilisez uniquement un identifiant de routage confirmé |
`buyer.name` | Nom acheteur | BT-44 | Requis | Disponible |
`buyer.siret` | Identifiant acheteur | BT-46 + BT-47 SIREN calculé | Socle EN16931 | Disponible ; le SIREN est déduit du SIRET |
`buyer.address.street / city / postal_code / country` | Adresse postale acheteur | BT-50 / BT-52 / BT-53 / BT-55 | Requis : country · Socle EN16931 : street, city, postal_code | Disponible pour EN16931 ; country est requis, code ISO 3166-1 alpha-2 (« FR », jamais « France ») |
`buyer.electronic_address.value / scheme_id` | Adresse électronique acheteur | BT-49 | Règles françaises : value*, scheme_id* | Disponible ; utilisez uniquement un identifiant de routage confirmé |
`references.buyer_reference / purchase_order_reference / contract_reference / project_reference / despatch_advice_reference / receiving_advice_reference / buyer_accounting_reference` | Références acheteur, commande, contrat, projet, avis | BT-10 / BT-11 / BT-12 / BT-13 / BT-15 / BT-16 / BT-19 | Optionnel : buyer_reference, purchase_order_reference, contract_reference, project_reference, despatch_advice_reference, receiving_advice_reference, buyer_accounting_reference | Disponible |
`invoice_reference / invoice_reference_issue_date` | Facture précédente pour un avoir ou une correction | BT-25 / BT-26 / BG-3 | Règles françaises : invoice_reference_issue_date · Optionnel : invoice_reference | Disponible pour les types 381 et 384 ; invoice_reference = le numéro exact de la facture d’origine (lettres, chiffres et + - _ /, sans espace ni phrase ; 35 caractères au plus pour les règles françaises), invoice_reference_issue_date au format AAAA-MM-JJ |
`document_notes[].content / subject_code` | Notes de document et mentions PMT, PMD ou AAB | BT-22 / BT-21 | Socle EN16931 : subject_code · Règles françaises : content* | Disponible ; subject_code est optionnel, mais limité à PMT, PMD ou AAB lorsqu’il est fourni |
`totals.net / totals.tax / totals.gross` | Totaux HT, TVA, TTC | BT-109 / BT-110 / BT-112 | Requis : net, tax, gross | Disponible |
`totals.prepaid_amount / totals.rounding_amount / totals.due` | Acompte, arrondi, net à payer | BT-113 / BT-114 / BT-115 | Socle EN16931 : prepaid_amount, rounding_amount, due | Disponible |
`allowances[] / charges[]` | Remises et charges au niveau document | BG-20 / BG-21 | Socle EN16931 : amount*, base_amount, reason, reason_code, vat_category, vat_rate | Disponible |
`tax_breakdown[]` | Ventilation TVA fournie par votre ERP | BG-23 | Requis : rate, base, amount · Socle EN16931 : category | Disponible |
`tax_breakdown[].exemption_reason / exemption_reason_code` | Motif ou code exonération par ventilation TVA | BT-120 / BT-121 | Socle EN16931 : exemption_reason_code · Optionnel : exemption_reason | Disponible pour toutes les catégories exonérantes (E, AE, K, G, O), y compris les mélanges — en multi-catégories, le motif par ventilation est requis |
`vat_exemption_reason / vat_exemption_code` | Motif ou code exonération global | BT-120 / BT-121 | Socle EN16931 : vat_exemption_reason, vat_exemption_code | Disponible seulement si une seule catégorie exonérante le porte |
`line_items[]` | Lignes facture | BG-25 | Requis : number, description, quantity, unit_price, net_amount, vat_rate · Socle EN16931 : vat_category · Optionnel : unit | Disponible |
`line_items[].purchase_order_line_reference / buyer_accounting_reference` | Références ligne | BT-132 / BT-133 | Optionnel : purchase_order_line_reference, buyer_accounting_reference | Disponible |
`line_items[].allowances[] / charges[]` | Remises et charges de ligne | BG-27 / BG-28 | Optionnel : amount, base_amount, reason, reason_code | Disponible dans la version API correspondant à cette documentation |
`line_items[].gross_unit_price (BT-148) / price_discount (BT-147)` | Prix brut et remise de prix | BT-148 / BT-147 | Optionnel : gross_unit_price, price_discount | Disponible dans la version API correspondant à cette documentation |
`payment.due_date / payment.terms / payment.iban / payment.bic` | Échéance et paiement (compte crédité) | BT-9 / BT-20 / BT-84 / BT-86 | Socle EN16931 : due_date, terms, iban · Optionnel : bic | Disponible ; due_date doit être une date calendaire AAAA-MM-JJ (année 1900 à 2100). Le schéma d’entrée n’a pas le motif des autres dates : une autre écriture répond 422 invalid_invoice_data. |
`payment.means_code` | Code moyen de paiement | BT-81 | Socle EN16931 | Disponible |
`payment.account_proprietary_id` | Identifiant de compte propriétaire (sans IBAN) | BT-84 | Socle EN16931 | Disponible : IBAN ou identifiant de compte propriétaire, au choix (CII-SR-470) |
`payment.account_name` | Nom du compte de paiement | BT-85 | Optionnel | Disponible ; requiert iban ou account_proprietary_id |
`payment.mandate_reference` | Référence de mandat SEPA (prélèvement) | BT-89 | Optionnel | Disponible ; cohérent seulement avec means_code 49 ou 59 |
`payment.debtor_account_iban` | IBAN du compte débité (prélèvement acheteur) | BT-91 | Socle EN16931 | Disponible ; cohérent seulement avec means_code 49 ou 59 — ce n’est pas l’IBAN du factor |
`payment.creditor_sepa_identifier` | Identifiant créancier SEPA (ICS) | BT-90 | Optionnel | Disponible ; cohérent seulement avec means_code 49 ou 59 |
`payee.name / payee.identifier` | Bénéficiaire / factor (payee déviant du seller) | BT-59 / BT-60 / BG-10 | Socle EN16931 : name* · Optionnel : identifier | Disponible ; le payee doit différer du seller (BR-17) |
`payer.name / payer.global_id / payer.legal_registration / payer.postal_address / payer.email / payer.electronic_address` | Tiers payeur distinct de l’acheteur et du bénéficiaire | EXT-FR-FE-BG-02 | Règles françaises : value*, scheme_id* · Optionnel : name, value, scheme_id, country, street, city, postal_code, email | Disponible ; name est requis si payer est fourni ; postal_address.country est requis avec une adresse postale ; email est un contact, distinct de l’identifiant de routage electronic_address { value, scheme_id } ; la sortie effective passe au profil EXTENDED |
`delivery.date / delivery.address` | Livraison et adresse de livraison | BT-72 / BG-13 | Socle EN16931 : date, country* · Optionnel : street, city, postal_code | Disponible ; date au format AAAA-MM-JJ, address.country en code ISO 3166-1 alpha-2 |
`invoicing_period (alias accepté : billing_period)` | Période de facturation | BG-14 / BT-73 / BT-74 | Socle EN16931 : start_date · Optionnel : end_date | Disponible ; billing_period est accepté comme alias ; start_date et end_date au format AAAA-MM-JJ |

#### Compléments pour un document extrait et champs refusés

Pour une source ERP complète, envoyez les adresses électroniques, les notes et la référence de facture précédente directement dans `invoice_data` avec les chemins confirmés ci-dessus. Les racines ci-dessous servent surtout à compléter un PDF ou XML analysé ; les champs réellement non supportés sont refusés explicitement plutôt qu’ignorés.

seller_context.electronic_address / buyer_context.electronic_address +

Rôle Routage France pour un document extrait

BT/BG BT-34 / BT-49

Comment l’envoyer Complément contextuel d’un PDF ou XML analysé ; avec une source ERP complète, utilisez seller.electronic_address et buyer.electronic_address dans invoice_data

seller_context.document_notes[] / buyer_context.document_notes[] +

Rôle Mentions PMT, PMD ou AAB pour un document extrait

BT/BG BT-22 / BT-21

Comment l’envoyer Complément contextuel d’un PDF ou XML analysé ; avec une source ERP complète, utilisez document_notes[] dans invoice_data

invoice_patch.preceding_invoice.reference / issue_date +

Rôle Facture précédente pour un document extrait

BT/BG BT-25 / BT-26

Comment l’envoyer Complément d’un PDF analysé ; invoice_patch ne peut pas être combiné avec un invoice_data complet ; reference = le numéro exact de la facture d’origine (lettres, chiffres et + - _ /, sans espace ni phrase), issue_date au format AAAA-MM-JJ

buyer.tax_registration_id +

Rôle Identifiant fiscal acheteur hors TVA

BT/BG non émis

Comment l’envoyer Refusé explicitement dans invoice_data : BT-32 est vendeur uniquement

Chemin JSON | Ce que cela renseigne | BT/BG | Comment l’envoyer |
`seller_context.electronic_address / buyer_context.electronic_address` | Routage France pour un document extrait | BT-34 / BT-49 | Complément contextuel d’un PDF ou XML analysé ; avec une source ERP complète, utilisez seller.electronic_address et buyer.electronic_address dans invoice_data |
`seller_context.document_notes[] / buyer_context.document_notes[]` | Mentions PMT, PMD ou AAB pour un document extrait | BT-22 / BT-21 | Complément contextuel d’un PDF ou XML analysé ; avec une source ERP complète, utilisez document_notes[] dans invoice_data |
`invoice_patch.preceding_invoice.reference / issue_date` | Facture précédente pour un document extrait | BT-25 / BT-26 | Complément d’un PDF analysé ; invoice_patch ne peut pas être combiné avec un invoice_data complet ; reference = le numéro exact de la facture d’origine (lettres, chiffres et + - _ /, sans espace ni phrase), issue_date au format AAAA-MM-JJ |
`buyer.tax_registration_id` | Identifiant fiscal acheteur hors TVA | non émis | Refusé explicitement dans invoice_data : BT-32 est vendeur uniquement |

#### Exemple de données complémentaires

Quand un diagnostic ou un scan demande de compléter un document analysé, reprenez uniquement les racines indiquées : `invoice_patch`, `seller_context` ou `buyer_context`. `invoice_patch` ne peut pas être combiné avec un `invoice_data` complet ; pour un flux ERP complet, préférez les champs directs de la matrice.

Les valeurs entre chevrons sont des champs à renseigner, pas des valeurs par défaut. Pour le schéma `0225`, utilisez l’identifiant de routage confirmé par votre contexte métier ou par le diagnostic ; ne recopiez pas automatiquement un SIRET.

```
{
  "invoice_patch": {
    "preceding_invoice": {
      "issue_date": "2025-08-31"
    },
    "payment": {
      "iban": "FR7630006000011234567890189"
    }
  },
  "seller_context": {
    "electronic_address": {
      "value": "FRROUTESELLER001",
      "scheme_id": "0225"
    },
    "document_notes": [
      {
        "subject_code": "PMT",
        "content": "Indemnite forfaitaire de recouvrement de 40 EUR due en cas de retard de paiement"
      },
      {
        "subject_code": "PMD",
        "content": "Penalites de retard exigibles selon les conditions contractuelles"
      },
      {
        "subject_code": "AAB",
        "content": "Aucun escompte pour paiement anticipe"
      }
    ]
  },
  "buyer_context": {
    "electronic_address": {
      "value": "FRROUTEBUYER001",
      "scheme_id": "0225"
    }
  }
}
```

### Réponses à gérer

#### Succès XML CII seul

Pour `output=xml_cii`, utilisez `result.xml`. Le PDF est absent et `packagingPerformed=false` ; cette absence est normale pour ce livrable.

```
{
  "success": true,
  "target": {
    "requested": "en16931",
    "executed": "en16931",
    "status": "verified",
    "missing_inputs": [],
    "not_run_reason": null
  },
  "result": {
    "targetProfile": "EN16931",
    "conversionSuccessful": true,
    "xml": "PD94bWwgdmVyc2lvbj0iMS4wIj8+...",
    "xmlSize": 4096,
    "pdf": null,
    "pdfUrl": null,
    "packagingPerformed": false,
    "validation": {
      "valid": true,
      "profile": "EN16931"
    },
    "processedInvoicesCharged": 1,
    "remainingInvoices": 999
  }
}
```

#### PDF/A-3 avec cible vérifiée

`target.status=verified` indique que les contrôles de la cible demandée ont réussi. Vérifiez aussi `packagingPerformed=true` et la présence de `result.pdf` avant de stocker le fichier.

```
{
  "success": true,
  "target": {
    "requested": "en16931",
    "executed": "en16931",
    "status": "verified",
    "missing_inputs": [],
    "not_run_reason": null
  },
  "result": {
    "targetProfile": "EN16931",
    "conversionSuccessful": true,
    "xml": "PD94bWwgdmVyc2lvbj0iMS4wIj8+...",
    "xmlSize": 4096,
    "pdf": "JVBERi0xLjQKJc...",
    "pdfSize": 102400,
    "packagingPerformed": true,
    "validation": {
      "valid": true,
      "profile": "EN16931"
    },
    "processedInvoicesCharged": 1,
    "remainingInvoices": 999
  }
}
```

#### Fichier généré avec réserves

`target.status=incomplete` ne prouve pas la cible complète, même si le PDF et le XML sont livrés et décomptés du quota. Stockez le fichier, conservez les réserves de `validationReadiness` avec lui, puis bloquez sa transmission tant qu'elles ne sont pas traitées.

```
{
  "success": false,
  "target": {
    "requested": "france_2026",
    "executed": "france_2026",
    "status": "incomplete",
    "missing_inputs": [],
    "not_run_reason": null
  },
  "result": {
    "targetProfile": "EN16931",
    "conversionSuccessful": false,
    "xml": "PD94bWwgdmVyc2lvbj0iMS4wIj8+...",
    "pdf": "JVBERi0xLjQKJc...",
    "packagingPerformed": true,
    "validationReadiness": {
      "frCtc": {
        "status": "incomplete",
        "blockers": [],
        "advisories": [
          "BR-FR-05_BT-22_PMT"
        ]
      }
    },
    "processedInvoicesCharged": 1,
    "remainingInvoices": 998
  }
}
```

#### Conversion bloquée

`target.status=blocked` ne doit créer aucun fichier final. Affichez les champs retournés avant un nouvel appel ; une liste non exhaustive ne doit pas être présentée comme une checklist finale.

```
{
  "success": false,
  "target": {
    "requested": "france_2026",
    "executed": null,
    "status": "blocked",
    "missing_inputs": [
      "seller_context.electronic_address.value",
      "buyer_context.electronic_address.value"
    ],
    "not_run_reason": "missing_inputs"
  },
  "verdict": "convert_with_inputs",
  "targetPreflight": {
    "requested": "france_2026",
    "status": "incomplete",
    "exhaustive": false,
    "requiredInputs": [
      {
        "btCode": "BT-34",
        "requestContextPath": "seller_context.electronic_address.value"
      },
      {
        "btCode": "BT-49",
        "requestContextPath": "buyer_context.electronic_address.value"
      }
    ],
    "unsupportedBlockers": []
  }
}
```

### Suivre son quota en production

Quand `/convert` produit un livrable, y compris avec `target.status=incomplete`, lisez les headers `X-Quota-Limit`, `X-Quota-Remaining` et `X-Quota-Reset` quand ils sont présents. Le corps de réponse expose aussi `result.processedInvoicesCharged` et `result.remainingInvoices` ; une valeur `null` signifie que le décompte n'est pas connu au moment de la réponse, pas qu'il est nul.

### Erreurs fréquentes

- `401` : clé absente, invalide ou révoquée. Reprenez la clé depuis [/api-key](https://facturxapi.com/api-key?source=erp_cta) ou [/dashboard/keys](https://facturxapi.com/dashboard/keys).
- `400 file_required_for_pdf_output` : vous demandez le livrable PDF/A-3 sans PDF fourni et sans `invoice_data` complet permettant de rendre le porteur. Fournissez l’une de ces deux sources.
- `400 invalid_options` : `options.mode="xml_only"` n’est pas le sélecteur public du livrable final. Utilisez `output=xml_cii`.
- `400 invalid_invoice_patch` : `invoice_patch` combiné avec un `invoice_data` complet, ou JSON de patch invalide.
- `409 inline_context_conflict` : une valeur inline contredit une valeur visible dans le document.
- `409 idempotency_conflict` : même `Idempotency-Key` rejouée avec une requête différente (fichier, `invoice_data`, sortie, cible ou options modifiés). Action : nouvelle clé. La requête rejouée n'est pas exécutée et ne consomme pas de quota (vérifié en production).
- `409 idempotency_in_progress` : même `Idempotency-Key` et même requête, première requête encore en cours de traitement. Action : attendre puis re-vérifier côté ERP ; ne changez pas de clé pour « forcer » un doublon. Quand la première requête est terminée et sa réponse enregistrée, le même `POST` rejoue cette réponse.
- `413 file_too_large` : fichier au-delà de la taille maximale (10 Mo).
- `415 unsupported_media_type` : fichier non PDF pour le flux Factur-X PDF/A-3.
- `422 insufficient_data` : données insuffisantes pour produire la cible demandée.
- `422 invalid_invoice_data` : total de TVA différent de la somme de la ventilation (BR-CO-14), remise de prix sans prix brut, catégorie TVA O/K/G/L/M incohérente, motif d’exonération ambigu en mode multi-catégories, `buyer.tax_registration_id` non supporté, ou règle EN16931 refusée explicitement.
- `422 unsupported_output_profile_for_invoice_data` : `invoice_data` ne peut pas cibler `MINIMUM`, `BASIC_WL` ou `BASIC`. Gardez le profil `EN16931` par défaut ou utilisez `EXTENDED` si votre contrat le prévoit.
- `422 unextractable_pdf` : aucune donnée exploitable extraite du PDF, sans `invoice_data` pour compenser.
- `503 requested_output_unavailable` : le PDF/A-3 demandé n’a pas pu être produit ; l’API échoue explicitement (quota remboursé) au lieu de retourner un succès XML-only silencieux.
- `422 ocr_confidence_too_low` : confiance OCR insuffisante en mode `strict`. Action : fournir `invoice_data` (recommandé) ou `options.confidence_mode="lenient"`.
- `503 ocr_service_unavailable` / `503 ocr_quota_exhausted` : OCR indisponible ou quota OCR épuisé — header `Retry-After` fourni. Action : rejouer après le délai, même clé d'idempotence. Sans objet en mode `invoice_data` complet (pas d'OCR).
- `402 quota_exceeded` : quota mensuel de factures traitées atteint (définitif jusqu'au renouvellement ou upgrade — pas de `Retry-After`). Le header `X-Quota-Used` peut indiquer l'usage courant au moment du refus ; il ne signifie pas que cet appel refusé a traité une facture.
- `429` : rate limit par minute — header `Retry-After` fourni. Action : backoff puis rejouer à l'identique (même clé d'idempotence).

En résumé, pour les codes listés ci-dessus : les `400`, `413`, `415` et `422` se corrigent avant un nouvel appel, avec une nouvelle clé d'idempotence ; `409 idempotency_in_progress` s'attend sur la clé d'origine (en changer relancerait une seconde conversion) ; `402 quota_exceeded` se lève par le renouvellement du quota ou un changement de plan ; `429` et les `503` `ocr_service_unavailable` / `ocr_quota_exhausted` se rejouent à l'identique après le délai `Retry-After` ; `503 requested_output_unavailable` rembourse le quota et se rejoue avec la même clé. Pour les autres codes, `503` compris, suivez la stratégie publiée par code dans l'extension OpenAPI `x-facturx-convert-error-registry` : la classe HTTP seule ne dit pas s'il faut relancer.

- Ne relancez pas à l’identique un 400, 413, 415 ou 422 : selon la stratégie publiée pour le code, corrigez l’entrée et envoyez la requête corrigée avec une nouvelle Idempotency-Key, ou contactez le support avec le request_id (par exemple request_failed).
- Seuls 429 (en attendant le délai du header Retry-After), 502, 503 et 504 peuvent se relancer, et pas tous : relancez seulement si la stratégie publiée pour le code le prévoit, avec un nombre de relances borné (par exemple 3) et la même Idempotency-Key pour la même requête. Cas particulier, 409 idempotency_in_progress (même requête, même clé, première requête encore en cours de traitement) : attendez puis relancez avec la même clé ; ne changez pas de clé, cela lancerait une seconde opération. D’autres codes 409 ont leur propre stratégie dans x-facturx-convert-error-registry.
- 402 : ce n’est pas une relance. Pour quota_exceeded (quota mensuel atteint), le renouvellement du quota ou un changement de plan le lève ; les autres 402 ont leur stratégie dans x-facturx-convert-error-registry.
- 500 : pas de relance automatique. Conservez le request_id et contactez le support.
- La stratégie de chaque code est publiée dans le fichier OpenAPI, extension x-facturx-convert-error-registry de POST /api/v1/convert : relancer avec la même clé, attendre Retry-After, corriger la requête, passer en output=xml_cii, suivre le job, contacter le support avec le request_id, ou quota remboursé. Un 503 ou un 504 ne se relance pas toujours : certains codes demandent de contacter le support, parfois après le délai Retry-After.

Pour les erreurs métier EN16931 (règles `BR-*`) remontées par la validation, la [bibliothèque d’erreurs](https://facturxapi.com/errors) détaille cause et correction règle par règle.

### Exemple multi-taux avec remise documentaire

Facture 20 % + 5,5 % avec une remise BG-20 portée par son taux : une entrée `tax_breakdown` par couple (catégorie, taux), bases exactes par groupe (BR-S-08). Exemple exécuté et vérifié contre la production.

```
{
  "invoice_number": "FA-2026-118",
  "issue_date": "2026-06-11",
  "seller": {
    "name": "Smoke Editeur SAS",
    "address": {
      "country": "FR",
      "street": "10 rue de la Paix",
      "city": "Paris",
      "postal_code": "75002"
    },
    "vat_id": "FR09999991235",
    "siret": "99999123500014"
  },
  "buyer": {
    "name": "Smoke Client SARL",
    "address": {
      "country": "FR",
      "street": "5 avenue des Champs",
      "city": "Lyon",
      "postal_code": "69002"
    },
    "vat_id": "FR83999992456",
    "siret": "99999245600015"
  },
  "totals": {
    "net": "73.33",
    "tax": "7.42",
    "gross": "80.75"
  },
  "tax_breakdown": [
    {
      "rate": "20",
      "category": "S",
      "base": "23.33",
      "amount": "4.67"
    },
    {
      "rate": "5.5",
      "category": "S",
      "base": "50.00",
      "amount": "2.75"
    }
  ],
  "line_items": [
    {
      "number": "1",
      "description": "Prestation 20%",
      "quantity": "1",
      "unit_price": "33.33",
      "net_amount": "33.33",
      "vat_rate": "20"
    },
    {
      "number": "2",
      "description": "Prestation 5.5%",
      "quantity": "1",
      "unit_price": "50.00",
      "net_amount": "50.00",
      "vat_rate": "5.5"
    }
  ],
  "allowances": [
    {
      "amount": "10.00",
      "reason": "Remise",
      "vat_category": "S",
      "vat_rate": "20"
    }
  ],
  "payment": {
    "due_date": "2026-07-11",
    "terms": "30 jours"
  }
}
```

### À préparer avant le premier test

Pour valider votre mapping sans générer de livrable ni consommer de quota, ajoutez `dry_run=true` : la réponse liste les champs manquants (`targetPreflight`, et `convertPreparation.fieldsToProvide` quand des champs guidés sont attendus) avant votre premier appel final.

- Un `invoice_data` complet ; si votre flux possède déjà un PDF de facture, gardez aussi un porteur testable sans donnée client sensible si vous partagez l’exemple.
- Un JSON ERP qui contient les champs dont votre flux a besoin. `invoice_data` est un champ multipart de type chaîne contenant le JSON sérialisé (pas un body JSON) — en shell, préférez `-F "invoice_data=$(cat facture.json)"` ou `--form-string` pour éviter les surprises d'échappement.
- Montants et taux en chaînes de caractères, arrondis à 2 décimales (`"970.00"`, `"20.00"`) — un montant sub-centime est refusé en 422 ; `quantity` et `unit_price` peuvent porter plus de décimales.
- Une règle d’idempotence : même clé uniquement pour la même requête complète ; nouvelle clé si le fichier, le JSON, la sortie, la cible, les options ou un complément changent.
- Un affichage clair des erreurs : champs manquants, conflit document/contexte, cible non exécutée.
- Un message produit séparé : document généré ou diagnostiqué, mais aucun statut PA inventé.

### Ce que FacturX API fait

- Générer un XML CII (base EN16931) depuis un `invoice_data` complet, avec `output=xml_cii`, sans PDF.
- Générer un Factur-X PDF/A-3 avec XML CII embarqué depuis un `invoice_data` complet sans PDF fourni, ou en utilisant un PDF existant comme porteur, avec `output=facturx_pdfa3`.
- Exécuter la validation EN16931, et les contrôles des règles françaises (FNFE-MPE) quand ils sont demandés (`validation_target=france_2026`) et exécutables — sinon la réponse dit explicitement pourquoi la cible n’a pas tourné (`not_run_reason`).
- Retourner des erreurs structurées qui nomment le champ à corriger, et un mode test `dry_run=true` qui liste les champs manquants sans consommer de quota.
- Diagnostiquer gratuitement un document existant via le [validateur public](https://facturxapi.com/scan) avant de câbler l’appel API.

### Ce que FacturX API ne promet pas

- Pas d’UBL en sortie de /convert aujourd’hui.
- Pas de dépôt, de transmission, de réception ni d’acceptation par une PA : /convert produit un document en amont ; le parcours PA reste séparé et relève de votre flux aval.
- Pas de routage vers une PA ni d’interrogation d’annuaire : les identifiants de routage (BT-34 / BT-49) sont transportés et contrôlés s’ils sont fournis, jamais résolus automatiquement.
- Pas de « conformité réforme 2026 » absolue : chaque résultat nomme le niveau réellement contrôlé — génération du XML CII, production du Factur-X PDF/A-3, validation EN16931, contrôles des règles françaises (FNFE-MPE) exécutés.
- Pas de garantie d’acceptation aval : un fichier produit et validé ici reste soumis aux règles du flux qui le reçoit.

Vous branchez des clients finaux sur ce flux ? Le [parcours intégrateurs](https://facturxapi.com/integrateurs) décrit où placer scan, conversion et validation dans votre architecture.

### Questions fréquentes

#### Puis-je sortir un XML CII sans PDF ?

Oui. Demandez output=xml_cii avec un invoice_data complet : le PDF est optionnel pour ce livrable. La réponse contient le XML dans result.xml, avec packagingPerformed=false puisqu’aucun PDF/A-3 n’est produit.

#### Est-ce un Factur-X ?

Le XML CII seul, non. Un Factur-X est un PDF/A-3 lisible avec le XML CII embarqué. Avec un invoice_data complet, /convert peut générer le Factur-X PDF/A-3 sans fichier PDF fourni : l’API rend le porteur visuel à partir des mêmes données. Si votre ERP dispose déjà d’un PDF, vous pouvez aussi le fournir comme porteur.

#### Est-ce accepté automatiquement par une PA ?

Non. /convert produit un document et exécute les contrôles demandés : validation EN16931, ou contrôles des règles françaises (FNFE-MPE) quand ils sont demandés et exécutables. Le dépôt, la transmission et l’acceptation relèvent du parcours PA, séparé de cette API.

#### UBL est-il disponible ?

Non en sortie : /convert ne produit pas d’UBL aujourd’hui. Les deux sorties publiques sont le XML CII (output=xml_cii) et le Factur-X PDF/A-3 (output=facturx_pdfa3). En entrée, un UBL Invoice est accepté et converti en XML CII (mapping strict, sinon 422 ubl_source_mapping_unsupported) ; un Factur-X PDF/A-3 depuis un UBL n’est pas garanti : voir la documentation de l’API.

#### Que faire en cas de 422 ?

422 insufficient_data : il manque des champs pour la cible demandée — complétez invoice_data avec les chemins listés dans la réponse (missing_inputs, targetPreflight). 422 invalid_invoice_data : une valeur est refusée par une règle (par exemple un total de TVA différent de la somme de la ventilation, ou un champ refusé) — corrigez la valeur nommée dans l’erreur. Testez avec dry_run=true pour itérer sans consommer de quota.

---

# Documentation de l’API

Source : https://facturxapi.com/docs

API REST · OpenAPI 3.1 · Factur-X CII

## Préparez les Factur-X de vos clients avant leur envoi via une Plateforme Agréée (PA) ou une solution compatible (SC).

Une brique technique REST à brancher sur votre ERP. Diagnostiquez les PDF/XML et réparez les XML CII récupérables. Pour générer un Factur-X PDF/A-3, fournissez soit un invoice_data complet, dont l’API rend le porteur sans PDF source, soit un PDF existant comme porteur alternatif. Avec output=xml_cii, l’API produit uniquement le XML CII.
[Obtenir ma clé gratuite](https://facturxapi.com/api-key?source=docs_hero) [Tester sans clé dans le navigateur](https://facturxapi.com/scan)

Endpoints OpenAPI

Usage REST

Hébergement Front : Cloudflare · API : Railway

PDF/A-3 veraPDF

POST api.facturxapi.com/api/v1/validate

Live

```
curl -X POST https://api.facturxapi.com/api/v1/validate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@./facture.pdf"
```

```
// Avec fetch API
const formData = new FormData();
formData.append('file', file);

const response = await fetch('https://api.facturxapi.com/api/v1/validate', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  },
  body: formData
});

const result = await response.json();
console.log(result.valid ? '✅ Valid' : '❌ Invalid');
console.log('Errors:', result.errors);
console.log('Profile:', result.profile);
```

```
import requests

# Upload et validation
with open('facture.pdf', 'rb') as f:
    response = requests.post(
        'https://api.facturxapi.com/api/v1/validate',
        headers={'Authorization': 'Bearer YOUR_API_KEY'},
        files={'file': f}
    )

result = response.json()
print('✅ Valid' if result['valid'] else '❌ Invalid')
print('Errors:', result['errors'])
print('Profile:', result['profile'])
```

Remplacez `YOUR_API_KEY` par votre clé Sandbox gratuite, activée par email.

### Premier appel en 12 lignes

Une simulation (`dry_run`) sur le cas « facture enrichie France 2026 (mentions PMT/PMD/AAB, adressage) » du [contrat d’intégration](https://facturxapi.com/docs/integration-contract#cas-types) : la clé reste dans une variable d’environnement.

Avant de lancer l’appel :
[créez votre clé API](https://facturxapi.com/api-key?source=docs_quickstart).

```
# 1. Copiez le cas « facture enrichie France 2026 » dans invoice-data.json
#    (contrat d’intégration, section « Cas types », bouton « Copier le JSON »)
export FACTURX_API_KEY="votre-clé-api"
curl -sS -X POST https://api.facturxapi.com/api/v1/convert \
  -H "X-API-Key: $FACTURX_API_KEY" \
  -F "dry_run=true" -F "validation_target=france_2026" \
  -F 'invoice_data=<invoice-data.json' \
  -w "\nHTTP %{http_code}\n"
```
 
```
# Réponse :
  "dry_run": true,
  "result": { "processedInvoicesCharged": 0, … }
HTTP 200
```

Ensuite : le [guide JSON ERP avec vos données complètes](https://facturxapi.com/docs/integration-convert-json-erp).

### Ce que vous pouvez faire aujourd’hui

Une ligne par usage, avec la commande ou la page pour commencer.

Ce que vous faites | Pour commencer | Lien |
Générer un Factur-X PDF/A-3 ou un XML CII à partir du JSON de votre ERP | `POST /api/v1/convert` | [Guide JSON ERP](https://facturxapi.com/docs/integration-convert-json-erp) |
Tester une facture avant de la générer : aucun livrable final, aucun quota consommé | `POST /api/v1/convert, dry_run=true` | Premier appel en 12 lignes |
Valider un PDF ou un XML Factur-X en EN 16931, et en option sur les règles françaises | `POST /api/v1/validate, validation_target` | [Méthode de validation](https://facturxapi.com/methodologie) |
Extraire le XML embarqué d’un PDF Factur-X | `POST /api/v1/extract` | [Extraire dans le navigateur](https://facturxapi.com/tools/extract) |
Réparer un XML Factur-X | `POST /api/v1/repair` | [Réparer dans le navigateur](https://facturxapi.com/tools/repair) |
Contrôler un fichier dans le navigateur, sans compte | /scan | [Ouvrir le diagnostic](https://facturxapi.com/scan) |
Obtenir une clé API Sandbox gratuite, sans carte bancaire | /api-key | [Créer ma clé](https://facturxapi.com/api-key?source=docs_capabilities) |
Appeler l’API depuis Python | `pip install facturx-api` | [SDK Python sur GitHub](https://github.com/facturxapi/sdk/tree/main/python) |
Appeler l’API depuis Node.js | `npm install @facturxapi/sdk` | [SDK Node.js sur GitHub](https://github.com/facturxapi/sdk/tree/main/node) |
Contrôler, générer et valider en ligne de commande | `facturx dry-run invoice.json` | [Livrée avec facturx-api](https://github.com/facturxapi/sdk/tree/main/python) |
Brancher l’API sur un agent IA (serveur MCP) | `pip install facturx-mcp` | [Guide agents](https://facturxapi.com/docs/agents) |
Lire le contrat d’intégration JSON, champ par champ | `GET /api/v1/integration-contract` | [Contrat d’intégration](https://facturxapi.com/docs/integration-contract) |
Comprendre une erreur EN 16931 et la corriger | /errors | [Fiches d’erreurs](https://facturxapi.com/errors) |

- Générer un Factur-X PDF/A-3 ou un XML CII à partir du JSON de votre ERP
`POST /api/v1/convert`
[Guide JSON ERP](https://facturxapi.com/docs/integration-convert-json-erp)
- Tester une facture avant de la générer : aucun livrable final, aucun quota consommé
`POST /api/v1/convert, dry_run=true`
Premier appel en 12 lignes
- Valider un PDF ou un XML Factur-X en EN 16931, et en option sur les règles françaises
`POST /api/v1/validate, validation_target`
[Méthode de validation](https://facturxapi.com/methodologie)
- Extraire le XML embarqué d’un PDF Factur-X
`POST /api/v1/extract`
[Extraire dans le navigateur](https://facturxapi.com/tools/extract)
- Réparer un XML Factur-X
`POST /api/v1/repair`
[Réparer dans le navigateur](https://facturxapi.com/tools/repair)
- Contrôler un fichier dans le navigateur, sans compte
/scan
[Ouvrir le diagnostic](https://facturxapi.com/scan)
- Obtenir une clé API Sandbox gratuite, sans carte bancaire
/api-key
[Créer ma clé](https://facturxapi.com/api-key?source=docs_capabilities)
- Appeler l’API depuis Python
`pip install facturx-api`
[SDK Python sur GitHub](https://github.com/facturxapi/sdk/tree/main/python)
- Appeler l’API depuis Node.js
`npm install @facturxapi/sdk`
[SDK Node.js sur GitHub](https://github.com/facturxapi/sdk/tree/main/node)
- Contrôler, générer et valider en ligne de commande
`facturx dry-run invoice.json`
[Livrée avec facturx-api](https://github.com/facturxapi/sdk/tree/main/python)
- Brancher l’API sur un agent IA (serveur MCP)
`pip install facturx-mcp`
[Guide agents](https://facturxapi.com/docs/agents)
- Lire le contrat d’intégration JSON, champ par champ
`GET /api/v1/integration-contract`
[Contrat d’intégration](https://facturxapi.com/docs/integration-contract)
- Comprendre une erreur EN 16931 et la corriger
/errors
[Fiches d’erreurs](https://facturxapi.com/errors)

Versions publiques et runtime observé

### Deux sources distinctes : publications upstream et exécution FacturX API

Les versions publiques viennent des éditeurs (FNFE-MPE, CEN). Le runtime exécuté est lu séparément via
`GET https://api.facturxapi.com/meta`
pour le service configuré sur cette page (sur l'hôte de l'API, pas sur ce site). Une publication plus récente n'est pas automatiquement celle
du moteur ; en l'absence de réponse exploitable, la version runtime reste non confirmée.

#### Publications publiques (sources upstream)

Factur-X publique 1.09.2
FNFE-MPE / FeRD (publication mise à jour le 2026-08-04)

#### Runtime déclaré par le service configuré dans GET /meta

Factur-X runtime exécuté1.09.2

Détail machine (GET /meta)

SourceFACTURX_RUNTIME_VERSION

execution_statusverified

manifest_digestfd05a55ec6d973b667eb0e2d385f050aafe3068be42a1b4d334f7a0eaee3c15a

compiled_en16931_xslt_digest67f03050e3add4c83dc93de36e4501f6a11aae1ac790b3f9558feb0581019bcb

source_zipFactur-X-1.09.2-Zugferd-2.5.2-2026-08-04-FINAL-FR.zip
7d2fe79580270c8babea3e40dbdae47bd68c0baa7022051be4f955921a1cd29a

artifact_base_pathresources/facturx_1.09.2

Source [GET /meta](https://api.facturxapi.com/meta) · réponse générée 2026-11-14T01:17:32.999449+00:00

Règles EN 16931 par syntaxe (/meta) UBL : règles CEN 1.3.16 ; CII : schematron Factur-X 1.09.2

Artefacts France / FR-CTC v1.4.0.04
resources/fr_ctc/1.4.0.04/extracted/cii/EN16931-CII-validation-preprocessed.sch

Listes de codes (famille runtime vérifiée) 10 artefact(s) codedb rattaché(s) à la famille runtime dans /meta.

Démarrer

### De 0 à un premier appel vérifiable

Trois étapes pour obtenir une clé, envoyer un fichier et lire le résultat des contrôles.

-
01

#### Votre clé Sandbox par email

Saisissez votre email, ouvrez le lien reçu, puis confirmez l'activation. Clé Sandbox incluse : 100 factures traitées offertes les 14 premiers jours, puis 10 factures traitées/mois, sans carte bancaire.

[Créer ma clé](https://facturxapi.com/api-key?source=docs_quickstart)
-
02

#### Lancer votre premier appel

Collez le `curl` ci-dessus dans un terminal. La réponse HTTP 200 indique `dry_run: true` et `processedInvoicesCharged: 0`.

[Recevoir mon lien d’activation](https://facturxapi.com/api-key?source=docs_quickstart#api-key-form-entry)
-
03

#### Parcours ERP/GED /convert

Guide dédié JSON ERP : créer une clé API, préparer les données `invoice_data`, choisir Factur-X PDF/A-3 ou XML CII seul, gérer les champs manquants et les limites UBL/PA.

[Ouvrir le guide /convert ERP](https://facturxapi.com/docs/integration-convert-json-erp)

📦

### Ressources d'intégration

Importez la spec OpenAPI dans votre outil favori (Insomnia, Bruno, Stoplight, Swagger UI…) ou la collection Postman pour démarrer avec une base prête à importer.

{}

#### Spécification OpenAPI 3.1

Schéma public : le fichier OpenAPI publie les routes validate, extract, convert, repair, integration-contract, meta et health. `/meta` et `/health` répondent sur l'hôte de l'API (`https://api.facturxapi.com/meta`, `https://api.facturxapi.com/health`), pas sur ce site. Les routes dashboard, billing, admin, webhooks, création de clé et gestion connectée restent hors de cette documentation.

[Télécharger openapi.json](https://facturxapi.com/openapi.json) [Swagger UI live →](https://api.facturxapi.com/docs)

ID

#### Contrat invoice_data

Contrat machine-readable pour préparer `invoice_data` : champs acceptés, règles EN16931 / règles françaises, mapping CII et exemples générés depuis la source de vérité API.

[Explorer le contrat](https://facturxapi.com/docs/integration-contract) [JSON /api/v1/integration-contract](https://api.facturxapi.com/api/v1/integration-contract)

P

#### Collection Postman

Collection publique prête à l'emploi avec les endpoints d'intégration. Créez d'abord votre clé depuis [la page clé API](https://facturxapi.com/api-key) : ce parcours utilise `/public/api-keys/free/step1` puis `/public/api-keys/free/step2`. La gestion connectée passe ensuite par `/api/v1/me/api-keys`, volontairement absente de cette collection publique. Ajoutez votre clé dans la variable `apiKey` et lancez vos premiers appels.

[Télécharger la collection](https://facturxapi.com/postman-collection.json)

Dans Postman : File → Import → Link puis coller l'URL copiée.

#### Tiers payeur : contrat JSON

Ajoutez `payer` uniquement lorsque la partie qui règle la facture diffère de l’acheteur. `payer.name` est requis si le bloc est présent. Vous pouvez aussi fournir son adresse postale dans `postal_address` — avec `country` — et son email de contact dans `email`. Cet email ne remplace pas `electronic_address` : ce dernier est un identifiant de routage qualifié contenant ensemble `value` et `scheme_id`, comme les identifiants optionnels `global_id` et `legal_registration`.

Ce tiers payeur correspond à `EXT-FR-FE-BG-02`. Il ne remplace ni le bénéficiaire `payee` de `BG-10`, ni le compte débité `payment.debtor_account_iban` de `BT-91`. Sa présence ne crée pas de montant prépayé `BT-113` : envoyez `totals.prepaid_amount` seulement si cette donnée est réellement connue. Le profil effectif produit est `EXTENDED` ; vérifiez-le dans `result.targetProfile`.

Le champ `payer` est optionnel. Si votre facture relève d’une livraison intracommunautaire, le contrat peut aussi demander `delivery.date` et `delivery.address.country` ; cette exigence est indépendante du tiers payeur.

Extrait minimal du bloc payer à ajouter

```
{
  "payer": {
    "name": "OPCO Formation SA",
    "postal_address": {
      "street": "12 rue de la Formation",
      "city": "Paris",
      "postal_code": "75008",
      "country": "FR"
    },
    "email": "facturation@opco.example",
    "electronic_address": {
      "value": "FRROUTEOPCO001",
      "scheme_id": "0225"
    }
  }
}
```

#### Snippets prêts par langage

PHP, Python, Node.js, Laravel, Symfony, .NET — avec retries, timeouts et codes d'erreur.

[Voir les intégrations →](https://facturxapi.com/integrations)

### Introduction

L'API FacturX permet de traiter des factures électroniques au format Factur-X (PDF hybride avec XML embarqué) ou XML standalone selon les standards EN16931.

Cette page détaille la validation, l'extraction, la conversion et la réparation ; le fichier OpenAPI publie aussi le contrat d'intégration, les métadonnées et la santé du service.

- Validate : Validation XSD + Schematron complète d'un PDF Factur-X ou XML CII
- Extract : Extraction du XML CII embarqué dans un PDF Factur-X
- Convert : Génération d'un Factur-X PDF/A-3 avec contrôles de sortie
- Repair : Correction automatique déterministe d'un XML CII invalide

### Qu'est-ce que Factur-X ?

Factur-X est un format de facture électronique hybride franco-allemand, également connu sous le nom de ZUGFeRD 2.x en Allemagne.

Une facture Factur-X combine deux éléments :

- Un PDF lisible : La facture visuelle classique, imprimable et lisible par l'humain
- Un fichier XML embarqué : Les données structurées de la facture, lisibles par les machines

Cette approche hybride permet une transition progressive vers la facturation électronique : les comptables peuvent continuer à lire les PDF, tandis que les systèmes informatiques peuvent extraire automatiquement les données.

#### Profils Factur-X

Factur-X définit plusieurs profils correspondant à différents niveaux de détail :

- Minimum : Données minimales (montants, dates, parties)
- Basic : Informations de base pour le traitement automatisé
- EN16931 : Profil couvrant le modèle sémantique complet de la norme européenne (recommandé)
- Extended : Champs additionnels pour besoins spécifiques

Quand le profil et les parties de la facture sont lisibles, l’API détecte le profil et applique les règles de validation correspondantes ; sinon, ni la détection ni la liste des champs manquants ne sont garanties.

Référence rapide des URN, schémas XSD et règles Schematron par profil : [URN, XSD et Schematron Factur-X](https://facturxapi.com/docs/urns-schemas-factur-x).

### Structure d'un PDF Factur-X

Un PDF Factur-X doit contenir un XML en pièce jointe. La spécification Factur-X 1.07.2 (§6.2) fixe son nom : `factur-x.xml`, ou `xrechnung.xml` pour le profil de référence XRechnung. ZUGFeRD 2.0 nommait ce fichier `zugferd-invoice.xml` ; depuis ZUGFeRD 2.1 le nom prévu est aussi `factur-x.xml`.

#### Comment vérifier manuellement ?

Dans Adobe Acrobat ou un lecteur PDF compatible :

- Ouvrez le PDF
- Allez dans le panneau des pièces jointes (icône trombone)
- Vérifiez la présence d'un fichier `.xml`

Si aucun fichier XML n'est présent, il s'agit d'un PDF classique, pas d'une facture Factur-X.

#### Erreur "No Factur-X XML found"

Cette erreur signifie que le PDF uploadé ne contient pas de XML embarqué. Causes possibles :

- Le PDF a été généré par un outil qui ne supporte pas Factur-X
- Le XML a été supprimé lors d'une modification du PDF
- Le fichier est un PDF classique, pas une facture Factur-X

### Comment créer une facture Factur-X ?

#### Avec FacturX API : depuis vos données de facture

Envoyez un `invoice_data` complet (les données de facture de votre ERP, au format JSON) à POST /api/v1/convert : l’API génère le XML CII seul (`output=xml_cii`) ou un Factur-X PDF/A-3 avec XML embarqué (`output=facturx_pdfa3`, porteur visuel rendu depuis les mêmes données ou votre PDF existant). Le fichier produit est soumis aux contrôles de la cible demandée (`validation_target`) ; il n’obtient le verdict « Factur-X EN16931 valide » que si ces contrôles passent. Les données manquantes ne sont jamais inventées ; quand le profil et les parties sont lisibles, elles sont listées. Parcours complet : [guide /convert avec JSON ERP](https://facturxapi.com/docs/integration-convert-json-erp).

D’autres outils savent aussi produire des Factur-X :

#### Logiciels de facturation

L'export Factur-X dépend du logiciel, de sa version et du profil choisi. Le nom de l'éditeur ne prouve pas qu'un PDF contient un XML Factur-X.

- À contrôler dans la documentation de l'éditeur : Sage, Cegid, EBP, SAP, Oracle, QuickBooks, Xero.

#### Bibliothèques open-source

Pour les développeurs souhaitant générer des Factur-X programmatiquement :

- Python : [factur-x (Akretion)](https://github.com/akretion/factur-x)
- Java : [Mustang Project](https://github.com/ZUGFeRD/mustangproject)
- PHP : [horstoeko/zugferd](https://github.com/horstoeko/zugferd)
- .NET : [ZUGFeRD-csharp](https://github.com/stephanstapel/ZUGFeRD-csharp)

#### Plateformes Agréées (PA)

Depuis le 1er septembre 2026, toutes les entreprises doivent être en capacité de recevoir une facture électronique. Les grandes entreprises et les entreprises de taille intermédiaire doivent émettre désormais leurs factures au format dématérialisé dès le 1er septembre 2026. Au 1er septembre 2027, les micro-entreprises, TPE et PME devront être en capacité d'émettre des factures électroniques.

Dans le cadre de la réforme française 2026-2027, les Plateformes Agréées assurent la transmission et le routage réglementaire. FacturX API prépare, valide et répare le document en amont, avant que votre ERP ou votre client ne le remette à sa PA.

### Règles métier EN16931

La norme EN16931 définit plus de 200 règles métier (Business Rules) que doit respecter une facture électronique. Ces règles sont vérifiées via Schematron.

#### Catégories de règles

- BR-xx : Règles de base (champs obligatoires, formats)
- BR-CO-xx : Règles de cohérence (calculs, totaux)
- BR-S-xx : Règles spécifiques aux régimes de TVA
- BR-CL-xx : Règles sur les codes et listes de valeurs

#### Exemples de règles courantes

Code | Description |
`BR-01` | Une facture doit avoir un identifiant de spécification (BT-24) |
`BR-02` | Une facture doit avoir un numéro de facture (BT-1) |
`BR-CO-10` | La somme des montants HT doit correspondre au total HT |
`BR-CO-15` | Le montant TTC doit être égal au HT + TVA |
`BR-S-01` | Une facture contenant une ligne, une remise ou une charge de catégorie TVA S doit contenir une ventilation TVA de catégorie S |

Lorsqu'une règle est violée, l'API retourne une erreur de type `schematron_failed_assert` avec le code de la règle concernée.

### Sécurité & RGPD

Cette section résume les contrôles de sécurité et les traitements externes à connaître avant d'intégrer l'API.

#### Infrastructure

- Hébergement : Cloudflare Pages (front) + Railway (API). Voir la [politique de confidentialité](https://facturxapi.com/politique-confidentialite) pour la liste complète des sous-traitants et leur localisation.
- Chiffrement en transit : TLS sur toutes les communications (HTTPS obligatoire).

#### Traitement des données

- Validation et scan : Les fichiers transmis servent au traitement demandé. Selon le parcours, des copies temporaires peuvent être conservées pour le traitement, sa reprise ou l’accès au résultat ; les principales situations sont décrites dans la politique de confidentialité.
- Espace de facturation (plans Launch, Scale et Business) : les profils émetteurs, clients, factures, lignes et références de PDF sont conservés pour créer, retrouver et justifier les factures émises.
- Traitement limité au service demandé : L'API analyse les champs nécessaires au scan, à la validation ou à la génération, sans scoring commercial.
- Enrichissement Sirene désactivable via l'API : Par défaut, les identifiants entreprise peuvent être vérifiés auprès de l'INSEE Sirene et de recherche-entreprises.api.gouv.fr. Le paramètre `enrich=false` est disponible uniquement sur les requêtes API directes ; les outils du dashboard ne proposent pas ce réglage aujourd'hui.
- Usage des données : les données ne sont pas utilisées pour entraîner un modèle, enrichir un tiers ou revendre des informations métier.
- Logs minimaux : Seules les métadonnées techniques sont conservées (horodatage, taille, résultat)
Les fichiers et données sont traités selon le parcours utilisé. Certaines données sont conservées pour permettre le diagnostic, la reprise ou l’accès aux résultats ; les détails figurent dans la politique de confidentialité. [Lire la matrice de conservation](https://facturxapi.com/politique-confidentialite).

#### Conformité

- Transparence RGPD : bases légales, droits d'accès/export/suppression, sous-traitants confirmés et services publics interrogés sont documentés dans la politique de confidentialité.

Pour plus de détails, consultez notre [politique de confidentialité](https://facturxapi.com/politique-confidentialite).

### Base URL

```
https://api.facturxapi.com
```

Toutes les routes de l'API, y compris `GET /meta` et `GET /health`, se trouvent sur cet hôte : [https://api.facturxapi.com/meta](https://api.facturxapi.com/meta) et [https://api.facturxapi.com/health](https://api.facturxapi.com/health). Le site de documentation ne les sert pas.

### Authentication

Pour l’authentification par clé API, l’API accepte ces deux headers ; les exemples de cette documentation utilisent `X-API-Key`, comme sur la page d’accueil :

```
X-API-Key: YOUR_API_KEY
Authorization: Bearer YOUR_API_KEY
```

Si les deux headers contiennent des clés API, `X-API-Key` est prioritaire.

[Obtenez votre clé sandbox](https://facturxapi.com/api-key) (100 factures traitées offertes les 14 premiers jours, puis 10 factures traitées/mois).

### Scan public

Le scan public disponible sur [/scan](https://facturxapi.com/scan) est un diagnostic sans compte.

- Le scan peut conclure que le socle Factur-X / EN16931 est exploitable tout en indiquant que les règles françaises (FNFE-MPE) demandent des compléments.
- Les compléments listés sont actionnables via `/convert` uniquement si `conversionInputRecipe` les expose comme champs guidés supportés.
- Un point nécessitant une vérification manuelle doit être traité séparément ; ce n’est pas une promesse de correction automatique.

### Désactiver l'enrichissement Sirene

Par défaut, les endpoints publics peuvent vérifier les SIREN/SIRET et le nom d'entreprise détectés dans la facture, et signaler un écart de code postal, auprès de l'INSEE Sirene et de recherche-entreprises.api.gouv.fr. Ces vérifications ressortent en avertissements ou en informations ; elles ne tranchent pas le verdict de validation. Sur une requête API directe, ajoutez `enrich=false` pour garder ce flux sur un traitement hors registres publics. Les outils du dashboard ne proposent pas ce réglage aujourd'hui.

```
curl -X POST "https://api.facturxapi.com/api/v1/validate?enrich=false" \
  -H "X-API-Key: YOUR_API_KEY" \
  -F "file=@./facture.xml"

curl -X POST "https://api.facturxapi.com/api/v1/extract?validate=true&enrich=false" \
  -H "X-API-Key: YOUR_API_KEY" \
  -F "file=@./factur-x.pdf"

curl -X POST "https://api.facturxapi.com/api/v1/repair?enrich=false" \
  -H "X-API-Key: YOUR_API_KEY" \
  -F "file=@./facture.xml"

curl -X POST "https://api.facturxapi.com/api/v1/convert?enrich=false" \
  -H "X-API-Key: YOUR_API_KEY" \
  -F "file=@./facture.pdf"
```

### Endpoints

[Règle de décompte](https://facturxapi.com/pricing#credits)

Endpoint | Description | Factures traitées |
`POST /api/v1/validate` | Valider un PDF Factur-X ou XML CII | 1 facture traitée |
`POST /api/v1/extract` | Extraire le XML embarqué d'un PDF Factur-X | 1 facture traitée |
`POST /api/v1/convert` | Générer un Factur-X PDF/A-3 avec contrôles de sortie | 1 par génération finale, décomptée une seule fois · 0 en simulation dry_run |
`POST /api/v1/repair` | Réparer un XML Factur-X | 1 facture traitée |

#### POST /api/v1/validate

Produit un diagnostic technique pour un PDF Factur-X ou un XML CII. Sans cible France explicite, le socle affiché est Factur-X / EN16931 (PDF/A-3 et XML embarqué pour les PDF, XSD et Schematron EN16931 pour l’XML). La vérification des règles françaises (FNFE-MPE) n’est incluse que lorsqu’elle est demandée et exécutable par le runtime.

##### Paramètres

- `file` (multipart, requis) : Fichier PDF Factur-X ou XML CII
- `lang` (query, optionnel) : Langue de la réponse (`en` / `fr`)
- `legacy` (query, optionnel, défaut : `false`) : Retourner l'ancien format court si votre intégration historique en dépend encore
- `validation_target` (query, recommandé) : `en16931` pour le socle Factur-X / EN16931, `france_2026` pour le socle EN16931 et les exigences des règles françaises (FNFE-MPE) disponibles
- `validation_profile`, `jurisdiction`, `require_profile` (query, legacy) : contrôles historiques encore acceptés pour les intégrations existantes

La réponse inclut toujours `target.requested`, `target.executed`, `target.status`, `target.missing_inputs` et `target.not_run_reason`. Les contrôles des règles françaises (FNFE-MPE) utilisent uniquement le pack déclaré par le runtime servi (version 1.4.0.04 confirmée par le moteur lors de la génération de cette page), et seulement lorsqu’ils sont exécutés et listés dans `appliedValidationProfiles` / `validationScopeLabel`. Si la cible explicite n’est pas exécutable, l’API retourne `422 validation_profile_unavailable`.

##### Décompte

1 facture traitée. Si une cible explicite n'est pas exécutable et retourne `422 validation_profile_unavailable`, si le refus part avant tout débit, aucune facture traitée n'est décomptée ; s'il survient après le débit, le remboursement n'est pas garanti et la facture traitée peut rester décomptée. Contrairement à `/convert`, `/extract` et `/repair`, `/validate` ne signale pas un remboursement non confirmé (`503 quota_refund_unconfirmed`).

##### Exemple curl

```
curl -X POST https://api.facturxapi.com/api/v1/validate?validation_target=en16931 \
  -H "X-API-Key: votre-cle-api" \
  -F "file=@./facture.pdf"
```

##### Réponse par défaut (200)

```
{
  "valid": true,
  "target": {
    "requested": "en16931",
    "executed": "en16931",
    "status": "verified",
    "missing_inputs": [],
    "not_run_reason": null
  },
  "validatedAt": "2026-04-28T10:00:00.000Z",
  "filename": "invoice.xml",
  "profile": "EN16931",
  "durationMs": 124,
  "summary": {
    "errorCount": 0,
    "warningCount": 0
  },
  "issues": [],
  "stages": {
    "pdfa": {
      "passed": true,
      "skipped": true,
      "skip_reason": "XML file - PDF/A validation not applicable",
      "error_count": 0,
      "warning_count": 0,
      "info_count": 0,
      "issues": []
    },
    "facturx_pdf": {
      "passed": true,
      "skipped": true,
      "skip_reason": "XML file - PDF checks not applicable",
      "error_count": 0,
      "warning_count": 0,
      "info_count": 0,
      "issues": []
    },
    "xsd": {
      "passed": true,
      "skipped": false,
      "error_count": 0,
      "warning_count": 0,
      "info_count": 0,
      "issues": []
    },
    "schematron": {
      "passed": true,
      "skipped": false,
      "error_count": 0,
      "warning_count": 0,
      "info_count": 0,
      "issues": []
    }
  },
  "errors": [],
  "warnings": []
}
```

##### Réponse legacy (?legacy=true)

```
{
  "valid": true,
  "errors": [],
  "warnings": [],
  "profile": "EN16931",
  "message": "Validation completed",
  "target": {
    "requested": "en16931",
    "executed": "en16931",
    "status": "verified",
    "missing_inputs": [],
    "not_run_reason": null
  }
}
```

##### Codes d'erreur spécifiques

- `401 authentication_required` : Aucune clé API dans la requête (ni `X-API-Key` ni `Authorization: Bearer`). `401 invalid_api_key` : Clé invalide ou révoquée. Corps JSON dans les deux cas : `detail.error`, `detail.message`, `detail.supported_methods` (méthodes d’authentification acceptées) et `request_id`
- `400` : Fichier vide ou invalide
- `415` : Format non supporté (ni PDF, ni XML)
- `422` : Cible de validation demandée mais non exécutable

#### POST /api/v1/extract

Extrait le fichier XML embarqué (`factur-x.xml`) d'un PDF Factur-X et retourne les données structurées. Optionnellement, valide le XML extrait.

##### Paramètres

- `file` (multipart, requis) : Fichier PDF Factur-X
- `validate` (query, optionnel, défaut : `false`) : Ajouter une validation complète du XML extrait dans la même réponse
- `lang` (query, optionnel) : Langue de la réponse (`en` / `fr`)

##### Décompte

1 facture traitée.

##### Exemple curl

```
curl -X POST https://api.facturxapi.com/api/v1/extract \
  -H "X-API-Key: votre-cle-api" \
  -F "file=@./facture-facturx.pdf"
```

##### Réponse (200)

```
{
  "xml": "PD94bWwgdmVyc2lvbj0iMS4wIj8+...",
  "xmlSize": 2048,
  "profile": "EN16931",
  "filename": "facture.pdf",
  "extractedAt": "2026-04-01T12:00:00Z",
  "durationMs": 42
}
```

##### Codes d'erreur spécifiques

- `415` : Le fichier n'est pas un PDF
- `422` : Aucun XML embarqué trouvé dans le PDF

#### POST /api/v1/convert

Produit un Factur-X PDF/A-3 avec XML CII embarqué (`output=facturx_pdfa3`, défaut) ou le XML CII seul (`output=xml_cii`), puis contrôle le fichier produit pour la cible demandée. Sources acceptées :

- PDF de facture : l’API extrait les données du PDF, qui sert aussi de porteur visuel.
- `invoice_data` complet : la source complète de la facture ERP (JSON). L’extraction du PDF est alors ignorée ; sans PDF, l’API rend le porteur depuis les mêmes données.
- XML Factur-X CII (guideline BASIC ou EN16931), envoyé seul dans `file`, lorsque le déploiement de l’API active cette source (sinon `415 unsupported_media_type`) : le XML est validé, repris sans inventer de valeur et le porteur est rendu depuis ces données. Il est converti tel quel : `invoice_data`, `invoice_patch`, contextes et réutilisation de profils sont refusés (`422 cii_xml_source_overlay_unsupported`). Un CII sans lignes (MINIMUM, BASIC WL) est refusé (`422 cii_source_profile_header_only`), comme ZUGFeRD 1.0 et toute autre guideline (`422 cii_source_unsupported`) : seuls les identifiants exacts `urn:cen.eu:en16931:2017` (EN16931) et `urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic` (BASIC) sont acceptés, ce qui exclut EXTENDED, XRECHNUNG et les guidelines ZUGFeRD.
- XML UBL Invoice ou CreditNote : le UBL doit d’abord passer les contrôles EN16931 UBL (`422 ubl_source_not_valid_en16931` sinon), puis être entièrement représentable par le mapping UBL → CII strict ; un champ non représentable est refusé (`422 ubl_source_mapping_unsupported`) au lieu d’être perdu. `output=xml_cii` produit le XML CII ; un Factur-X PDF/A-3 depuis un UBL seul suppose que le déploiement active le rendu du porteur (sinon `422 ubl_pdf_carrier_required`). `invoice_data` ne se combine pas avec un UBL (`400 invalid_invoice_data_source_conflict`).
- Compléments partiels sur un document PDF : `invoice_patch`, `seller_context`, `buyer_context`, uniquement pour les chemins que `conversionInputRecipe` expose comme supportés. Ils ne remplacent jamais silencieusement une donnée visible (`409 inline_context_conflict` en cas de désaccord).
- Réutilisation explicite d’un profil enregistré : avec `profile_reuse=explicit` et des sélecteurs limités à votre compte (`issuer_id`/`seller_profile_id` pour le vendeur, `client_id`/`buyer_profile_id` pour l’acheteur), l’API reprend l’adresse électronique et les notes de document enregistrées du vendeur, et l’adresse électronique enregistrée de l’acheteur ; l’identité et la version du profil entrent dans l’identité de la requête. Aucun profil n’est chargé silencieusement ni depuis un autre compte : sélecteur sans opt-in (`422 profile_reuse_requires_explicit_opt_in`), opt-in sans sélecteur (`422 profile_reuse_selector_required`), sélecteurs en désaccord (`409 profile_selector_conflict`), profil introuvable pour votre compte (`404 seller_profile_not_found` / `404 buyer_profile_not_found`), profil en conflit avec le contexte inline (`409 profile_inline_context_conflict`).

Pour le parcours intégrateur PDF + JSON ERP, consultez le [guide dédié /convert avec JSON ERP](https://facturxapi.com/docs/integration-convert-json-erp).
Pour explorer chaque champ `invoice_data` (code BT/BG, règle EN16931 ou française, XPath CII) et valider un payload en direct, ouvrez le [contrat d'intégration](https://facturxapi.com/docs/integration-contract).

Choisissez toujours la cible avec `validation_target`. `en16931` vérifie le socle Factur-X / EN16931. `france_2026` inclut EN16931 plus les exigences françaises FNFE-MPE disponibles dans le runtime.

Commencez par une simulation (`dry_run=true`) : elle ne consomme pas le quota et ne produit pas de livrable final. Un XML candidat peut toutefois être généré. La réponse selon les règles françaises inclut alors `targetPreflight`. Si `targetPreflight.exhaustive` vaut `false`, utilisez `targetPreflight.status`, `targetPreflight.exhaustive` et les points bloquants structurés pour informer l'utilisateur sans présenter la liste comme complète. Les champs de `targetPreflight.requiredInputs` doivent être envoyés via les racines partielles indiquées par l’API : `invoice_patch`, `seller_context` et `buyer_context`, jamais comme un `invoice_data` partiel.

La génération finale selon les règles françaises doit reprendre la structure de `conversionInputRecipe.examplePayload` retournée par la simulation, puis remplacer toute valeur modèle par des valeurs réelles confirmées. Ne lancez la génération avec `validation_target=france_2026` que si `targetPreflight.exhaustive=true` et si `targetPreflight.unsupportedBlockers` est vide ; sinon conservez le résultat comme diagnostic et affichez les points bloquants restants. Cette condition ne bloque pas la génération d’un Factur-X EN16931 valide avec `validation_target=en16931` : les compléments des règles françaises restent du travail à traiter avant transmission.

Si la réponse signale une fonctionnalité API non disponible pour un champ requis, ne lancez pas la génération finale : affichez la raison structurée, conservez le diagnostic, puis reprenez uniquement quand l’API expose un chemin supporté pour ce champ via `conversionInputRecipe.requiredInputs`, une correction automatique documentée, ou une exclusion explicite qui retire ce champ des données attendues.

##### Paramètres

- `dry_run` (form field, optionnel, défaut : `false`) : Lance une simulation sans livrable final et sans décompte de quota. Ce n’est pas une absence de génération.
- `output` (form field, optionnel) : `facturx_pdfa3` par défaut, ou `xml_cii` pour obtenir uniquement le XML CII.
- `file` (multipart) : porteur PDF optionnel pour `output=facturx_pdfa3`. Sans fichier, un `invoice_data` complet permet à l’API de rendre le porteur avant le packaging PDF/A-3. Pour `output=xml_cii`, aucun PDF n’est produit.
- `validation_target` (form field, recommandé) : `en16931` pour un Factur-X EN16931, `france_2026` pour le socle EN16931 et les contrôles des règles françaises (FNFE-MPE) disponibles.
- `options` (form field, optionnel) : Options de conversion au format JSON

- `output_profile` : Profil Factur-X cible (défaut : `"EN16931"`)
- `confidence_mode` : `"strict"` (défaut) ou `"lenient"` pour l'OCR
- `validation_target` peut aussi être envoyé dans `options` si votre client préfère garder tous les réglages en JSON.

- `invoice_data` (form field, optionnel) : Données structurées complètes de la facture au format JSON. Quand fourni, l'extraction texte du PDF est ignorée.
- Sous le pack France, `supporting_documents[].description`, lorsqu’il est renseigné, doit être un code de la liste BT-123.
- `invoice_patch` (form field, optionnel) : Complément facture partiel. Support actuel : `preceding_invoice.issue_date` pour BT-26, avec référence d'origine effective déjà détectée ou fournie de façon cohérente, et `payment.iban` pour BT-84 quand le compte vendeur manque au document.
- `seller_context` ou `seller_profile_inline` (form field, optionnel) : Contexte vendeur inline non persistant pour BT-34 et les mentions BT-22 PMT/PMD/AAB.
- `buyer_context` ou `buyer_profile_inline` (form field, optionnel) : Contexte acheteur inline non persistant pour BT-49.
- `lang` (query, optionnel) : Langue de la réponse (`en` / `fr`)
- `Idempotency-Key` (header, optionnel) : Clé d'idempotence pour les retries. Le hash d'identité couvre la requête complète : le fichier PDF, `invoice_data`, `invoice_patch`, `seller_context`, `buyer_context`, les sélecteurs de profils enregistrés (`profile_reuse`, `issuer_id`/`client_id`, `seller_profile_id`/`buyer_profile_id`), `output`, `validation_target` et les options. Rejouer la même clé avec un de ces éléments modifié retourne `409 idempotency_conflict`.
`invoice_patch` et les contextes inline ne doivent pas écraser silencieusement une valeur visible dans le PDF/XML. En cas de désaccord document/contexte, l'API retourne `409 inline_context_conflict`. `invoice_patch` ne se combine pas avec `invoice_data` complet.

##### Décompte

1 par génération finale, décomptée une seule fois · 0 en simulation dry_run. La simulation dry_run=true ne consomme pas le quota et ne produit pas de livrable final. Un XML candidat peut toutefois être généré. Elle accepte aussi les fichiers XML pour diagnostic, sans création d'un livrable Factur-X.

##### Exemple curl (mode ERP — recommandé)

```
curl -X POST https://api.facturxapi.com/api/v1/convert \
  -H "X-API-Key: votre-cle-api" \
  -F "file=@./facture.pdf" \
  -F "validation_target=en16931" \
  -F 'invoice_data={
  "invoice_number": "FA-2026-042",
  "issue_date": "2026-04-01",
  "invoice_type": "380",
  "currency": "EUR",
  "business_process": "S1",
  "document_notes": [
    {
      "subject_code": "PMT",
      "content": "Indemnite forfaitaire de recouvrement de 40 EUR due en cas de retard de paiement"
    },
    {
      "subject_code": "PMD",
      "content": "Penalites de retard exigibles selon les conditions contractuelles"
    },
    {
      "subject_code": "AAB",
      "content": "Aucun escompte pour paiement anticipe"
    }
  ],
  "seller": {
    "name": "Ma Societe SAS",
    "siret": "99999123500014",
    "vat_id": "FR09999991235",
    "electronic_address": {
      "value": "FRROUTESELLER001",
      "scheme_id": "0225"
    },
    "address": {
      "street": "10 rue de Rivoli",
      "city": "Paris",
      "postal_code": "75001",
      "country": "FR"
    }
  },
  "buyer": {
    "name": "Client SA",
    "siret": "99999245600015",
    "electronic_address": {
      "value": "FRROUTEBUYER001",
      "scheme_id": "0225"
    },
    "address": {
      "street": "20 rue de la Republique",
      "city": "Lyon",
      "postal_code": "69002",
      "country": "FR"
    }
  },
  "payer": {
    "name": "OPCO Formation SA",
    "postal_address": {
      "street": "12 rue de la Formation",
      "city": "Paris",
      "postal_code": "75008",
      "country": "FR"
    },
    "email": "facturation@opco.example",
    "electronic_address": {
      "value": "FRROUTEOPCO001",
      "scheme_id": "0225"
    }
  },
  "references": {
    "buyer_reference": "SERVICE-ACHATS",
    "purchase_order_reference": "PO-2026-0017",
    "contract_reference": "CTR-2026-04"
  },
  "totals": {
    "net": "970.00",
    "tax": "194.00",
    "gross": "1164.00",
    "prepaid_amount": "100.00",
    "rounding_amount": "0.00",
    "due": "1064.00"
  },
  "tax_breakdown": [
    {
      "rate": "20.00",
      "category": "S",
      "base": "970.00",
      "amount": "194.00"
    }
  ],
  "line_items": [
    {
      "number": "1",
      "description": "Prestation conseil",
      "quantity": "10",
      "unit": "C62",
      "unit_price": "100.00",
      "net_amount": "970.00",
      "vat_rate": "20.00",
      "vat_category": "S",
      "purchase_order_line_reference": "10",
      "gross_unit_price": "120.00",
      "price_discount": "20.00",
      "allowances": [
        {
          "amount": "50.00",
          "reason": "Remise ligne",
          "reason_code": "95"
        }
      ],
      "charges": [
        {
          "amount": "20.00",
          "reason": "Supplement urgent"
        }
      ]
    }
  ],
  "payment": {
    "due_date": "2026-05-01",
    "terms": "Paiement a 30 jours",
    "iban": "FR7630006000011234567890189"
  },
  "delivery": {
    "date": "2026-04-01",
    "address": {
      "street": "20 rue de la Republique",
      "city": "Lyon",
      "postal_code": "69002",
      "country": "FR"
    }
  },
  "invoicing_period": {
    "start_date": "2026-04-01",
    "end_date": "2026-04-30"
  }
}'
```

##### Exemple curl (mode extraction texte)

```
curl -X POST https://api.facturxapi.com/api/v1/convert \
  -H "X-API-Key: votre-cle-api" \
  -F "validation_target=en16931" \
  -F "file=@./facture.pdf"
```

##### Exemple curl (simulation selon les règles françaises avec targetPreflight)

```
curl -X POST https://api.facturxapi.com/api/v1/convert \
  -H "X-API-Key: votre-cle-api" \
  -F "dry_run=true" \
  -F "validation_target=france_2026" \
  -F "file=@./facture.pdf"
```

##### Génération finale selon les règles françaises après une simulation exhaustive

Utilisez les racines et chemins indiqués par le `conversionInputRecipe.examplePayload` de la simulation, puis remplacez les exemples par des valeurs réelles confirmées. Les valeurs modèles inchangées sont refusées par l'API ; cet exemple montre le chemin `dry_run` → exemple exploitable → `/convert` final, pas qu’un IBAN seul suffit pour les règles françaises.

```
curl -X POST https://api.facturxapi.com/api/v1/convert \
  -H "X-API-Key: votre-cle-api" \
  -H "Idempotency-Key: facture-france-2026-001" \
  -F "validation_target=france_2026" \
  -F "file=@./facture.pdf" \
  -F 'invoice_patch={"payment":{"iban":"FR7630006000011234567890189"}}' \
  -F 'seller_context={"electronic_address":{"value":"FRROUTESELLER001","scheme_id":"0225"},"document_notes":[{"subject_code":"PMT","content":"Indemnite forfaitaire de recouvrement de 40 EUR due en cas de retard de paiement"},{"subject_code":"PMD","content":"Penalites de retard exigibles selon les conditions contractuelles"},{"subject_code":"AAB","content":"Aucun escompte pour paiement anticipe"}]}' \
  -F 'buyer_context={"electronic_address":{"value":"FRROUTEBUYER001","scheme_id":"0225"}}'
```

##### Exemple curl (avoir DI 0414 avec compléments des règles françaises)

```
curl -X POST https://api.facturxapi.com/api/v1/convert \
  -H "X-API-Key: votre-cle-api" \
  -H "Idempotency-Key: di-0414-2026-05-05-001" \
  -F "file=@./avoir-exemple-public.pdf" \
  -F "validation_target=france_2026" \
  -F 'invoice_patch={"preceding_invoice":{"issue_date":"2025-08-31"},"payment":{"iban":"FR7630006000011234567890189"}}' \
  -F 'seller_context={"electronic_address":{"value":"FRROUTESELLER001","scheme_id":"0225"},"document_notes":[{"subject_code":"PMT","content":"Indemnite forfaitaire de recouvrement de 40 EUR due en cas de retard de paiement"},{"subject_code":"PMD","content":"Penalites de retard exigibles selon les conditions contractuelles"},{"subject_code":"AAB","content":"Aucun escompte pour paiement anticipe"}]}' \
  -F 'buyer_context={"electronic_address":{"value":"FRROUTEBUYER001","scheme_id":"0225"}}'
```

##### Données inline envoyées

```
{
  "invoice_patch": {
    "preceding_invoice": {
      "issue_date": "2025-08-31"
    },
    "payment": {
      "iban": "FR7630006000011234567890189"
    }
  },
  "seller_context": {
    "electronic_address": {
      "value": "FRROUTESELLER001",
      "scheme_id": "0225"
    },
    "document_notes": [
      {
        "subject_code": "PMT",
        "content": "Indemnite forfaitaire de recouvrement de 40 EUR due en cas de retard de paiement"
      },
      {
        "subject_code": "PMD",
        "content": "Penalites de retard exigibles selon les conditions contractuelles"
      },
      {
        "subject_code": "AAB",
        "content": "Aucun escompte pour paiement anticipe"
      }
    ]
  },
  "buyer_context": {
    "electronic_address": {
      "value": "FRROUTEBUYER001",
      "scheme_id": "0225"
    }
  }
}
```

##### Réponse (200)

```
{
  "success": true,
  "target": {
    "requested": "en16931",
    "executed": "en16931",
    "status": "verified",
    "missing_inputs": [],
    "not_run_reason": null
  },
  "result": {
    "durationMs": 2500,
    "targetProfile": "EN16931",
    "conversionSuccessful": true,
    "packagingPerformed": true,
    "xml": "PD94bWwg...",
    "xmlSize": 4096,
    "pdf": "JVBERi0x...",
    "pdfSize": 102400,
    "extraction": {
      "sourceType": "native_text",
      "pageCount": 1
    },
    "validation": {
      "valid": true,
      "profile": "EN16931"
    },
    "processedInvoicesCharged": 1,
    "remainingInvoices": 99
  }
}
```

##### Suivre son quota en production

Pour afficher l'usage côté intégration sur un succès `/convert`, lisez les headers `X-Quota-Limit`, `X-Quota-Remaining` et `X-Quota-Reset` quand ils sont présents. Complétez avec `result.remainingInvoices` dans le corps JSON de la réponse, quand il est présent. Sur une génération finale, `result.processedInvoicesCharged` vaut `1` quand l'appel est décompté ; la clé est omise quand l'appel ne crée pas de nouvelle charge. Un rejeu avec la même `Idempotency-Key` renvoie la réponse enregistrée avec l'en-tête `Idempotent-Replayed: true` ; si elle portait `result.processedInvoicesCharged`, la clé y vaut `0`. En simulation `dry_run=true`, le champ vaut `0`. Une génération refusée sans livrable le porte à `0` dans `result` ; une erreur HTTP renvoyée avant la génération le porte à `0` dans `detail.processedInvoicesCharged`, quand il y figure.

##### Formats attendus dans invoice_data

- Pays : Code ISO 3166-1 alpha-2, deux lettres : « FR », « DE ». Jamais le nom du pays (« France »). Exemple : `"country": "FR"`. Champs : `seller.address.country`, `buyer.address.country`, `delivery.address.country`, `payer.postal_address.country`.

- Dates : AAAA-MM-JJ (ISO 8601) : « 2026-01-15 ». Ces champs refusent JJ/MM/AAAA et une heure. payment.due_date n’a pas ce motif à l’entrée : la conversion le refuse pourtant en 422 invalid_invoice_data s’il n’est pas une date calendaire AAAA-MM-JJ (année 1900 à 2100). Exemple : `"issue_date": "2026-01-15"`. Champs : `issue_date`, `delivery.date`, `invoice_reference_issue_date`, `vat_point_date`, `invoicing_period.start_date`, `invoicing_period.end_date`, `line_items[].period.start_date`, `line_items[].period.end_date`.

- Facture d’origine d’un avoir (BT-25) : Le numéro exact de la facture d’origine, tel qu’il y est écrit : lettres, chiffres et + - _ /, sans espace ni phrase ; 35 caractères au plus pour les règles françaises (règles BR-FR-01 et BR-FR-02). L’API accepte jusqu’à 100 caractères en entrée. Exemple : `"invoice_reference": "FA-2026-001"`. Champs : `invoice_reference`, `invoice_patch.preceding_invoice.reference`.

##### Lire un refus 422

- Le corps d'un refus `422` suit le schéma `ApiErrorEnvelope` : `{ "detail": { "error", "message", … }, "request_id" }`, où `request_id` peut valoir `null`. Lisez `detail.error` : c'est le code stable (par exemple `invalid_data_format` ou `insufficient_data`) ; `detail.message` est le texte lisible.
- Cherchez le contexte dans `detail` : `field` nomme le champ en cause (exemple du contrat : `"error": "invalid_data_format", "field": "issue_date"`) et `missing_fields` liste les champs manquants (`"error": "insufficient_data"`).
- Corrigez l'entrée, puis envoyez-la de nouveau avec une nouvelle `Idempotency-Key` : un `422` ne se relance jamais à l'identique (voir Politique de relance).
- Pour voir tous les constats d'un document avant de générer, lancez `dry_run=true` : la réponse `200` porte la liste `issues[]`, qui n'est pas dans le corps d'un `422`.
- Gardez `request_id` (et l'en-tête `X-Request-ID`) pour le support.
- `errors[]` : le contrat ne décrit aucune liste `errors[]` dans le corps d'un `422` de `/convert` aujourd'hui ; cette page le décrira quand l'API le publiera, ne vous appuyez pas dessus. (La réponse de `/validate` a sa propre liste `errors[]`, avec un autre schéma.)

##### Réponse avec compléments manquants

```
{
  "success": false,
  "dry_run": true,
  "target": {
    "requested": "france_2026",
    "executed": null,
    "status": "blocked",
    "missing_inputs": [
      "seller_context.electronic_address.value",
      "buyer_context.electronic_address.value"
    ],
    "not_run_reason": "missing_inputs"
  },
  "verdict": "convert_with_inputs",
  "missing_fields": [
    "seller_context.electronic_address.value",
    "buyer_context.electronic_address.value"
  ],
  "targetPreflight": {
    "requested": "france_2026",
    "status": "incomplete",
    "exhaustive": false,
    "remainingAfterInputsPolicy": "unknown",
    "requiredInputs": [
      {
        "btCode": "BT-84",
        "ruleRef": "FX-SCH-A-000132",
        "requestContextPath": "invoice_patch.payment.iban"
      },
      {
        "btCode": "BT-34",
        "ruleRef": "BR-FR-13_BT-34",
        "requestContextPath": "seller_context.electronic_address.value"
      },
      {
        "btCode": "BT-49",
        "ruleRef": "BR-FR-12_BT-49",
        "requestContextPath": "buyer_context.electronic_address.value"
      }
    ],
    "automaticFixes": [],
    "unsupportedBlockers": []
  }
}
```

##### Codes d'erreur spécifiques

- `400 file_required_for_pdf_output` : Livrable Factur-X PDF/A-3 demandé sans PDF fourni et sans `invoice_data` complet permettant de rendre le porteur. Fournissez l’une de ces deux sources
- `400 invalid_options_json` : `options` n'est pas un JSON valide ou n'est pas un objet
- `400 invalid_options` : Combinaison invalide, par exemple `options.mode="xml_only"` qui n'est plus le sélecteur public du livrable (utilisez `output=xml_cii`)
- `400 invalid_invoice_patch` : `invoice_patch` combiné avec `invoice_data` complet, ou JSON non objet (même schéma de code pour `invoice_data`, `seller_context`, `buyer_context`)
- `409 inline_context_conflict` : Complément inline en conflit avec une valeur visible dans le document
- `409 idempotency_conflict` : Même `Idempotency-Key` avec une requête différente (fichier, `invoice_data`, sortie, cible ou options modifiés). Corrigez la requête ou utilisez une nouvelle clé intentionnellement
- `409 idempotency_in_progress` : même `Idempotency-Key` et même requête, première requête encore en cours de traitement. Attendez puis réessayez avec la même clé ; n’en créez pas une nouvelle pour forcer un second job.
- `413 file_too_large` : Fichier au-delà de la taille maximale
- `415 unsupported_media_type` : Fichier ni PDF, ni XML source accepté par ce déploiement (CII BASIC/EN16931 lorsque la source CII est activée, UBL Invoice/CreditNote)
- `422 cii_xml_source_overlay_unsupported` / `cii_source_profile_header_only` / `cii_source_unsupported` : uniquement lorsque la source CII est activée sur le déploiement — source XML CII combinée à un complément, sans lignes, ou de guideline non prise en charge
- `400 xml_security_error` : uniquement lorsque la source CII est activée sur le déploiement — XML déclarant un DOCTYPE ou des entités, refusé par sécurité
- `422 ubl_source_not_valid_en16931` / `ubl_source_mapping_unsupported` / `ubl_source_mapping_incomplete` / `ubl_pdf_carrier_required` : Source UBL invalide, non représentable sans perte, incomplète, ou PDF/A-3 demandé sans rendu de porteur disponible
- `422 invalid_invoice_data` : `invoice_data` refusé par une règle EN16931 contrôlée par le moteur (par exemple BR-CO-14 : total de TVA différent de la somme de la ventilation par taux), ou par une règle de catégorie TVA ou de motif d'exonération — le message cite la règle BR en cause
- `422 invalid_invoice_patch` : Date impossible ou champ inline invalide
- `422 insufficient_data` : BT-26 fourni sans référence de facture d'origine effective, ou données insuffisantes pour produire la cible
- `422 unextractable_pdf` : Aucune donnée exploitable extraite du PDF (et pas d'`invoice_data` fourni)
- `422 ocr_confidence_too_low` : Confiance OCR insuffisante en mode `strict`
- `422 unsupported_output_profile_for_invoice_data` : `invoice_data` ne peut pas cibler `MINIMUM`, `BASIC_WL` ou `BASIC` — gardez `EN16931` (défaut) ou `EXTENDED`
- `503 requested_output_unavailable` : Le PDF/A-3 demandé n'a pas pu être produit ; l'API échoue explicitement (quota remboursé) au lieu de retourner un succès XML-only silencieux
- `503 ocr_service_unavailable` / `503 ocr_quota_exhausted` : Service OCR indisponible ou quota OCR épuisé (header `Retry-After` fourni)
Les `400`, `413`, `415` et `422` ci-dessus ne se relancent jamais : corrigez l'entrée (voir Politique de relance).

##### Conversion asynchrone : suivre un job

Quand une conversion est traitée en asynchrone, `POST /api/v1/convert` répond `202` avec `result.jobId` et `result.status = "processing"`. Le traitement asynchrone ne concerne que les PDF scannés (OCR) dont le nombre de pages atteint un seuil fixé par le déploiement, sur les déploiements qui l'activent : un envoi `invoice_data` ou un XML source (CII ou UBL) est toujours traité en synchrone. Cette route de suivi n'apparaît pas encore dans le fichier OpenAPI public, qui ne décrit que la réponse `202`.

- `GET /api/v1/convert/jobs/{jobId}` : même authentification que `/convert` (`X-API-Key` ou `Authorization: Bearer`). Sans clé : `401 authentication_required`. Un job d'un autre compte ou inconnu : `404`, avec `error` = `job_not_found`.
- En-tête de réponse `X-Convert-Job-Status` : `queued`, `running`, `completed`, `failed`, `canceled`, `expired`.
- Tant que le job est `queued` ou `running`, le corps est `success: false` avec `result.status = "processing"` et `target.not_run_reason = "async_processing_not_completed"` : continuez à interroger.
- Job `completed` : même enveloppe que la réponse synchrone de `/convert` (`success`, `target`, `result`), avec des URL signées d'artefacts régénérées à chaque lecture. `completed` ne veut pas dire « vérifié » : lisez `success` et `target.status`.
- Job `failed`, `canceled` ou `expired` : `success: false` et `result.jobId`. Un job `canceled` ou `expired`, un job `failed` sans `result_json`, ou un `result_json` qui n’est pas un objet JSON, rend `result.status = "fail"` avec `result.error.code` et `result.error.message`. Un job `failed` dont le `result_json` est un objet JSON ne conserve `result.error` que si `result` est lui-même un objet : les fichiers livrables en sont retirés, et `result.error` n’est pas réécrit avec `code` et `message`. Si `result` manque ou n’est pas un objet, la réponse remplace `result` par `status` `"fail"`, `error.code` `"job_result_malformed"` et `message` `"Stored job result is malformed"`. Un conflit de contexte porte `error` et `message`, sans `code`. Lisez `result.error` en entier plutôt que de supposer `result.error.code`.
- Pas de `Retry-After` sur un `200` : l'intervalle de polling est à votre charge. Les exemples ci-dessous commencent à 2 s, doublent jusqu'à 10 s et s'arrêtent après 5 minutes : ce sont des valeurs d'exemple, pas des garanties de l'API. Le polling consomme la même limite par minute que le reste de l'API : une `429` porte `Retry-After`.
- Durée de vie : le résultat d'un job est conservé au moins 1 h, 24 h par défaut selon la configuration actuelle du déploiement ; ensuite le job passe en `expired`. Les URL signées d'artefacts ne survivent pas au job.
- Ne refaites pas le `POST` pour « relancer » un job en cours. Avec la même `Idempotency-Key` et la même requête, `POST /api/v1/convert` répond `202` avec ce `jobId` et `result.status = "processing"` quand la clé porte l’identifiant du job et qu’elle est `processing`, ou qu’elle est `completed` et que ce job correspond encore : le résultat se lit alors par la route de suivi, pas dans ce `202`. Une clé `completed` dont le job ne correspond plus ne répond pas `202` : la réponse est un autre `409` (ou `503` si la lecture du job échoue), pas `409 idempotency_in_progress`. Une même clé avec une autre requête répond `409 idempotency_conflict`. Sans `Idempotency-Key`, un nouvel envoi asynchrone crée un nouveau job. Les relances du polling suivent la Politique de relance : seulement `429`, `502`, `503` et `504`, en nombre borné ; `401`, `404` et `500` arrêtent la boucle.

###### Exemple Python

```
import os
import time

import requests

API_KEY = os.environ['FACTURX_API_KEY']
API_URL = 'https://api.facturxapi.com'

def retry_after_seconds(response, default):
    try:
        return float(response.headers.get('Retry-After', default))
    except ValueError:
        return default

def wait_for_convert_job(job_id, max_wait_seconds=300, first_delay=2.0, max_delay=10.0, max_server_errors=3):
    """Poll GET /api/v1/convert/jobs/{job_id}. Never POST /convert again for the same file: that starts a second job."""
    deadline = time.monotonic() + max_wait_seconds
    delay = first_delay
    server_errors = 0
    while time.monotonic() < deadline:
        response = requests.get(
            f'{API_URL}/api/v1/convert/jobs/{job_id}',
            headers={'Authorization': f'Bearer {API_KEY}'},
            timeout=20,
        )
        if response.status_code == 200:
            body = response.json()
            if body['result']['status'] != 'processing':
                return body
            server_errors = 0
            wait = delay
            delay = min(delay * 2, max_delay)
        elif response.status_code == 429:
            wait = retry_after_seconds(response, delay)
        elif response.status_code in (502, 503, 504):
            server_errors += 1
            if server_errors > max_server_errors:
                raise RuntimeError(f'Job {job_id}: HTTP {response.status_code} after {max_server_errors} retries')
            wait = delay
        else:
            # 401, 404 job_not_found, 500 and every other 4xx: no retry. Read "error" and keep the request id.
            raise RuntimeError(f'Job {job_id}: HTTP {response.status_code} {response.text}')
        if time.monotonic() + wait >= deadline:
            break
        time.sleep(wait)
    raise TimeoutError(f'Job {job_id} still processing after {max_wait_seconds} s')

# accepted = response.json() after a 202 from POST /api/v1/convert
job_id = accepted['result']['jobId']
final = wait_for_convert_job(job_id)
if final['result']['status'] == 'fail':
    print('Job failed, canceled or expired:', final['result']['error'])
elif not final.get('success'):
    print('Not verified:', final['target'])
else:
    print('Done:', final['result'].get('pdfUrl') or final['result'].get('xmlUrl'))
```

###### Exemple Node.js (20+)

```
const API_KEY = process.env.FACTURX_API_KEY;
const API_URL = 'https://api.facturxapi.com';
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

function retryAfterMs(response, fallbackMs) {
  const seconds = Number(response.headers.get('Retry-After'));
  return Number.isFinite(seconds) && seconds > 0 ? seconds * 1000 : fallbackMs;
}

// Poll GET /api/v1/convert/jobs/{jobId}. Never POST /convert again for the same file: that starts a second job.
async function waitForConvertJob(jobId, { maxWaitMs = 300_000, firstDelayMs = 2_000, maxDelayMs = 10_000, maxServerErrors = 3 } = {}) {
  const deadline = Date.now() + maxWaitMs;
  let delayMs = firstDelayMs;
  let serverErrors = 0;
  while (Date.now() < deadline) {
    const response = await fetch(API_URL + '/api/v1/convert/jobs/' + jobId, {
      headers: { Authorization: 'Bearer ' + API_KEY },
      signal: AbortSignal.timeout(20_000),
    });
    let waitMs;
    if (response.status === 200) {
      const body = await response.json();
      if (body.result.status !== 'processing') return body;
      serverErrors = 0;
      waitMs = delayMs;
      delayMs = Math.min(delayMs * 2, maxDelayMs);
    } else if (response.status === 429) {
      waitMs = retryAfterMs(response, delayMs);
    } else if ([502, 503, 504].includes(response.status)) {
      serverErrors += 1;
      if (serverErrors > maxServerErrors) throw new Error('Job ' + jobId + ': HTTP ' + response.status + ' after ' + maxServerErrors + ' retries');
      waitMs = delayMs;
    } else {
      // 401, 404 job_not_found, 500 and every other 4xx: no retry. Read "error" and keep the request id.
      throw new Error('Job ' + jobId + ': HTTP ' + response.status + ' ' + (await response.text()));
    }
    if (Date.now() + waitMs >= deadline) break;
    await sleep(waitMs);
  }
  throw new Error('Job ' + jobId + ' still processing after ' + maxWaitMs / 1000 + ' s');
}

// accepted = await response.json() after a 202 from POST /api/v1/convert
const jobId = accepted.result.jobId;
const final = await waitForConvertJob(jobId);
if (final.result.status === 'fail') {
  console.log('Job failed, canceled or expired:', final.result.error);
} else if (!final.success) {
  console.log('Not verified:', final.target);
} else {
  console.log('Done:', final.result.pdfUrl ?? final.result.xmlUrl);
}
```

#### POST /api/v1/repair

Analyse un fichier XML CII et applique uniquement les corrections déterministes couvertes (format de date, séparateur décimal, namespaces, codes d’unité UN/ECE, casse devise, schemeID manquants lorsqu’une valeur prise en charge peut être déduite sans ambiguïté). Ne recalcule ni les totaux ni la TVA et n’invente aucune donnée métier. Retourne le XML obtenu (`repaired_xml`), le diff détaillé et la validation avant/après. `repairSuccessful` vaut `true` seulement si au moins une correction a été appliquée et si la cible demandée est vérifiée après correction (`targetVerified`) ; sinon la réponse reste un diagnostic, et la présence de `repaired_xml` ne prouve pas la conformité. Dans l’outil Web, le téléchargement du XML n’est proposé que lorsque la cible est vérifiée.

##### Paramètres

- `file` (multipart, requis) : Fichier XML CII à corriger
- `constraints` (form field, optionnel) : Contraintes de réparation au format JSON

- `max_changes_allowed` : Nombre max de modifications (0 à 1 000)
- `do_not_modify_amounts` : Interdit toute modification de montant (booléen, défaut : `true`). Si `false`, seules les normalisations décimales déterministes couvertes peuvent modifier les montants ; aucun total métier n’est recalculé.
- `do_not_invent_missing_parties` : Interdit tout ajout de partie absente (booléen, défaut : `true`). Aucune donnée métier manquante n’est déduite ou créée.

- `target_profile` (query, optionnel) : Profil Factur-X cible
- `lang` (query, optionnel) : Langue de la réponse (`en` / `fr`)
- `Idempotency-Key` (header, optionnel) : Clé d'idempotence pour les retries

##### Décompte

1 facture traitée.

##### Exemple curl

```
curl -X POST https://api.facturxapi.com/api/v1/repair \
  -H "X-API-Key: votre-cle-api" \
  -F "file=@./facture.xml"
```

##### Réponse (200)

```
{
  "durationMs": 124,
  "repaired_xml": "PD94bWwg...",
  "target": {
    "requested": "en16931",
    "executed": "en16931",
    "status": "verified",
    "missing_inputs": [],
    "not_run_reason": null
  },
  "repairSuccessful": true,
  "diff_summary": [
    {
      "code": "format_corrected",
      "path": "/rsm:CrossIndustryInvoice/.../ram:IssueDateTime",
      "message": "Corrected date format from '2024-01-15' to '20240115'",
      "ruleReference": "R001"
    }
  ],
  "validation_before": {
    "valid": false,
    "target": {
      "requested": "en16931",
      "executed": "en16931",
      "status": "failed",
      "missing_inputs": [],
      "not_run_reason": null
    },
    "summary": {
      "errorCount": 2,
      "warningCount": 0
    }
  },
  "validation_after": {
    "valid": true,
    "target": {
      "requested": "en16931",
      "executed": "en16931",
      "status": "verified",
      "missing_inputs": [],
      "not_run_reason": null
    },
    "summary": {
      "errorCount": 0,
      "warningCount": 0
    }
  }
}
```

##### Codes d'erreur spécifiques

- `401 authentication_required` : Aucune clé API dans la requête (ni `X-API-Key` ni `Authorization: Bearer`). `401 invalid_api_key` : Clé invalide ou révoquée. Corps JSON dans les deux cas : `detail.error`, `detail.message`, `detail.supported_methods` (méthodes d’authentification acceptées) et `request_id`
- `415` : Le fichier n'est pas du XML
- `422` : Erreur de parsing XML ou contrainte de réparation dépassée

### Format de réponse

Chaque endpoint retourne un objet JSON. Les formats de réponse spécifiques sont documentés dans chaque section d'endpoint ci-dessus. Pour `/validate`, le format par défaut est le rapport unifié multi-étapes.

#### Validation — format unifié par défaut (200 OK)

La réponse détaille le verdict global, le temps de traitement, le résumé, les étapes PDF/A-3, Factur-X PDF, XSD et Schematron, ainsi que le périmètre exécuté. Le champ `message` n'existe que dans le mode legacy.

```
{
  "valid": true,
  "target": {
    "requested": "en16931",
    "executed": "en16931",
    "status": "verified",
    "missing_inputs": [],
    "not_run_reason": null
  },
  "validatedAt": "2026-04-28T10:00:00.000Z",
  "filename": "invoice.xml",
  "profile": "EN16931",
  "durationMs": 124,
  "summary": {
    "errorCount": 0,
    "warningCount": 0
  },
  "issues": [],
  "stages": {
    "pdfa": {
      "passed": true,
      "skipped": true,
      "skip_reason": "XML file - PDF/A validation not applicable",
      "error_count": 0,
      "warning_count": 0,
      "info_count": 0,
      "issues": []
    },
    "facturx_pdf": {
      "passed": true,
      "skipped": true,
      "skip_reason": "XML file - PDF checks not applicable",
      "error_count": 0,
      "warning_count": 0,
      "info_count": 0,
      "issues": []
    },
    "xsd": {
      "passed": true,
      "skipped": false,
      "error_count": 0,
      "warning_count": 0,
      "info_count": 0,
      "issues": []
    },
    "schematron": {
      "passed": true,
      "skipped": false,
      "error_count": 0,
      "warning_count": 0,
      "info_count": 0,
      "issues": []
    }
  },
  "errors": [],
  "warnings": []
}
```

##### Champs

- `valid` (boolean) : `true` si aucune erreur n’est détectée dans le périmètre exécuté, `false` sinon
- `validatedAt` (string) : Horodatage ISO du diagnostic
- `filename` (string|null) : Nom du fichier analysé
- `durationMs` (number) : Durée du traitement
- `summary` (object) : Compteurs `errorCount` et `warningCount`
- `issues` (array) : Liste plate des erreurs, avertissements et informations
- `stages` (object) : Résultat détaillé par étape de validation
- `validationScopeLabel` / `appliedValidationProfiles` : périmètre réellement exécuté (EN16931 seul ou règles françaises (FNFE-MPE) si demandé et disponible)
- `skippedValidationProfiles` / `unsupportedValidationProfiles` : cible demandée mais non exécutée ou non supportée
- `legalDisclaimer` : mention à afficher aux utilisateurs; le diagnostic ne vaut pas acceptation PA
- `profile` (string|null) : Profil Factur-X détecté (`EN16931`, `Basic`, `Minimum`, `Extended`)
- `errors` / `warnings` (array) : Champs de compatibilité pour les anciens clients

##### Format court legacy (?legacy=true)

```
{
  "valid": true,
  "errors": [],
  "warnings": [],
  "profile": "EN16931",
  "message": "Validation completed",
  "target": {
    "requested": "en16931",
    "executed": "en16931",
    "status": "verified",
    "missing_inputs": [],
    "not_run_reason": null
  }
}
```

##### Structure d'une issue

```
{
  "code": "BR-CO-10",
  "severity": "error",
  "stage": "schematron",
  "message": "Sum of invoice line net amounts must equal invoice total net amount.",
  "line": 42,
  "location": "line 42",
  "ruleId": "BR-CO-10",
  "xpath": "/rsm:CrossIndustryInvoice/.../ram:SpecifiedTradeSettlementHeaderMonetarySummation"
}
```

##### Types d'erreurs

- `stage: "pdfa"` : conformité PDF/A-3 du conteneur
- `stage: "facturx_pdf"` : présence et cohérence des métadonnées Factur-X dans le PDF
- `stage: "xsd"` : structure XML CII
- `stage: "schematron"` : règles métier EN16931 et profil Factur-X

### Exemples de code

```
curl -X POST https://api.facturxapi.com/api/v1/validate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@./facture.pdf"
```

```
// Avec fetch API
const formData = new FormData();
formData.append('file', file);

const response = await fetch('https://api.facturxapi.com/api/v1/validate', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  },
  body: formData
});

const result = await response.json();
console.log(result.valid ? '✅ Valid' : '❌ Invalid');
console.log('Errors:', result.errors);
console.log('Profile:', result.profile);
```

```
import requests

# Upload et validation
with open('facture.pdf', 'rb') as f:
    response = requests.post(
        'https://api.facturxapi.com/api/v1/validate',
        headers={'Authorization': 'Bearer YOUR_API_KEY'},
        files={'file': f}
    )

result = response.json()
print('✅ Valid' if result['valid'] else '❌ Invalid')
print('Errors:', result['errors'])
print('Profile:', result['profile'])
```

### Codes d'erreur HTTP

Code | Description |
`200` | Requête traitée avec succès (le résultat peut indiquer des erreurs de validation) |
`400` | Fichier vide ou invalide (`Empty file`) |
`401` | Clé API manquante ou invalide |
`413` | Fichier trop volumineux (`file_too_large`) |
`415` | Format de fichier non supporté (PDF attendu pour extract, XML pour repair ; sources de convert : voir POST /api/v1/convert) |
`422` | Contenu non traitable (XML absent, données insuffisantes, confiance OCR trop basse, contrainte de réparation dépassée) |
`402` | Quota mensuel de factures atteint (`quota_exceeded`) |
`429` | Rate limit par minute (`rate_limit_exceeded`) : 60 requêtes par minute sur cette API, selon GET /meta (voir Limite par minute) |
`500` | Erreur serveur (stockage, traitement) |
`503` | Service temporairement indisponible (moteur de validation, OCR ou génération du PDF/A-3) |

### Limites

#### Quota mensuel

Le quota mensuel dépend de l'offre choisie. En public, retenez surtout : Sandbox = 100 factures traitées offertes les 14 premiers jours, puis 10 factures traitées/mois, Launch = 100 factures traitées par mois, Scale = 500 factures traitées par mois, Business = 2 000 factures traitées par mois ; sur-volume et contrat sur devis. Pilote accompagné se qualifie au cas par cas.

#### Comprendre le quota mensuel

[Règle de décompte](https://facturxapi.com/pricing#credits)

Fonction API | Factures traitées | Quand l'utiliser |
`POST /api/v1/validate` | 1 facture traitée | Diagnostiquer une facture Factur-X déjà produite |
`POST /api/v1/extract` | 1 facture traitée | Extraire le XML CII embarqué dans un PDF Factur-X |
`POST /api/v1/repair` | 1 facture traitée | Réparer un XML CII invalide avant transmission |
`POST /api/v1/convert` | 1 par génération finale, décomptée une seule fois · 0 en simulation dry_run | Générer un Factur-X PDF/A-3 avec XML embarqué et contrôles de sortie |

Le validateur public reste gratuit et séparé du quota API.

#### Limite par minute

60 requêtes par minute sur `https://api.facturxapi.com` : valeur lue dans [GET https://api.facturxapi.com/meta](https://api.facturxapi.com/meta) (`limits.rate_limit_requests_per_minute`) lors de la génération de cette page. La limite dépend de l'environnement : relisez `/meta` de l'API que vous appelez. Au-delà, l'API répond `429 rate_limit_exceeded` avec l'en-tête `Retry-After`.

#### Taille fichier

Taille maximale par défaut : 10 MB

#### Timeout

Sur `/convert`, un délai dépassé est signalé par une erreur 504 (OCR ou génération du PDF). Prévoyez un timeout client large pour cet appel.

### Bonnes pratiques

- Toujours vérifier le champ `valid` avant de traiter la réponse
- Logger les erreurs de type `schematron_failed_assert` pour analyse métier
- Gérer les timeouts et les erreurs réseau (429, 502, 503, 504, timeout) avec un nombre de relances borné
- Ne pas stocker la clé API en dur dans le code (variables d'environnement)
- Relancer avec un backoff exponentiel seulement dans les cas de la politique de relance ci-dessous

#### Politique de relance

- Ne relancez pas à l’identique un 400, 413, 415 ou 422 : selon la stratégie publiée pour le code, corrigez l’entrée et envoyez la requête corrigée avec une nouvelle Idempotency-Key, ou contactez le support avec le request_id (par exemple request_failed).
- Seuls 429 (en attendant le délai du header Retry-After), 502, 503 et 504 peuvent se relancer, et pas tous : relancez seulement si la stratégie publiée pour le code le prévoit, avec un nombre de relances borné (par exemple 3) et la même Idempotency-Key pour la même requête. Cas particulier, 409 idempotency_in_progress (même requête, même clé, première requête encore en cours de traitement) : attendez puis relancez avec la même clé ; ne changez pas de clé, cela lancerait une seconde opération. D’autres codes 409 ont leur propre stratégie dans x-facturx-convert-error-registry.
- 402 : ce n’est pas une relance. Pour quota_exceeded (quota mensuel atteint), le renouvellement du quota ou un changement de plan le lève ; les autres 402 ont leur stratégie dans x-facturx-convert-error-registry.
- 500 : pas de relance automatique. Conservez le request_id et contactez le support.
- La stratégie de chaque code est publiée dans le fichier OpenAPI, extension x-facturx-convert-error-registry de POST /api/v1/convert : relancer avec la même clé, attendre Retry-After, corriger la requête, passer en output=xml_cii, suivre le job, contacter le support avec le request_id, ou quota remboursé. Un 503 ou un 504 ne se relance pas toujours : certains codes demandent de contacter le support, parfois après le délai Retry-After.

### Support

Besoin d'aide ? Contactez-nous :

- Email : [contact@facturxapi.com](mailto:contact@facturxapi.com)

#### Prêt à intégrer l'API ?

Obtenez votre clé API gratuitement et commencez à appeler le moteur avec un quota clair en factures traitées.

[Obtenir une clé API](https://facturxapi.com/api-key)

Et après ?

### Accélérez l'intégration

Choisissez l'étape suivante pour activer FacturX API sur votre stack.

[🔑 #### Obtenir une clé API Créez une clé sandbox (100 factures traitées offertes les 14 premiers jours, puis 10 factures traitées/mois) et testez depuis votre environnement.](https://facturxapi.com/api-key?source=docs_next_steps)[🧩 #### Snippets par langage PHP, Python, Node.js, Laravel, Symfony, .NET. OpenAPI et Postman téléchargeables.](https://facturxapi.com/integrations?source=docs_next_steps)[📛 #### Bibliothèque d'erreurs EN16931 43 fiches d'erreurs EN16931 : cause, où regarder, exemple et correction.](https://facturxapi.com/errors?source=docs_next_steps)[🔬 #### Méthodologie Pipeline : fichier reçu → PDF/A-3 si PDF → Factur-X / XML embarqué → XSD CII → Schematron EN16931 → rapport correctif.](https://facturxapi.com/methodologie?source=docs_next_steps)[💶 #### Comparer les plans Sandbox, Launch, Scale, Business et programmes accompagnés avec le quota mensuel associé.](https://facturxapi.com/pricing?source=docs_next_steps)

---

# Bibliothèque d’erreurs

Source : https://facturxapi.com/errors

EN16931

## Bibliothèque d'erreurs Factur-X

43 fiches d'erreurs EN16931 : cause métier, où regarder, exemple minimal et correction concrète. Utilisez-les pour alimenter votre monitoring et votre backlog correctif.

[BR-02 ### Numéro de facture absent Le champ BT-1 (numéro de facture) est obligatoire et ne peut pas être vide.](https://facturxapi.com/errors/br-02)[BR-05 ### Code devise absent Le code devise de la facture (BT-5) est obligatoire. Un champ absent ou vide déclenche cette erreur.](https://facturxapi.com/errors/br-05)[BR-16 ### Aucune ligne de facture La facture doit contenir au moins une ligne (BG-25). Un XML sans ligne de détail déclenche cette erreur.](https://facturxapi.com/errors/br-16)[BR-06 ### Nom du vendeur absent La facture doit contenir le nom du vendeur (BT-27). Un vendeur sans nom déclenche cette erreur.](https://facturxapi.com/errors/br-06)[BR-07 ### Nom de l'acheteur absent La facture doit contenir le nom de l'acheteur (BT-44). Un acheteur sans nom déclenche cette erreur.](https://facturxapi.com/errors/br-07)[BR-62 ### Adresse électronique du vendeur sans schemeID L'adresse électronique du vendeur (BT-34) doit avoir un identifiant de schéma (schemeID).](https://facturxapi.com/errors/br-62)[BR-63 ### Adresse électronique de l'acheteur sans schemeID L'adresse électronique de l'acheteur (BT-49) doit avoir un identifiant de schéma (schemeID).](https://facturxapi.com/errors/br-63)[BR-08 ### Adresse postale du vendeur absente La facture doit contenir l'adresse postale du vendeur (BG-5).](https://facturxapi.com/errors/br-08)[BR-10 ### Adresse postale de l'acheteur absente La facture doit contenir l'adresse postale de l'acheteur (BG-8).](https://facturxapi.com/errors/br-10)[BR-21 ### Identifiant de ligne vide Chaque ligne de facture (BG-25) doit avoir un identifiant de ligne (BT-126).](https://facturxapi.com/errors/br-21)[BR-23 ### Quantité facturée sans unité Une ligne de facture (BG-25) doit avoir un code d'unité de mesure de la quantité facturée (BT-130).](https://facturxapi.com/errors/br-23)[BR-25 ### Nom de l'article vide Chaque ligne de facture (BG-25) doit contenir le nom de l'article (BT-153).](https://facturxapi.com/errors/br-25)[BR-27 ### Prix net de l'article négatif Le prix net de l'article (BT-146) ne doit pas être négatif.](https://facturxapi.com/errors/br-27)[BR-29 ### Période de facturation : fin avant début Si la date de début (BT-73) et la date de fin (BT-74) de la période de facturation sont données, la date de fin doit être postérieure ou égale à la date de début.](https://facturxapi.com/errors/br-29)[BR-30 ### Période de ligne : fin avant début Si la date de début (BT-134) et la date de fin (BT-135) de la période d'une ligne sont données, la date de fin doit être postérieure ou égale à la date de début.](https://facturxapi.com/errors/br-30)[BR-33 ### Remise de document sans motif Chaque remise au niveau du document (BG-20) doit avoir un motif (BT-97) ou un code motif (BT-98).](https://facturxapi.com/errors/br-33)[BR-38 ### Frais de document sans motif Tout frais au niveau du document (BG-21) doit avoir un motif (BT-104) ou un code motif (BT-105).](https://facturxapi.com/errors/br-38)[BR-48 ### Ventilation TVA sans taux Chaque ventilation de TVA (BG-23) doit avoir un taux (BT-119), sauf si la facture n'est pas soumise à la TVA.](https://facturxapi.com/errors/br-48)[BR-55 ### Référence de facture antérieure vide Chaque référence à une facture antérieure (BG-3) doit contenir le numéro de cette facture (BT-25).](https://facturxapi.com/errors/br-55)[BR-S-05 ### Ligne au taux normal avec un taux de 0 % Sur une ligne dont la catégorie de TVA (BT-151) est « Standard rated » (S), le taux (BT-152) doit être supérieur à zéro.](https://facturxapi.com/errors/br-s-05)[BR-S-08 ### Base TVA au taux normal différente de la somme des lignes Pour chaque taux de la catégorie S, la base de la ventilation (BT-116) doit être égale à la somme des montants nets des lignes à ce taux, plus les frais et moins les remises de document de la même catégorie et du même taux.](https://facturxapi.com/errors/br-s-08)[BR-DEC-09 ### Total net des lignes avec plus de 2 décimales Le nombre maximal de décimales autorisé pour le total net des lignes (BT-106) est 2.](https://facturxapi.com/errors/br-dec-09)[BR-DEC-12 ### Total HT de la facture avec plus de 2 décimales Le nombre maximal de décimales autorisé pour le total HT de la facture (BT-109) est 2.](https://facturxapi.com/errors/br-dec-12)[BR-DEC-14 ### Total TTC de la facture avec plus de 2 décimales Le nombre maximal de décimales autorisé pour le total TTC de la facture (BT-112) est 2.](https://facturxapi.com/errors/br-dec-14)[BR-DEC-18 ### Montant à payer avec plus de 2 décimales Le nombre maximal de décimales autorisé pour le montant à payer (BT-115) est 2.](https://facturxapi.com/errors/br-dec-18)[BR-DEC-19 ### Base de la ventilation TVA avec plus de 2 décimales Le nombre maximal de décimales autorisé pour la base de la ventilation TVA (BT-116) est 2.](https://facturxapi.com/errors/br-dec-19)[BR-DEC-20 ### Montant de TVA de la ventilation avec plus de 2 décimales Le nombre maximal de décimales autorisé pour le montant de TVA de la ventilation (BT-117) est 2.](https://facturxapi.com/errors/br-dec-20)[BR-DEC-23 ### Montant net de ligne avec plus de 2 décimales Le nombre maximal de décimales autorisé pour le montant net de ligne (BT-131) est 2.](https://facturxapi.com/errors/br-dec-23)[BR-FR-05 ### Mention de l'indemnité forfaitaire de recouvrement absente La mention relative aux frais de recouvrement (note de code PMT) est absente ; elle est obligatoire dans les notes de la facture (BG-1).](https://facturxapi.com/errors/br-fr-05)[BR-FR-10 ### SIREN du vendeur absent Le SIREN du vendeur (BT-30) est obligatoire et doit être composé exactement de 9 chiffres.](https://facturxapi.com/errors/br-fr-10)[BR-CO-09 ### Numéro de TVA sans préfixe pays Les numéros de TVA du vendeur (BT-31), du représentant fiscal du vendeur (BT-63) et de l'acheteur (BT-48) doivent commencer par un code pays ISO 3166-1 alpha-2 ; la Grèce peut utiliser EL.](https://facturxapi.com/errors/br-co-09)[BR-CO-11 ### Total des remises sans remise correspondante Le total des remises de document (BT-107) doit être égal à la somme des montants de remise de document (BT-92).](https://facturxapi.com/errors/br-co-11)[BR-CO-19 ### Période de facturation vide Si la période de facturation (BG-14) est utilisée, la date de début (BT-73) ou la date de fin (BT-74) doit être renseignée, ou les deux.](https://facturxapi.com/errors/br-co-19)[BR-CO-10 ### Total HT lignes incohérent La somme des montants nets de ligne (BT-131) doit être égale au total net des lignes déclaré en en-tête (BT-106).](https://facturxapi.com/errors/br-co-10)[BR-CO-12 ### Total des charges document incohérent La somme des montants de charges au niveau document (BG-21) doit être égale au total des charges déclaré (BT-108).](https://facturxapi.com/errors/br-co-12)[BR-CO-13 ### Total HT facture incohérent Le total HT facture (BT-109) doit être égal à la somme des lignes + charges document − remises document.](https://facturxapi.com/errors/br-co-13)[BR-CO-14 ### Total TVA différent de la somme des ventilations Le montant total de TVA de la facture (BT-110) doit être égal à la somme des montants de TVA de chaque ventilation par catégorie (BT-117).](https://facturxapi.com/errors/br-co-14)[BR-CO-15 ### Total TTC facture incohérent Le total avec TVA (BT-112) doit être égal au total HT (BT-109) plus le montant total de TVA (BT-110).](https://facturxapi.com/errors/br-co-15)[BR-CO-17 ### Montant TVA calculé incorrect Le montant TVA par catégorie (BT-117) doit être égal au montant HT taxable (BT-116) multiplié par le taux (BT-119) divisé par 100, arrondi à 2 décimales. Le contrôle tolère un écart dont la borne dépend de la syntaxe (CII ou UBL) et du taux.](https://facturxapi.com/errors/br-co-17)[BR-CO-26 ### Identifiant vendeur manquant Pour identifier le vendeur, au moins l'un des trois identifiants doit être présent : BT-29 (identifiant commercial), BT-30 (identifiant d'enregistrement légal, SIREN en France), ou BT-31 (numéro de TVA).](https://facturxapi.com/errors/br-co-26)[BR-CO-16 ### Montant à payer incohérent Le montant à payer (BT-115) doit être égal au total TTC (BT-112) moins le montant déjà payé (BT-113) plus l’arrondi (BT-114).](https://facturxapi.com/errors/br-co-16)[BR-CL-04 ### Code devise invalide Le code devise (BT-5) doit être un code ISO 4217 alpha-3 valide. Un code comme "EURO" au lieu de "EUR" déclenche cette erreur.](https://facturxapi.com/errors/br-cl-04)[BR-CL-25 ### SchemeID d’identifiant de routage électronique invalide BR-CL-25 : le schemeID de l'identifiant de routage électronique du vendeur ou de l'acheteur doit appartenir à la liste EAS autorisée.](https://facturxapi.com/errors/br-cl-25)

### Règles françaises de la facture électronique

Message officiel, exemple refusé puis accepté par l'API, correction.
[BR-FR-01 #### Numéro de facture trop long (plus de 35 caractères) Règle française BR-FR-01 : le numéro de facture ne doit pas dépasser 35 caractères. Message officiel, exemple refusé puis accepté par l'API, correction.](https://facturxapi.com/errors/br-fr-01)[BR-FR-02 #### Numéro de facture avec des caractères interdits Règle française BR-FR-02 : le numéro de facture n'accepte que lettres, chiffres et + - _ /, sans espace. Message officiel, exemple vérifié, correction.](https://facturxapi.com/errors/br-fr-02)[BR-FR-03 #### Date avec une année hors de 2000 à 2099 Règle française BR-FR-03 : les dates de la facture doivent avoir une année entre 2000 et 2099. Exemple refusé (échéance en 2126) puis accepté, correction.](https://facturxapi.com/errors/br-fr-03)[BR-FR-04 #### Code type de document non autorisé en France Règle française BR-FR-04 : seuls 16 codes type de document sont acceptés (380, 381, 384, 389…). Liste officielle, exemple refusé avec 326, correction.](https://facturxapi.com/errors/br-fr-04)[BR-FR-06 #### Mention obligatoire présente deux fois dans les notes Règle française BR-FR-06 : les mentions PMT, PMD, AAB et TXD ne doivent apparaître qu'une fois dans les notes. Exemple vérifié avec PMT en double, correction.](https://facturxapi.com/errors/br-fr-06)[BR-FR-08 #### Cadre de facturation absent ou inconnu Règle française BR-FR-08 : le cadre de facturation (B1, S1, M1…) doit être une des 20 valeurs autorisées. Exemple refusé, valeurs acceptées, correction.](https://facturxapi.com/errors/br-fr-08)[BR-FR-09 #### SIRET qui ne commence pas par le SIREN Règle française BR-FR-09 : un SIRET doit avoir 14 chiffres et commencer par le SIREN de la même partie. Exemple vérifié, correction du vendeur ou de l'acheteur.](https://facturxapi.com/errors/br-fr-09)[BR-FR-11 #### Facture B2B sans SIREN de l'acheteur Règle française BR-FR-11 : une facture marquée B2B (note BAR) doit porter le SIREN de l'acheteur, sur 9 chiffres. Exemple vérifié, correction.](https://facturxapi.com/errors/br-fr-11)[BR-FR-12 #### Adresse électronique de l'acheteur manquante Règle française BR-FR-12 : l'adresse électronique de l'acheteur (BT-49) est obligatoire. Exemple refusé puis accepté par l'API, correction pas à pas.](https://facturxapi.com/errors/br-fr-12)[BR-FR-13 #### Adresse électronique du vendeur manquante Règle française BR-FR-13 : l'adresse électronique du vendeur (BT-34) est obligatoire. Exemple refusé puis accepté par l'API, correction.](https://facturxapi.com/errors/br-fr-13)[BR-FR-16 #### Taux de TVA non autorisé en France Règle française BR-FR-16 : le taux de TVA doit être un des taux de la liste officielle, sans symbole %. Exemple refusé avec 21 %, liste des taux, correction.](https://facturxapi.com/errors/br-fr-16)[BR-FR-20 #### Valeur de traitement (note BAR) inconnue Règle française BR-FR-20 : la note BAR doit valoir B2B, B2BINT, B2C, B2CINT, OUTOFSCOPE ou ARCHIVEONLY. Exemple refusé, correction.](https://facturxapi.com/errors/br-fr-20)[BR-FR-21 #### Facture B2B : adresse électronique de l'acheteur sans SIREN ni schéma 0225 Règle française BR-FR-21 : en B2B, l'adresse électronique de l'acheteur doit commencer par son SIREN, avec le schéma 0225. Exemple vérifié, correction.](https://facturxapi.com/errors/br-fr-21)[BR-FR-23 #### Adresse électronique au format non autorisé Règle française BR-FR-23 : une adresse électronique 0225 n'accepte que lettres, chiffres et - _ . Exemple refusé avec « # », correction.](https://facturxapi.com/errors/br-fr-23)[BR-FR-32-LEGALID #### SIREN d'une partie qui n'a pas 9 chiffres Règle française BR-FR-32 : un identifiant légal déclaré avec le schéma 0002 (SIREN) doit compter exactement 9 chiffres, sans lettre. Exemple vérifié.](https://facturxapi.com/errors/br-fr-32-legalid)[BR-FR-CO-04 #### Facture rectificative sans référence à la facture d'origine Règle française BR-FR-CO-04 : une facture rectificative (384, 471, 472, 473) doit référencer une et une seule facture antérieure, avec sa date. Exemple vérifié.](https://facturxapi.com/errors/br-fr-co-04)[BR-FR-CO-05 #### Avoir sans référence à la facture d'origine Règle française BR-FR-CO-05 : un avoir (261, 381, 396, 502, 503) doit référencer la facture d'origine et sa date. Message officiel, exemple vérifié, correction.](https://facturxapi.com/errors/br-fr-co-05)[BR-FR-CO-07 #### Date d'échéance antérieure à la date de facture Règle française BR-FR-CO-07 : la date d'échéance (BT-9), si elle est indiquée, ne peut pas précéder la date de facture (BT-2), sauf acompte ou cadre B2, S2, M2.](https://facturxapi.com/errors/br-fr-co-07)[BR-FR-CO-09 #### Facture déjà payée : montant payé différent du total TTC Règle française BR-FR-CO-09 : avec un cadre B2, S2 ou M2 (facture déjà payée), le montant payé doit égaler le total TTC. Exemple vérifié, correction.](https://facturxapi.com/errors/br-fr-co-09)[BR-FR-CO-10 #### Identifiant du vendeur sans schéma d'identification Règle française BR-FR-CO-10 : un identifiant du vendeur (BT-29) doit toujours porter son schéma (BT-29-1). Exemple vérifié, correction.](https://facturxapi.com/errors/br-fr-co-10)[BR-FR-DEC-01 #### Montant de facture avec plus de 2 décimales Règle française BR-FR-DEC-01 : totaux, TVA, remises, frais et montants nets de ligne : au plus 2 décimales, un point décimal, 19 caractères hors point. Exemple.](https://facturxapi.com/errors/br-fr-dec-01)[BR-FR-DEC-03 #### Prix d'article négatif ou mal formaté Règle française BR-FR-DEC-03 : prix net, prix brut et remise d'une ligne positifs (sauf S9, M9, B9), au plus 6 décimales et 19 chiffres. Exemple.](https://facturxapi.com/errors/br-fr-dec-03)

### Autres règles de la norme EN 16931

Message officiel, exemple refusé puis accepté par l'API, correction.
[BR-CO-03 #### Date et code du fait générateur de TVA tous les deux présents Règle EN 16931 BR-CO-03 : la date du fait générateur de TVA (BT-7) et son code (BT-8) s'excluent. Exemple refusé puis accepté par l'API, correction.](https://facturxapi.com/errors/br-co-03)[BR-S-10 #### TVA au taux normal avec un motif d'exonération Règle EN 16931 BR-S-10 : une ventilation au taux normal (S) ne doit pas porter de motif d'exonération. Exemple refusé puis accepté par l'API, correction.](https://facturxapi.com/errors/br-s-10)

---

# Méthodologie

Source : https://facturxapi.com/methodologie

Diagnostic technique

## Notre méthodologie de validation

Un diagnostic qui sépare PDF/A-3, Factur-X, XSD, Schematron et rapport correctif
EN16931, sans prétendre à une acceptation par une Plateforme Agréée.

Méthodologie relue le 22 septembre 2026.

### Vérifiez le validateur vous-même : deux fichiers, leur résultat attendu

Exécution le 6 novembre 2026, entre 16:24 et 16:25 UTC sur l’environnement de staging,
API révision `900685311ea7`, par le même point d’entrée que la page /scan, sans compte.
Données fictives.

Fichier | Contrôles du service (staging) | Contrôle indépendant CEN 1.3.16 |
[Facture d’exemple valide (PDF)](https://facturxapi.com/demo/facturx-valid-sample.pdf) | PDF/A-3, Factur-X, XSD et Schematron réussis ; France 2026 exécutée sans constat. Verdict affiché : AUCUNE ACTION REQUISE. | XML embarqué : 0 assertion en échec. |
[Facture d’exemple invalide (XML)](https://facturxapi.com/demo/scan-test-files-20261106/facture-exemple-invalide-br-co-16.xml)
Même facture, deux changements : numéro suffixé « -BRCO16 » et montant à payer BT-115 = 1100.00 au lieu de 1200.00. | XSD réussi ; 1 erreur bloquante [BR-CO-16](https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/BR-CO-16/) ; règles France 2026 bloquées tant que la base échoue. Verdict affiché : CORRECTION EN16931 REQUISE. | BR-CO-16 seule, niveau fatal. |

Pour le XML CII, le service applique le Schematron du paquet Factur-X 1.09.2
(artefact `facturx-1.09.2-en16931-cii`, SHA-256 `67f03050e3add4c8…`, lu dans la réponse).
Le contrôle indépendant applique l’autre référentiel publié, le XSLT CEN EN16931 1.3.16, hors du service.

[Réponses, empreintes SHA-256 et contrôle indépendant](https://facturxapi.com/demo/scan-test-files-20261106/README.md)
· [Dossier d’une conversion JSON → Factur-X, avec ses limites](https://facturxapi.com/demo/integration-proof-20261105/README.md)

Pour reproduire : téléchargez les deux fichiers et [déposez-les sur le scanner](https://facturxapi.com/scan).

1

### Conformité PDF/A-3 (ISO 19005-3)

Vérification que le PDF est conforme à la norme d'archivage PDF/A-3,
prérequis obligatoire pour toute facture Factur-X.

#### Ce que nous vérifions :

- ✓ Structure PDF conforme à ISO 32000-1:2008
- ✓ Polices embarquées (pas de dépendances externes)
- ✓ Métadonnées XMP correctement formatées
- ✓ Restrictions PDF/A-3 sur les actions JavaScript et les contenus actifs
- ✓ Fichiers embarqués autorisés (niveau PDF/A-3)
Moteur : veraPDF

Nous utilisons [veraPDF](https://verapdf.org),
un validateur open source qui applique des profils de contrôle PDF/A.
Le résultat décrit les exigences testées ; il ne constitue pas un service d’archivage légal.

2

### Contrôles Factur-X sur le PDF

Vérification des règles spécifiques Factur-X : présence et conformité
de l'attachement XML et des métadonnées XMP.

#### Ce que nous vérifions :

- ✓ Attachement XML Présence du fichier `factur-x.xml` (ou `zugferd-invoice.xml`)

- ✓ AFRelationship Relation fichier correcte : `/Data`, `/Alternative` ou `/Source`

- ✓ Métadonnées XMP Factur-X Namespace et propriétés `fx:DocumentType`, `fx:ConformanceLevel`

3

### Validation XSD (Schéma XML)

Vérification de la structure XML contre le schéma XSD officiel
UN/CEFACT Cross-Industry Invoice (CII) correspondant au profil et aux artefacts sélectionnés pour le document.

#### Ce que nous vérifions :

- ✓ Structure XML conforme au profil détecté
- ✓ Éléments obligatoires présents
- ✓ Types de données corrects (dates, montants, codes)
- ✓ Cardinalités respectées (éléments uniques vs multiples)
Schémas sources : FNFE-MPE & FeRD
Nos schémas XSD proviennent directement du package officiel
[Factur-X](https://fnfe-mpe.org/factur-x/factur-x_en/)
publié conjointement par le FNFE-MPE (France) et le FeRD (Allemagne). La version réellement exécutée est exposée dans les artefacts de réponse API.

##### Schémas par profil :

MINIMUM BASIC WL BASIC EN 16931 EXTENDED

4

### Règles métier Schematron (EN16931)

Vérification des règles de cohérence métier définies par la norme
européenne EN16931 sur la facturation électronique.

#### Ce que nous vérifions :

- ✓ Cohérence des montants (lignes, TVA, totaux)
- ✓ Présence et format des identifiants selon les règles applicables ; sans preuve à eux seuls de leur existence dans un registre
- ✓ Codes conformes aux listes officielles (devises, pays, unités)
- ✓ Règles conditionnelles selon la catégorie TVA : un taux nul ne suffit pas à rendre un motif obligatoire
- ✓ Contraintes croisées entre champs
Règles BR selon le profil
Les artefacts Schematron traduisent les règles EN16931. Le dépôt
[ConnectingEurope](https://github.com/ConnectingEurope/eInvoicing-EN16931)
publie leurs versions. Pour une validation FacturX API, consultez les artefacts et versions du rapport : une version publiée n’est pas la preuve de la version exécutée.

##### Exemples de règles vérifiées :

`BR-01` Une facture doit avoir un identifiant de spécification
`BR-CO-10` La somme des montants nets de ligne (BT-131) doit égaler BT-106 ; le total HT BT-109 tient aussi compte des remises et charges de niveau document
`BR-S-08` Pour chaque taux de TVA S, la base taxable de la ventilation doit correspondre aux lignes et charges moins les remises portant ce même taux

### Lire le périmètre du résultat

Le conteneur Factur-X, les règles du profil, le [socle EN16931](https://facturxapi.com/en16931) et les contrôles France CTC
sont des résultats distincts. Les profils allégés ne couvrent pas toutes les données EN16931.
Une cible France demandée mais non exécutée reste non évaluée ; aucun de ces contrôles ne prouve une acceptation PA.

Exemple : [BR-Z-10](https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/BR-Z-10/)
interdit un motif d’exonération dans la ventilation TVA de catégorie Z, alors que
[BR-AE-10](https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/BR-AE-10/)
prévoit un motif codé ou textuel pour l’autoliquidation. Le taux zéro n’est donc pas une règle universelle de motif.

Sur l’accueil, la réponse affichée est une capture : ses tailles et empreintes sont celles de cette capture, pas celles d’un appel à la version courante de l’API.

### Pipeline de validation

1
Fichier reçu
PDF ou XML

→
2
PDF/A-3
Contrôle si PDF

→
3
Factur-X
XML embarqué

→
4
XSD CII
Structure XML

→
5
Schematron EN16931
Règles métier

→
6
Rapport correctif
Verdict et conseils

Le rapport distingue les contrôles exécutés, échoués et non évalués. Un échec PDF/A-3 ne prouve pas que les contrôles XML ont été ignorés : vérifiez leur résultat et, le cas échéant, la raison de non-exécution.

### Sécurité du traitement

#### 🔒 Protection XXE

Tous les parseurs XML sont sécurisés contre les attaques XXE (XML External Entity)
et XML bomb. Aucune entité externe n'est résolue.

#### 🗑️ Conservation des fichiers

Les fichiers transmis servent au traitement demandé. Selon le parcours, des copies temporaires peuvent être conservées pour le traitement, sa reprise ou l’accès au résultat ; les principales situations sont décrites dans la politique de confidentialité. [Voir la matrice de conservation](https://facturxapi.com/politique-confidentialite).

#### 🔒 Chiffrement et sous-traitants

Les échanges avec le service utilisent HTTPS.
Liste des sous-traitants et de leur localisation détaillée dans la
[politique de confidentialité](https://facturxapi.com/politique-confidentialite).

#### ⚡ Validation et réparation

La validation renvoie un diagnostic sans réparer le document.
La réparation XML et la génération d’un nouveau fichier sont des opérations distinctes, avec leurs propres résultats de contrôle.

### Sources et références

- [FNFE-MPE — Spécification Factur-X](https://fnfe-mpe.org/factur-x/factur-x_en/)
Package officiel contenant les schémas XSD, Schematron et exemples.

- [veraPDF — Validateur PDF/A](https://verapdf.org/)
Validateur open-source de référence pour PDF/A, soutenu par la PDF Association.

- [CEN TC 434 — Règles Schematron EN16931](https://github.com/ConnectingEurope/eInvoicing-EN16931)
Artefacts de validation officiels maintenus par Connecting Europe Facility.

- [Directive 2014/55/UE](https://eur-lex.europa.eu/eli/dir/2014/55/oj)
Directive européenne sur la facturation électronique dans les marchés publics.

- [ISO 19005-3:2012 (PDF/A-3)](https://www.iso.org/standard/57229.html)
Norme internationale pour l'archivage de documents électroniques avec fichiers embarqués.

### Prêt à valider vos factures ?

Plan Sandbox disponible : 100 factures traitées offertes les 14 premiers jours, puis 10 factures traitées/mois, sans carte bancaire.

[Tester une facture](https://facturxapi.com/scan) [Documentation API](https://facturxapi.com/docs)

---

# Tarifs

Source : https://facturxapi.com/pricing

Tarifs API

## Des tarifs lisibles par facture traitée.

Commencez avec Sandbox, activez Launch
pour un premier flux récurrent, puis passez sur Scale ou
Business quand le volume le demande.

Avant tout paiement, FacturX affiche le plan Launch ou Scale choisi et demande une acceptation explicite des [CGV du 8 novembre 2026](https://facturxapi.com/cgv).

#### Sandbox

0€pour tester
Clé gratuite pour tester le moteur sans carte bancaire.

- 100 factures traitées offertes les 14 premiers jours, puis 10 factures traitées/mois
- Validation, extraction, conversion et réparation selon les endpoints disponibles
- Clé API sandbox
- Validateur public gratuit, hors quota API

Sans carte bancaire. Le validateur public reste séparé. Les endpoints disponibles sont listés dans la [documentation](https://facturxapi.com/docs).

Premier flux

#### Launch

39€/mois
Pour brancher un premier flux récurrent avec un quota clair.

- 100 factures traitées par mois
- PDF + JSON vers Factur-X PDF/A-3
- Validation, extraction, conversion et réparation
- Souscription en ligne, quota Launch appliqué

Souscription en ligne : 100 factures traitées par mois, puis quota Launch appliqué au compte.

#### Scale

149€/mois
Pour absorber une montée en volume sans changer d’intégration API.

- 500 factures traitées par mois
- Même intégration API, marge de traitement plus large
- Historique et suivi adaptés aux flux récurrents
- Assistance par email par l'équipe technique

Souscription en ligne : 500 factures traitées par mois, puis quota Scale appliqué au compte.

#### Business

À partir de 499 €/mois
Pour volumes récurrents, bases installées et contraintes d’exploitation.

- 2 000 factures traitées par mois ; sur-volume et contrat sur devis
- Validation, extraction, conversion et réparation avec accompagnement ERP
- Historique, exports et multi-projets selon contrat

Retour de l’équipe par email après examen du contexte transmis.

Programmes accompagnés

#### Pour les pilotes réels et les contraintes sur mesure

Ces options servent quand le contexte doit être qualifié avant de choisir le bon cadre de production.

##### Pilote accompagné

Sur devis
Pour réussir un pilote réel avec critères de succès et accompagnement.

- Sur candidature, avec périmètre et durée définis
- Cadrage du pilote et des critères de succès
- Priorisation des cas réels à traiter
- Plan de bascule vers Business

TVA non applicable, art. 293 B du CGI.

### Quel parcours choisir ?

Tester

Sandbox sert à vérifier rapidement les réponses API et les premiers cas de validation sans engagement.

Intégrer

Launch permet de brancher un premier flux récurrent avec un quota clair.

Accélérer

Scale augmente le quota sans imposer de nouvelle intégration API.

Industrialiser

Business et Pilote accompagné prennent le relais pour les volumes, les pilotes réels et les contraintes contractuelles.

### 1 livrable final = 1 facture traitée

Un appel abouti à /validate, /extract ou /repair décompte une facture traitée. Une génération /convert réserve une facture, décomptée si un livrable final est produit ; sans livrable, elle est remboursée, sauf remboursement non confirmé (503 quota_refund_unconfirmed). Une simulation /convert avec dry_run=true ne consomme pas le quota et ne produit pas de livrable final. Le validateur public reste gratuit et séparé de votre quota mensuel.

#### Comprendre le quota mensuel

Fonction API | Factures traitées | Quand l'utiliser |
`POST /api/v1/validate` | 1 facture traitée | Diagnostiquer une facture Factur-X déjà produite |
`POST /api/v1/extract` | 1 facture traitée | Extraire le XML CII embarqué dans un PDF Factur-X |
`POST /api/v1/repair` | 1 facture traitée | Réparer un XML CII invalide avant transmission |
`POST /api/v1/convert` | 1 par génération finale, décomptée une seule fois · 0 en simulation dry_run | Générer un Factur-X PDF/A-3 avec XML embarqué et contrôles de sortie |

Le validateur public reste gratuit et séparé du quota API.

#### Pourquoi ces tarifs sont plus lisibles

Le quota suit le nombre de factures traitées : vous pouvez relier directement l’usage de l’API au plan choisi. Les limites techniques du service restent séparées de ce quota commercial.

#### Le vrai rôle du plan Sandbox

Sandbox sert à tester le moteur sur vos premiers documents et à vérifier le format des réponses. Dès que vous validez un flux récurrent, Launch prend le relais.

### Questions fréquentes

Le contrôle FacturX vaut-il acceptation par ma plateforme agréée ?
Le contrôle applique les règles EN 16931 et, lorsque le contexte du document permet de les évaluer, les artefacts de contrôle FNFE-MPE des règles françaises. L'acceptation finale appartient à votre plateforme agréée. Le scan ne soumet rien à une Plateforme Agréée et ne crée aucun statut d'acceptation PA : il produit un diagnostic avant intégration ou avant envoi dans le flux choisi par l'utilisateur.

Le validateur public consomme-t-il mon quota mensuel ?

Non. Le validateur public reste gratuit et ne consomme pas votre quota mensuel.

Quand rester sur Launch ?

Restez sur Launch si vous êtes sur un premier flux standard, avec une équipe technique autonome et sans besoin de cadrage sur mesure.

Quand passer sur Scale ?

Passez sur Scale quand votre flux récurrent dépasse le cadre de démarrage et que vous voulez plus de marge mensuelle sans changer d’intégration API.

Quand basculer sur Pilote accompagné ?

Quand vous devez éprouver un cas réel dans un périmètre défini et cadrer les critères de réussite avant un déploiement plus large.

Business inclut-il une grille standard ?

Business démarre à 499 €/mois pour 2 000 factures traitées par mois ; le sur-volume et le contrat se chiffrent sur devis, et l’accompagnement se cadre avant activation.

Comment vous écrire pour un programme accompagné ?

Cliquez sur « Décrire mon contexte » ou « Décrire mon pilote » ci-dessus, ou écrivez à contact@facturxapi.com. L’équipe vous répond par email après examen du contexte transmis.

### Démarrez par une clé gratuite

Testez le moteur sur vos premiers fichiers, puis passez sur Launch ou Scale en ligne quand votre flux est prêt. Business reste accompagné.
[Créer ma clé API gratuite](https://facturxapi.com/api-key)
