Free ZUGFeRD and Factur-X validator
Valinvo's free validator checks a ZUGFeRD 2.x or Factur-X invoice, as the PDF with the invoice embedded or as the CII XML alone, against the official rules. For a PDF it also checks the PDF itself (PDF/A-3) and its metadata. Every problem comes with its rule ID, its location and a message. You need no account and no API key, and your file is processed in memory and not stored.
Open the validator · Use it from code (API quickstart)
What it checks
- The invoice XML (UN/CEFACT CII) against the FeRD rules of ZUGFeRD 2.5.2 / Factur-X 1.09.2, for the profiles MINIMUM, BASIC WL, BASIC, EN 16931 and EXTENDED. The profile is read from the document, so you do not choose it first.
- France: a Factur-X EN 16931 invoice with a French billing frame (BT-23, for example
S1) is also checked against the official French rules of the e-invoicing reform,BR-FR-…(FNFE-MPE 1.4.0.04). - The PDF (ZUGFeRD, Factur-X, or XRechnung in a PDF): we read the attached
factur-x.xml,zugferd-invoice.xmlorxrechnung.xmland check it as above, check the PDF against PDF/A-3 (ISO 19005-3, with veraPDF), and check that the PDF's XMP metadata names the same profile and attachment as the XML. - The invoice is only
validwhen the XML, the metadata and PDF/A-3 all pass. The result names what was applied, for examplezugferd-2.5.2-en16931+pdf-a-3uorfactur-x-1.09.2-en16931-fr-1.4.0.04+pdf-a-3u. - Files up to 20 MB.
Not supported yet: the French profile EXTENDED-CTC-FR and ZUGFeRD 1.0. You get a clear message instead of a result.
The rules come from the official publishers (FeRD for ZUGFeRD / Factur-X, CEN for EN 16931, FNFE-MPE for the French rules) and are applied as published.
How to use it
- Open the validator and upload the PDF, or paste the XML.
- Click Validate.
- Read the list: each error shows the rule ID, the location and what is wrong. Fix the invoice in your system and validate again.
From code: the same check as an API
curl -X POST https://valinvo.bmk-hub.com/v1/validate \
-H 'X-Accept-Terms: 1.0' \
-H 'Content-Type: application/pdf' \
--data-binary @invoice.pdf
For the XML alone, send Content-Type: application/xml. A valid ZUGFeRD PDF without a delivery date gives:
{
"ruleSet": "zugferd-2.5.2-en16931+pdf-a-3u",
"valid": true,
"errors": [],
"warnings": [{
"rule": "PEPPOL-EN16931-R008",
"message": "Document MUST not contain empty elements. (still status warning)",
"location": "/rsm:CrossIndustryInvoice[1]/rsm:SupplyChainTradeTransaction[1]/ram:ApplicableHeaderTradeDelivery[1]"
}]
}
Warnings do not make an invoice invalid. This one is common: the ZUGFeRD schema requires the delivery block even when there is no delivery date or ship-to address to put in it. An invoice with problems is a normal 200 answer with valid: false. A PDF without an invoice attachment gets 400 no_embedded_invoice. More in the quickstart.
Common ZUGFeRD and Factur-X errors
| Rule | What it means | Usual fix |
|---|---|---|
BR-CO-15, BR-CO-16 | The totals don't add up: total with VAT ≠ total without VAT + VAT, or amount due ≠ total − paid + rounding. | Calculate the totals from the lines and VAT breakdown, rounded to 2 decimals. |
BR-S-02, BR-CO-26 | Lines with standard-rated VAT, but no seller VAT ID (and no other seller identifier). | Add the seller's VAT ID (BT-31). |
BR-FR-05 | A mandatory French note is missing: PMT (recovery costs), PMD (late-payment penalties) or AAB (early-payment discount). | Add all three notes with their subject codes. |
BR-FR-10, BR-FR-32 | The seller's SIREN (BT-30, scheme 0002) is missing or not exactly 9 digits. | Use the 9-digit SIREN with scheme 0002. |
BR-FR-12 | The buyer's electronic address (BT-49) is missing. | Add it, usually scheme 0225 with the buyer's SIREN. |
BR-FR-CO-12 | A French invoice in another currency without the VAT total in EUR. | Add the tax currency EUR (BT-6) and the VAT total in EUR (BT-111). |
PDF/A-3 … | The PDF isn't valid PDF/A-3. The rule ID names the ISO 19005-3 clause and test, for example PDF/A-3 6.2.11.4.1-1 (a font is not embedded). | Produce the PDF with a PDF/A-3 capable library, with all fonts embedded. |
ZF-XMP-1 … ZF-XMP-4 | The PDF's metadata doesn't match the invoice: no XMP, no profile, a different profile, or a different attachment name. | Write the Factur-X XMP extension with the XML's profile and file name. |
French rule IDs come back with the business term they concern, for example BR-FR-05_BT-22_PMT. The French rules' messages are in French, as published.
Questions
Is the validator really free? Yes. The online validator needs no account or API key. The API can also be tried without a key, with a small daily limit for creating invoices.
Is my invoice stored? No. The file is processed in memory and not stored. Please use sample data or invoices you are allowed to share.
Does "valid" mean the recipient or the French platform accepts it? Not necessarily. The check applies the official rules as published. A recipient or a plateforme agréée (PA) may check more, and the check is not tax or legal advice.
Can Valinvo also create the invoice? Yes. You send one JSON invoice and receive a ZUGFeRD PDF (zugferd-en16931) or a French Factur-X (factur-x-fr), checked against the same rules. See the quickstart.
By using the validator you accept the Terms of Use.
Quickstart · XRechnung validator · Peppol validator · ZUGFeRD / Factur-X validator · ZUGFeRD-csharp: your options · Error codes