Serveur de validation MCP
Factur-X, ZUGFeRD & XRechnung
Serveur MCP pour la validation automatisée de factures électroniques au format Factur-X, ainsi que des formats allemands ZUGFeRD et XRechnung. Renvoie des résultats JSON structurés avec des suggestions de correction concrètes.
1. Aperçu
Le serveur fournit trois outils et une ressource que les agents IA peuvent appeler via le Model Context Protocol.
| Scénario | Outil / Ressource |
|---|---|
| Vérifier une facture avant l'envoi | validate_invoice |
| Lire les données XML d'un PDF ZUGFeRD | extract_xml |
| Vérifier que le PDF et le XML concordent | check_consistency |
| Interroger les formats et jeux de règles disponibles | validation://rules |
2. Architecture & flux de données
Déroulement pour validate_invoice
3. Moteurs de validation
Chaque requête est vérifiée par deux moteurs en même temps. Les résultats sont consolidés, dédupliqués, puis renvoyés.
| Moteur | Version | Formats couverts |
|---|---|---|
| Mustang Project | v2.26.0 | ZUGFeRD 1.0–2.4, Factur-X 1.0, XRechnung (général) |
| Outil de validation KoSIT | v1.6.3 | XRechnung 3.0.2 (CII + UBL), EN 16931 CII/UBL (brut), Factur-X 1.07.3 / 1.08 (tous les profils) |
errors. Les doublons (même ID de règle + message) sont supprimés automatiquement. Les erreurs KoSIT ne sont retenues que si un scénario de validation adapté a été détecté — pour des GuidelineIDs inconnus, Mustang seul prend le relais.
4. Installation & configuration
# Kostenlos registrieren:
https://zugferd-validator.de/portal
npm install -g zugferd-mcp-client
// mcp_config.json (je nach Client abweichender Pfad) { "mcpServers": { "zugferd": { "command": "zugferd-mcp-client", "env": { "ZUGFERD_API_KEY": "zv_dein_key_hier" } } } }
API REST directe
L'API peut aussi être appelée directement, sans client MCP :
# Beispiel: Validierung per curl curl -X POST https://api.zugferd-validator.de/v1/validate \ -H "Content-Type: application/json" \ -H "X-Api-Key: zv_dein_key_hier" \ -d '{"file_content":"<base64>","file_type":"xml"}'
Variables d'environnement (client MCP)
| Variable | Description | Défaut |
|---|---|---|
ZUGFERD_API_KEY | Clé API du portail | – (obligatoire) |
ZUGFERD_API_URL | URL de base de l'API | https://api.zugferd-validator.de |
5. Outils
Valide une facture électronique (PDF ZUGFeRD/Factur-X ou XML XRechnung) selon la norme EN 16931 et les extensions allemandes. Renvoie des erreurs, avertissements et suggestions de correction structurés.
Schéma d'entrée
data:application/pdf;base64,…) sont retirés automatiquement.
"pdf" pour les PDF ZUGFeRD/Factur-X · "xml" pour les fichiers XML XRechnung/CII purs
rule_id: "PROFILE_MISMATCH" est généré.Valeurs :
minimum · basic_wl · basic · en16931 · extended · xrechnung
Schéma de sortie
{
"valid": true,
"format": "ZUGFeRD 2.x",
"profile": "EN16931",
"container": "pdf",
"syntax": "CII",
"summary": "Keine Probleme gefunden",
"errors": [],
"warnings": [],
"notices": [],
"metadata": {
"invoice_number": "RE-2026-001",
"issue_date": "2026-04-01",
"seller": "Musterfirma GmbH",
"buyer": "Beispiel AG",
"total_amount": "1190.00",
"currency": "EUR"
}
}
{
"valid": false,
"format": "XRechnung 3.0",
"profile": "XRECHNUNG",
"summary": "1 Fehler, 1 Warnung gefunden",
"errors": [
{
"severity": "error",
"rule_id": "BR-DE-15",
"field": "BT-10",
"message": "Die Käuferreferenz / Leitweg-ID (BT-10) muss übermittelt werden.",
"fix_suggestion": "Füge die Käuferreferenz / Leitweg-ID (BT-10) in 'ram:ApplicableHeaderTradeAgreement/ram:BuyerReference' ein.",
"xpath": "//ram:ApplicableHeaderTradeAgreement/ram:BuyerReference"
}
],
"warnings": [
{
"severity": "warning",
"rule_id": "BR-DE-17",
"field": "BT-3",
"message": "Mit dem Element \"Invoice type code\" (BT-3) sollen ausschließlich folgende Codes aus der Codeliste UNTDID 1001 übermittelt werden: 326, 380, 384, 389 …",
"fix_suggestion": "Bei einer Vorschussrechnung (386) ist die Warnung hinnehmbar: XRechnung empfiehlt den Code nicht, lässt ihn aber zu. Wer sie vermeiden will, nimmt 326 (Teilrechnung).",
"xpath": "//rsm:ExchangedDocument/ram:TypeCode"
}
]
}
Champs de sortie
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
valid | boolean | Oui | true si aucune erreur n'a été trouvée |
format | string | Non | Format détecté : "ZUGFeRD 2.x" ou "ZUGFeRD 1.0" pour un PDF, sinon p. ex. "XRechnung 3.0", "Peppol BIS Billing 3.0" ou "EN 16931" ; null si aucun XML n'est extractible |
profile | string | Non | Profil détecté en majuscules, p. ex. "EN16931", "EXTENDED" ou "XRECHNUNG" ; null si aucun XML n'est extractible |
container | string | Non | pdf (PDF avec facture électronique intégrée) ou xml (fichier XML) |
syntax | string | Non | CII ou UBL |
summary | string | Oui | Résumé lisible, p. ex. "2 Fehler, 1 Warnung gefunden" |
errors | array | Oui | Erreurs de validation — rendent la facture non valide |
warnings | array | Oui | Avertissements — la facture peut néanmoins être valide |
notices | array | Non | Remarques informatives sans effet sur la validité |
metadata | object | Non | Données de facture extraites — présentes pour les PDF si le XML intégré a pu être lu, et toujours pour file_type: "xml" |
Extrait le document XML intégré d'un PDF ZUGFeRD/Factur-X. Renvoie le contenu XML complet sous forme de chaîne, avec le format et le profil détectés.
Entrée
Sortie
{
"xml_content": "<?xml version='1.0' encoding='UTF-8'?>\n<rsm:CrossIndustryInvoice ...>...</rsm:CrossIndustryInvoice>",
"format": "ZUGFeRD 2.x",
"profile": "EN16931"
}
xml_content extrait peut être transmis directement (après encodage Base64) à validate_invoice avec file_type: "xml".Vérifie que les données visibles par l'humain dans le PDF (numéro de facture, date, montant total) correspondent aux données machine stockées dans la pièce jointe XML. Révèle les manipulations ou erreurs de saisie.
Entrée
Sortie
{
"consistent": true,
"discrepancies": []
}
{
"consistent": false,
"discrepancies": [
{
"field": "total_amount",
"pdf_value": "1190.00",
"xml_value": "1180.00",
"message": "Gesamtbetrag im PDF ('1190.00') unterscheidet sich von dem im XML ('1180.00')."
}
]
}
Champs vérifiés & tolérances
| Champ | Motif de détection dans le PDF | Tolérance |
|---|---|---|
invoice_number | Rechnungsnummer:, Rechnung Nr., Invoice No. | Casse, espaces et tirets ignorés |
issue_date | Rechnungsdatum:, Datum:, Invoice Date: | Aucune — les formats de date sont normalisés en ISO 8601 |
total_amount | Gesamtbetrag:, Rechnungsbetrag:, Total: | ±0,01 EUR (différences d'arrondi) |
Crée une facture électronique valide à partir de données structurées, au choix comme PDF ZUGFeRD (PDF/A-3 avec XML CII EN 16931 intégré) ou comme XML XRechnung pur (CII avec CIUS XRechnung 3.0 et Leitweg-ID pour le B2G). Plusieurs lignes, catégories de TVA S, Z, E, AE, K et G, débours sans TVA, remises et majorations, date ou période de prestation, montants déjà payés, références à des factures antérieures, pièces jointes, virement ou prélèvement SEPA. Sans état : rien n'est conservé, pièces jointes comprises. REST : POST /v1/create. Montants en centimes, date au format YYYY-MM-DD.
Entrée (extrait)
zugferd (PDF) ou xrechnung (XML)invoice : credit_note (avoir/annulation ; montants positifs, le PDF n'affiche alors pas de montant à payer), corrected (facture rectificative), self_billed (autofacturation), prepayment (facture d'acompte ; XRechnung émet pour 386 l'avertissement BR-DE-17, la facture reste valide), partial (facture partielle), debit_note (note de débit). En brut via type_code.[{ number, date }], 20 au plus. Dans les deux formats, le XML ne contient que la première en BG-3, car le schéma de l'EN 16931 n'en admet qu'une ; la note (BT-22) cite toutes les autres.{ number, date } (BT-25/26), par exemple pour un avoir. Pas en même temps que preceding_invoices.seller manque, nous reprenons le profil d'émetteur de votre compte.vat_category : défaut S ; Z = 0 %, E = exonéré, AE = autoliquidation, K = livraison intracommunautaire, G = exportation.vat_rate: 0, vat_category omis ou E. Dans le XML, catégorie E avec motif et code VATEX-EU-79-C. Pas en même temps que d'autres lignes de catégorie E (BR-E-01). Dans le XML, le débours compte dans le total HT (BT-109), mais pas dans la TVA, comme l'exige l'EN 16931. Si votre propre facture affiche le total HT sans lui, les deux montants diffèrent ; le total TTC concorde.{ start, end }, la fin pas avant le début. Avec une période et sans date de prestation, nous fixons BT-72 à la fin de la période. Pour une facture d'acompte (prepayment) sans l'une ni l'autre, nous omettons BT-72 ; la vérification ZUGFeRD émet alors un avertissement (PEPPOL-EN16931-R008), c'est normal. Sinon, la date de facture s'applique.prepaid_vat_cents, elle indique aussi le montant HT et la TVA de la déduction, comme l'exige le droit allemand (§ 14, al. 5 UStG) pour les factures finales.xrechnungmandate_reference (BT-89), creditor_id (BT-90, sinon repris du profil d'émetteur), debtor_iban (BT-91). Fixe le moyen de paiement 59. Pour ZUGFeRD, l'IBAN peut être masqué (DE89**************3000), pour XRechnung non. Nous n'écrivons alors pas de compte bénéficiaire (BR-DE-25-b). Si vous envoyez direct_debit, les trois sont nécessaires ; omettez alors payment_means.type_code ou mettez 59.[{ filename, content_base64, description? }]. Sont admis PDF, PNG, JPEG, CSV, XLSX et ODS (BR-CL-24), 10 fichiers au plus, 5 Mo au plus au total. Les noms de fichier doivent être uniques. À partir de deux pièces jointes, la vérification émet l'avertissement CII-SR-476 (avec deux descriptions aussi CII-SR-475) ; la règle compte toutes les pièces jointes ensemble, la facture reste valide. Via MCP, la réponse d'une facture ZUGFeRD avec pièces jointes ne contient que pdf_base64 ; le XML est dans le PDF.false.Sortie
{
"format": "zugferd",
"profile": "EN16931",
"pdf_base64": "JVBERi0xLjc…",
"xml": "<?xml version=\"1.0\"…",
"branding": "free_footer"
}
xml est toujours joint, sauf via MCP pour une facture ZUGFeRD avec pièces jointes. extract_xml le tire alors du PDF.
Pièces jointes
Les pièces jointes figurent seulement dans le XML de la facture électronique (BT-125), pas en plus comme pièce jointe du PDF. Chaque fichier fait 5 Mo au plus, et tous ensemble 5 Mo au plus aussi, mesurés après décodage. Nous lisons le type à l'extension (.pdf, .png, .jpg, .jpeg, .csv, .xlsx, .ods) et le vérifions sur les premiers octets du fichier ; s'ils ne concordent pas, vous recevez 400. Un nom de fichier a jusqu'à 100 caractères, sans / ni \ et sans point au début ; deux noms qui ne diffèrent que par les majuscules et minuscules comptent comme identiques. description (BT-123) a 200 caractères au plus. content_base64 contient du Base64 pur ; nous retirons un préfixe data:…;base64,. Le Base64 grossit les fichiers d'un tiers : 5 Mo de pièces jointes donnent environ 7 Mo dans la requête, et la réponse les contient encore une fois dans la facture. Via MCP, envoyez donc de préférence de petites pièces jointes.
Profil d'émetteur
Ce qui manque dans la requête, nous le complétons à partir du profil d'émetteur de votre compte : tout le vendeur si seller manque (son numéro fiscal seulement si le profil n'a pas de numéro de TVA), ainsi que l'IBAN, le BIC, le titulaire du compte, les conditions de paiement, le logo et, pour un prélèvement, l'identifiant créancier. Ce que contient la requête l'emporte toujours. Vous gérez le profil dans votre compte ou via l'API : GET /v1/keys/issuer le lit, PUT /v1/keys/issuer l'enregistre, DELETE /v1/keys/issuer le supprime. Champs : name, street, zip, city, country, vat_id, tax_number, email, phone, contact_name, iban, bic, account_name, payment_terms, logo_b64, creditor_id. PUT ne modifie que les champs présents dans la requête ; une chaîne vide ou null efface un champ. PUT refuse avec 400 un numéro de TVA sans code pays, un numéro fiscal de forme incorrecte et un identifiant créancier invalide.
Erreurs
Nous répondons à une entrée invalide par 400 et { "error": "Ungültige Eingabe", "details": "…" }. Les erreurs de schéma indiquent le chemin et la raison, plusieurs séparées par des points-virgules. Les problèmes de contenu, comme un prélèvement sans référence de mandat, figurent en phrases entières dans details (en allemand), plusieurs séparées par des espaces. Une date qui n'a pas la forme YYYY-MM-DD nomme son champ, par exemple preceding_invoices[0].date (compté à partir de 0). Via MCP, les problèmes de contenu et les dates reviennent sous la forme du même objet. Les erreurs de schéma sont interceptées plus tôt par le protocole MCP lui-même : vous recevez une erreur d'outil (isError: true) avec le texte de la vérification du schéma, pas un objet avec error et details.
validate_invoice sur le pdf_base64 ou le xml renvoyé, ou en réglant self_check: true pour un aller-retour unique. Le serveur détermine le branding selon le forfait (pied de page sur le forfait Gratuit, white-label à partir d'Automatiser). Quota propre pour la création : Gratuit 1 facture par mois ; Automatiser et Scaler illimités, usage raisonnable via la limite horaire.zv_test_…, via GET /v1/keys/me) : pour intégrer librement sans entamer le quota réel. Les factures créées portent un filigrane « DEMO » en mosaïque sur chaque page plus un marqueur XML — entièrement testables, mais sans valeur comme véritable facture. 100/jour, 3/minute ; comptées séparément du quota réel.Afficher une facture sous forme lisible. Transforme une XRechnung (UBL ou CII), une facture CII ou un PDF Factur-X/ZUGFeRD en affichage lisible. Il repose sur la visualisation de la KoSIT (Apache 2.0), dans la version fournie avec Mustang 2.26.0. Aucune clé nécessaire ; l'affichage ne compte pas dans le quota de contrôles mais a sa propre limite journalière : 20 par adresse IP sans compte, 50 avec l'offre gratuite, 500 avec Automatiser, 2 000 avec Scaler (sinon 429). Rien n'est enregistré ni journalisé. Comme outil MCP : view_invoice.
Champs
413)"pdf" ou "xml"de, en ou fr, par défaut detrue (false via MCP)Réponse : readable, html, format, profile, syntax, attachments (nom, type, taille, Base64), check (valide, nombre d'erreurs et d'avertissements, premiers messages) et limit. Le HTML est nettoyé : pas de script, pas de gestionnaires d'événements, pas de liens avec cible, pas d'images ni de formulaires, plus une Content Security Policy. Affichez-le tout de même uniquement dans un <iframe sandbox> sans droits, et enregistrez les pièces jointes comme fichiers au lieu de les ouvrir dans le navigateur. Si le fichier ne peut pas être affiché, readable vaut false et check en donne la raison ; un PDF sans facture électronique donne 422.
Vérifier un Leitweg-ID. Vérifie la structure, le code (Land 01 à 16, État fédéral 99) et les chiffres de contrôle (modulo 97-10) selon la spécification de format 2.0.2 de la KoSIT. Si les chiffres de contrôle sont faux ou manquent, la réponse donne l'identifiant correspondant dans corrected_id. Elle ne dit pas si l'identifiant est attribué ; il n'existe pas d'annuaire public. Sans clé, sans quota, 120 appels par minute au plus (sinon 429). Rien n'est enregistré. Outil MCP : check_leitweg_id.
Champs
de, en ou fr, par défaut deRéponse (200, aussi pour un identifiant invalide) : valid, leitweg_id (forme normalisée), parts (coarse, fine, check_digits), region, expected_check_digits, corrected_id, errors et warnings (chacun code et message), notice. Faites confirmer un identifiant proposé par le donneur d'ordre avant de l'utiliser.
Contrôle par lot sur le serveur. Pour de nombreuses factures à la fois, sans que votre programme ou navigateur reste connecté tout le temps : téléverser les fichiers, lancer, récupérer les résultats plus tard. À partir de l'offre Automatiser. Les factures restent chiffrées sur notre serveur en Allemagne jusqu'au contrôle et sont supprimées juste après. Les résultats restent sept jours, puis nous les supprimons. Quand tout est terminé, un e-mail part à l'adresse du compte. Dans un compte d'entreprise, le titulaire peut désactiver cette option pour les autres accès (PATCH /v1/org/settings avec { "stapel_ablage": false }).
Appels
{ sprache?: "de" | "en" | "fr" } (langue de l'e-mail). Réponse 201 avec { id, max_dateien, max_bytes }. Au maximum 3 lots ouverts par clé.{ name, file_type: "pdf" | "xml", file_content } (Base64, 15 Mo au maximum). Au maximum 500 fichiers par lot.status (hochladen = téléversement, wartend = en attente, fertig = terminé, angehalten = arrêté), anzahl, fertig, ok, mit_fehlern, neu, grund, ablauf. ergebnisse contient les résultats comme pour validate_invoice, avec nr et reference (nom du fichier). Avec seit=0, vous recevez tout et la liste namen ; ensuite passez le dernier stand comme seit pour ne recevoir que les nouveaux (le dernier peut revenir deux fois).Chaque fichier compte dans le quota hebdomadaire. S'il est épuisé, le lot s'arrête (status: "angehalten", grund: "kontingent") ; les fichiers restants ne sont pas contrôlés et sont supprimés. Le serveur traite ces lots uniquement sur les places libres à ce moment ; les contrôles directs passent en premier.
Renvoie le résultat du contrôle sous forme de rapport de validation au format PDF/A-3b, prêt à archiver et à transmettre. Le rapport indique le résultat, chaque message avec son identifiant de règle et son champ, la date du contrôle, le format et le profil reconnus, l’empreinte SHA-256 du fichier contrôlé et le jeu de règles, c’est-à-dire les versions des outils utilisés. Chaque appel effectue un nouveau contrôle et compte dans le quota hebdomadaire comme une validation. Disponible comme outil MCP validation_report et via REST avec POST /v1/report.
Entrée
pdf ou xmlAFRelationship /Source) pour rester lisible par machine. Par défaut false.de, en, fr — par défaut derechnung.pdf ou rechnung.xml.Sortie
Content-Type: application/pdf Content-Disposition: attachment; filename="rapport-validation-facture.pdf" X-Validation-Result: valid | invalid
Exemple
curl -X POST https://api.zugferd-validator.de/v1/report \
-H "X-Api-Key: $ZV_KEY" \
-H "Content-Type: application/json" \
-d "{\"file_content\": \"$(base64 -w0 rechnung.pdf)\", \"file_type\": \"pdf\", \"attach_source\": true}" \
-o bericht.pdf
403 ; un exemple de rapport filigrané est accessible sans clé via GET /v1/report/sample?lang=de|en|fr.6. Ressource : validation_rules
Renvoie l'ensemble de règles actuel du serveur : formats et profils pris en charge, ainsi que le moteur de validation utilisé.
URI : validation://rules
{
"supported_formats": [
"ZUGFeRD 1.0", "ZUGFeRD 2.0", "ZUGFeRD 2.1", "ZUGFeRD 2.2",
"ZUGFeRD 2.3", "ZUGFeRD 2.x / Factur-X 1.0x",
"XRechnung 1.2", "XRechnung 2.0", "XRechnung 2.3", "XRechnung 3.0"
],
"supported_profiles": [
"minimum", "basic_wl", "basic", "en16931", "extended", "xrechnung"
],
"validation_engines": [
"Mustang Project v2.26.0",
"KoSIT Validierungstool v1.6.3 (XRechnung 3.0.2 + EN 16931 CII)"
],
"last_updated": "2026-04-08"
}
7. Gestion des erreurs
En cas d'erreur, tous les outils renvoient un objet JSON avec un champ error. Via MCP, il y a une exception : si l'entrée ne correspond pas au schéma de l'outil (mauvais type, champ obligatoire manquant, valeur hors liste), le protocole MCP le signale lui-même par une erreur d'outil (isError: true) avec le texte de la vérification du schéma, et non par un objet JSON.
{
"error": "Kurze Fehlerkategorie",
"details": "Ausführliche Beschreibung mit konkretem Hinweis zur Behebung."
}
| error | Déclencheur |
|---|---|
"Fehlender Parameter" | Champ obligatoire non transmis |
"Ungültiger Parameter" | Valeur incorrecte pour file_type |
"Ungültiger Base64-Input" | Chaîne Base64 non valide transmise |
"Validierungsfehler" | Mustang CLI n'a pas pu démarrer (p. ex. Java absent) ou timeout après 30 s |
"XML-Extraktion fehlgeschlagen" | Aucun fichier XML trouvé dans la pièce jointe du PDF (pour extract / consistency). Pour validate, un notice avec rule_id: "NO_EMBEDDED_XML" est renvoyé à la place et valid: true est défini |
"PDF-Lesefehler" | Le PDF ne peut pas être lu |
"XML-Parsing-Fehler" | Le XML extrait n'est pas un XML valide |
"Interner Fehler" | Erreur d'exécution inattendue |
"error": "Validierungsfehler" est renvoyé. Un timeout de KoSIT est ignoré en silence — les résultats de Mustang sont conservés.8. Types de données communs
ValidationIssue
Utilisé dans les tableaux errors, warnings et notices de validate_invoice.
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
severity | "error" | "warning" | "notice" | Oui | Niveau de gravité du constat |
rule_id | string | Oui | ID de règle, p. ex. "BR-DE-1", "BR-CL-10". Valeur "UNKNOWN" pour les violations de schéma XSD (KoSIT) ou lorsqu'aucune ID de règle n'a pu être déterminée |
field | string | Non | Champ BT concerné, p. ex. "BT-10" |
message | string | Oui | Message d'erreur (en allemand) |
fix_suggestion | string | Non | Conseil de correction concret avec exemple XML |
xpath | string | Non | XPath vers l'élément XML concerné |
scope | "xrechnung" | "peppol" | Non | Uniquement sur les remarques d'une facture reconnue qui n'est pas une XRechnung (BT-24 sans l'identifiant xrechnung), par exemple ZUGFeRD ou Factur-X. "xrechnung" pour les règles BR-DE-… : elles ne s'appliquent que si votre destinataire exige une XRechnung, par exemple une administration allemande. "peppol" pour les règles PEPPOL-… : elles ne s'appliquent qu'à l'envoi par le réseau Peppol. Absent sur les erreurs, les avertissements et les autres remarques. |
InvoiceMetadata
Champ optionnel dans le résultat de validate_invoice (uniquement pour file_type: "xml").
| Champ | Type | Description |
|---|---|---|
invoice_number | string? | Numéro de facture (BT-1) |
issue_date | string? | Date de facture ISO 8601, p. ex. "2026-04-01" |
seller | string? | Nom du vendeur (BT-27) |
buyer | string? | Nom de l'acheteur (BT-44) |
total_amount | string? | Montant total sous forme de chaîne décimale, p. ex. "1190.00" |
currency | string? | Code devise ISO 4217, p. ex. "EUR" |
9. Formats & profils pris en charge
Formats
| Format | Standard | Remarque |
|---|---|---|
| ZUGFeRD 1.0 | ZUGFeRD 1.0 / GEFEG | Version plus ancienne, prise en charge des profils limitée |
| ZUGFeRD 2.0 | FeRD 2.0 | Première version basée sur CII |
| ZUGFeRD 2.1 | Factur-X 1.0 (FR) | Techniquement identique à Factur-X 1.0 |
| ZUGFeRD 2.2 | Factur-X 1.0.05 | Corrections mineures |
| ZUGFeRD 2.3 | Factur-X 1.0.06 | Version antérieure à 2.4 |
| ZUGFeRD 2.x / Factur-X 1.0x | EN 16931 + D16B | Version principale actuelle (2026) — l'API renvoie "ZUGFeRD 2.x" |
| XRechnung 1.2 | XRechnung 1.2 | Version XRechnung plus ancienne |
| XRechnung 2.x | XRechnung 2.0–2.3 | Différentes versions intermédiaires |
| XRechnung 3.0 | XRechnung 3.0 | Version XRechnung actuelle |
Profils (ZUGFeRD/Factur-X)
| ID de profil | Nom affiché | Usage typique |
|---|---|---|
minimum | MINIMUM | Traitement machine simple |
basic_wl | BASIC-WL | Sans détail des lignes |
basic | BASIC | Factures standard |
en16931 | EN 16931 (COMFORT) | Donneurs d'ordre publics, PEPPOL |
extended | EXTENDED | Processus B2B complexes |
xrechnung | XRECHNUNG | Administration publique allemande |
10. Règles & suggestions de correction
Le serveur contient une base de suggestions de correction pour 160 catégories de règles. Les erreurs des deux moteurs de validation (Mustang + KoSIT) sont consolidées — lorsqu'une ID de règle connue est trouvée, la suggestion de correction est ajoutée automatiquement.
rule_id donne la règle en majuscules et sans zéro initial : BR-6 au lieu de BR-06, BR-DE-25-B au lieu de BR-DE-25-b. Quand XRechnung scinde une règle en deux, l'identifiant complet est indiqué. Les identifiants de champ comme BT-89 ne sont jamais une ID de règle.
Règles BR-DE 32 règles
Extensions allemandes, obligatoires pour les factures conformes à XRechnung. État XRechnung 3.0.2 ; les avertissements et notes ne rendent pas la facture invalide.
| ID de règle | Champ | Description courte |
|---|---|---|
BR-DE-1 | BG-16 | PAYMENT INSTRUCTIONS (BG-16) manquantes |
BR-DE-2 | BG-6 | Contact vendeur (BG-6) |
BR-DE-3 | BT-37 | Ville du vendeur (BT-37) |
BR-DE-4 | BT-38 | Code postal du vendeur (BT-38) |
BR-DE-5 | BT-41 | Interlocuteur du vendeur (BT-41) |
BR-DE-6 | BT-42 | Numéro de téléphone du vendeur (BT-42) |
BR-DE-7 | BT-43 | E-mail du vendeur (BT-43) |
BR-DE-8 | BT-52 | Ville de l'acheteur (BT-52) |
BR-DE-9 | BT-53 | Code postal de l'acheteur (BT-53) |
BR-DE-10 | BT-77 | Ville de livraison (BT-77) |
BR-DE-11 | BT-78 | Code postal de livraison (BT-78) |
BR-DE-12 | – | supprimée dans la version XRechnung actuelle |
BR-DE-13 | – | supprimée dans la version XRechnung actuelle |
BR-DE-14 | BT-119 | Taux de TVA (BT-119) |
BR-DE-15 | BT-10 | Référence acheteur / Leitweg-ID (BT-10) |
BR-DE-16 | BT-31 | Numéro de TVA / numéro fiscal du vendeur |
BR-DE-17 | BT-3 | Type de facture que XRechnung ne recommande pas, par exemple 386 (avertissement) |
BR-DE-18 | BT-20 | Informations d'escompte (BT-20) au mauvais format |
BR-DE-19 | BT-84 | IBAN du bénéficiaire invalide pour un virement (58) (avertissement) |
BR-DE-20 | BT-91 | IBAN du payeur invalide pour un prélèvement (59) (avertissement) |
BR-DE-21 | BT-24 | Specification identifier (BT-24) non conforme à XRechnung (avertissement) |
BR-DE-22 | BT-125 | Noms de fichiers joints non uniques |
BR-DE-23-A | BG-17 | Virement (30, 58) sans coordonnées du compte |
BR-DE-23-B | BT-81 | Virement (30, 58) avec carte ou prélèvement |
BR-DE-24-A | BG-18 | Paiement par carte (48, 54, 55) sans données de carte |
BR-DE-24-B | BT-81 | Paiement par carte avec compte ou prélèvement |
BR-DE-25-A | BG-19 | Prélèvement (59) sans données de prélèvement |
BR-DE-25-B | BT-81 | Prélèvement (59) avec compte bénéficiaire ou carte |
BR-DE-26 | BT-3 | Facture rectificative (384) sans référence à la facture antérieure (avertissement) |
BR-DE-27 | BT-42 | Téléphone avec moins de trois chiffres (avertissement) |
BR-DE-28 | BT-43 | Adresse e-mail de forme incorrecte (avertissement) |
BR-DE-30 | BT-90 | Prélèvement sans identifiant créancier |
BR-DE-31 | BT-91 | Prélèvement sans IBAN du payeur |
BR-DE-TMP-32 | BT-72 | Aucune date de livraison ou de prestation (note) |
Règles fondamentales EN 16931 (BR-*) 10 règles
| ID de règle | Champ | Description courte |
|---|---|---|
BR-1 | BT-24 | Specification identifier (BT-24) |
BR-2 | BT-1 | Numéro de facture (BT-1) |
BR-3 | BT-2 | Date de facture (BT-2) |
BR-4 | BT-3 | Code de type de facture (BT-3) |
BR-5 | BT-5 | Code devise (BT-5) |
BR-6 | BT-27 | Nom du vendeur (BT-27) |
BR-7 | BT-44 | Nom de l'acheteur (BT-44) |
BR-8 | BG-5 | Adresse postale du vendeur (BG-5) |
BR-9 | BG-5 | Code pays du vendeur (BT-40) |
BR-10 | BG-8 | Adresse postale de l'acheteur (BG-8) |
Règles de calcul (BR-CO-*) & règles de listes de codes (BR-CL-*) 8 règles
| ID de règle | Description courte |
|---|---|
BR-CO-3 | La date de taxe et le code de date de taxe s'excluent mutuellement |
BR-CO-9 | Numéro de TVA du vendeur sans préfixe pays |
BR-CO-10 | La somme des montants nets des lignes est incorrecte |
BR-CO-13 | Montant total hors TVA mal calculé |
BR-CL-10 | schemeID non valide (pas issue d'ISO 6523) |
BR-CL-16 | Code de moyen de paiement non valide (pas issu d'UNTDID 4461) |
BR-CL-17 | Catégorie de TVA non valide dans une remise ou majoration au niveau du document (en UBL aussi dans la ventilation de TVA) |
BR-CL-18 | Catégorie de TVA non valide au niveau de la ligne (en CII aussi dans la ventilation de TVA) |
Règles de catégorie de taxe (BR-S/Z/E/AE-*) 4 règles
| ID de règle | Description courte |
|---|---|
BR-S-1 | Taux normal (S) sans ventilation de TVA de catégorie S |
BR-Z-1 | Taux zéro (Z) : exactement une ventilation de TVA de catégorie Z |
BR-E-1 | Exonéré (E) : exactement une ventilation de TVA de catégorie E, donc un seul motif de 0 % par facture |
BR-AE-1 | Autoliquidation (AE) : exactement une ventilation de TVA de catégorie AE |
11. Exemples d'utilisation
Exemple 1 : valider un XML XRechnung
{
"tool": "validate_invoice",
"arguments": {
"file_content": "PD94bWwgdmVyc2lvbj0iMS4wIj8+...",
"file_type": "xml",
"profile": "xrechnung"
}
}
{
"valid": true,
"format": "XRechnung 3.0",
"profile": "XRECHNUNG",
"summary": "Keine Probleme gefunden",
"errors": [],
"warnings": [],
"metadata": {
"invoice_number": "INV-2026-0042",
"issue_date": "2026-04-07",
"seller": "Tech GmbH",
"buyer": "Bundesbehörde X",
"total_amount": "5950.00",
"currency": "EUR"
}
}
Exemple 2 : facture erronée avec suggestion de correction
{
"tool": "validate_invoice",
"arguments": {
"file_content": "JVBERi0xLjQK...",
"file_type": "pdf"
}
}
{
"valid": false,
"format": "ZUGFeRD 2.x",
"profile": "EN16931",
"summary": "1 Fehler gefunden",
"errors": [{
"severity": "error",
"rule_id": "BR-DE-15",
"field": "BT-10",
"message": "Käuferreferenz (BT-10) muss für XRechnung angegeben werden.",
"fix_suggestion": "Füge 'ram:BuyerReference' hinzu, z.B. '04011000-1234-34' für Behörden.",
"xpath": "//ram:ApplicableHeaderTradeAgreement/ram:BuyerReference"
}],
"warnings": []
}
Exemple 3 : extraire et valider le XML
// Schritt 1 — XML aus PDF extrahieren { "tool": "extract_xml", "arguments": { "pdf_content": "JVBERi0x..." } } // Schritt 2 — Extrahiertes XML validieren (base64-kodiert übergeben) { "tool": "validate_invoice", "arguments": { "file_content": "<base64 des xml_content>", "file_type": "xml" } }
Exemple 4 : contrôle de cohérence
{
"tool": "check_consistency",
"arguments": { "pdf_content": "JVBERi0xLjQK..." }
}
{
"consistent": false,
"discrepancies": [{
"field": "total_amount",
"pdf_value": "1190.00",
"xml_value": "1180.00",
"message": "Gesamtbetrag im PDF ('1190.00') unterscheidet sich von dem im XML ('1180.00')."
}]
}
Exemple 3 : PDF simple sans XML intégré
Une facture PDF classique sans pièce jointe ZUGFeRD/Factur-X renvoie valid: true avec un notice informatif — pas d'erreur, mais une indication qu'aucune donnée structurée n'a pu être vérifiée.
{
"tool": "validate_invoice",
"arguments": {
"file_content": "JVBERi0xLjQK...",
"file_type": "pdf"
}
}
{
"valid": true,
"format": null,
"profile": null,
"summary": "2 Hinweise gefunden",
"errors": [],
"warnings": [],
"notices": [
{
"severity": "notice",
"rule_id": "UNKNOWN",
"message": "XML could not be extracted"
},
{
"severity": "notice",
"rule_id": "NO_EMBEDDED_XML",
"message": "Kein eingebettetes XML gefunden. Die PDF ist möglicherweise keine ZUGFeRD/Factur-X Rechnung."
}
]
}
12. Limites & restrictions connues
| Restriction | Détails |
|---|---|
| Timeout | Mustang CLI est interrompu côté serveur après 30 secondes. Les fichiers très volumineux ou corrompus peuvent déclencher ce timeout. |
| Limite de débit | Validation : Gratuit 20/semaine · Automatiser 500/semaine · Scaler illimité. Création (quota propre) : Gratuit 1 par mois · Automatiser et Scaler illimités, usage raisonnable via la limite horaire. Création sandbox : 100/jour, max. 3/minute. En cas de dépassement : HTTP 429. |
| Débit | Automatiser tourne à pleine vitesse jusqu'à 60 appels par heure, Scaler jusqu'à 300. Au-delà, rien n'est bloqué : les appels suivants passent dans une voie lente et n'obtiennent que les places libres à ce moment. Si le serveur est plein, il répond après au plus 20 secondes d'attente avec HTTP 503, Retry-After: 15 et slow_lane: true. Votre programme renvoie alors simplement la facture. Le quota hebdomadaire reste valable. |
| OCR des PDF | check_consistency n'analyse que le texte PDF lisible par machine. Les PDF scannés sans couche OCR ne sont pas pris en charge. |
| Métadonnées pour les PDF | validate_invoice extrait aussi les métadonnées des PDF, à condition qu'un XML intégré soit présent et lisible. Pour les PDF simples sans XML, ce champ est absent. |
| Contrôle de cohérence | Seuls trois champs sont comparés (numéro, date, montant). Les adresses, numéros fiscaux et détails de lignes ne sont pas confrontés. |
| ID de règle inconnues | Si une ID de règle manque dans la base de suggestions, fix_suggestion reste vide. Le message est renvoyé malgré tout. |
| Taille de fichier | API hébergée : une requête peut peser au plus 50 Mo en JSON, sinon vous recevez 413. Le Base64 grossit les fichiers d'un tiers, donc environ 35 Mo de fichiers tiennent dans une requête. Dans le contrôle par lot (/v1/stapel), chaque fichier fait au plus 15 Mo. Le serveur MCP auto-hébergé n'a pas de limite fixe, mais Mustang s'arrête après 30 secondes ; les très gros PDF n'y arrivent peut-être pas. |
| Pièces jointes | À la création d'une facture, 10 pièces jointes au plus, chacune et toutes ensemble 5 Mo au plus, mesurés après décodage. À partir de deux pièces jointes, la vérification émet l'avertissement CII-SR-476 ; la facture reste valide. |
13. Journal des modifications
Novembre 2026 : quand une remarque s'applique
- Nouveau : sur une facture qui n'est pas une XRechnung, les remarques des règles
BR-DE-…etPEPPOL-…portent le champscope("xrechnung"ou"peppol"). Il indique quand la remarque s'applique. Le rapport PDF et le validateur du site l'affichent sous le message. Les autres champs restent inchangés.
Octobre 2026 : numéro fiscal, prélèvement et pièces jointes
- Nouveau dans
create_invoice/POST /v1/create: numéro fiscal allemand au lieu d'un numéro de TVA (seller.tax_number), débours sans TVA (lines[].pass_through), montants déjà payés (prepaid_amount_cents,prepaid_vat_cents), références à des factures antérieures (preceding_invoices), prélèvement SEPA (direct_debit) et pièces jointes (attachments). - Nouveau : le profil d'émetteur (
/v1/keys/issuer) contient l'identifiant créancier (creditor_id).PUT /v1/keys/issuerne modifie que les champs présents dans la requête ; une chaîne vide ounullefface un champ. Il refuse avec400un numéro de TVA sans code pays et un numéro fiscal de forme incorrecte. - Modifié : avec une période de prestation et sans date de prestation, la date de prestation (BT-72) est désormais la fin de la période, et non plus la date de facture. Pour une facture d'acompte sans date ni période, BT-72 est omis ; la vérification ZUGFeRD émet alors un avertissement (PEPPOL-EN16931-R008).
- Modifié : les entrées qui produisaient jusqu'ici un fichier invalide (ni numéro de TVA ni numéro fiscal, numéro de TVA sans code pays, période finissant avant son début, prélèvement dans une XRechnung sans mandat) reçoivent désormais une réponse 400.
- Modifié : le PDF d'un avoir (
credit_note) n'affiche plus de montant à payer, mais indique que le montant sera crédité. - Modifié : via MCP, la réponse d'une facture ZUGFeRD avec pièces jointes ne contient que
pdf_base64; le XML est dans le PDF. - Modifié : ID de règles corrigées : plus de fausses ID (BT-89, TMP-32, EU-79), les règles KoSIT avec une lettre gardent leur nom complet (BR-DE-25-B au lieu de BR-DE-25), les messages en double disparaissent. La suggestion pour BR-DE-20 (IBAN du payeur) ne dit plus que la règle n'existe plus ; CII-SR-475 et CII-SR-476 avec plusieurs pièces jointes sont expliquées comme sans conséquence.
Octobre 2026 : détection du format
formatetprofileproviennent désormais de l'identifiant de spécification (le champ guideline en CII,CustomizationIDen UBL), et non plus de la première URN du document. Auparavant, beaucoup de factures XRechnung et EN 16931 revenaient sans format.- Nouveaux champs
container(pdf: PDF avec facture électronique intégrée,xml: fichier XML) etsyntax(CII,UBL). - Libellés :
ZUGFeRD 2.xetZUGFeRD 1.0pour un PDF, sinonXRechnung 3.0,Peppol BIS Billing 3.0ouEN 16931. Nouveaux profilsXRECHNUNGetPEPPOL;EXTENDEDn'est plus signalé commeEN16931.
Juin 2026 — Création de factures
- Nouvel outil
create_invoice/POST /v1/create: créer des factures électroniques valides à partir de données structurées — comme PDF ZUGFeRD (PDF/A-3) ou XML XRechnung pur (avec Leitweg-ID pour le B2G). - Plusieurs lignes, toutes les catégories de TVA (S/Z/E/AE), remises/majorations, informations de paiement, échéance.
- Types de document : facture, avoir/annulation, correction, autofacturation, facture d'acompte et facture partielle — avec référence à la facture d'origine.
- Branding selon le forfait (pied de page sur le forfait Gratuit / white-label à partir d'Automatiser avec logo optionnel) ; quota hebdomadaire propre, distinct de la validation.
- Clés sandbox/test (
zv_test_…) : intégration libre avec filigrane « DEMO », sans entamer le quota réel.
Avril 2026 — Première publication
- Validation selon EN 16931 (
validate_invoice) pour les PDF ZUGFeRD/Factur-X et les XML XRechnung, avec des suggestions de correction concrètes. - Extraction XML (
extract_xml) et contrôle de cohérence PDF↔XML (check_consistency). - Client MCP pour Claude & autres agents IA ; moteurs Mustang et KoSIT.