InvoiceKit

Check a Factur-X or ZUGFeRD invoice without sending the PDF to anyone

Drop a hybrid invoice PDF and get back whether a conformance validator would accept it — PDF/A-3 metadata, the embedded XML attachment, the profile the document claims versus the one its XML declares — plus the invoice XML itself. The whole checker runs in this tab: the PDF is never uploaded.

Factur-X & ZUGFeRD 2.x profiles MINIMUM, BASIC, EN 16931, EXTENDED · ISO 19005-3 (PDF/A-3) · free, no account, no email

Hybrid PDF

or drag a file onto the box below.

No file loaded. A Factur-X file is an ordinary-looking PDF — the invoice XML is an attachment inside it.

the engine starts on your first audit

Audit

Nothing to report yet. The engine loads once, then every check is local.

What is audited

A Factur-X file can fail in two places: the PDF envelope around the XML, and the XML itself. This page audits the envelope, then validates the XML with the same engine as the validator on the front page. Every finding carries a stable id, so a build can react to one defect rather than to a sentence. The rule-set picker changes the second half only: the envelope verdict does not move, because a file can be a well-formed Factur-X envelope and still carry an invoice that breaks BR-CO-15.

Envelope checks, with the ids they emit
AreaIdsExamples of what is caught
Profile and attachment fx.payload, fx.filename, fx.level, fx.flavour, fx.context, fx.multipayload no invoice XML attached; attachment named factur-x.xml while the PDF declares order.xml; MINIMUM metadata wrapping an EN 16931 XML
PDF/A-3 metadata pdfa.xmp, pdfa.schema, pdfa.part, pdfa.conformance, pdfa.outputintent, pdfa.info no XMP stream at all; pdfaid:part says 2 not 3; a colour output intent that is not DeviceRGB; an XMP extension schema missing for the profile
Attachment plumbing pdfa.af, pdfa.attachments, pdfa.fileparams, pdfa.filesize, fx.digest EmbeddedFile without FileSpec; missing checksum; the declared size disagreeing with the stored bytes
Rendering and readers pdfa.font, pdfa.tagged, pdfa.structtree, fx.fonts, fx.pages, fx.pagemode, fx.companion a font not embedded, so the invoice reflows on someone else's machine; no structure tree for accessibility; a separate factur-x.xml shipped beside the PDF instead of inside it

Fatal findings are the ones a conformance validator rejects. Warnings pass a validator but get complained about by a recipient: an untagged file, for instance. Notes explain how the document will behave in a reader.

Frequently asked

Do I need the XML as a separate file?

No — that is the point of a hybrid document. The XML is an attachment inside the PDF, and this page reads it out of there. If your toolchain emits invoice.pdf and factur-x.xml as two files, the pair is a companion arrangement, not a Factur-X file, and the audit says so.

My XML passes but the PDF fails. Why bother fixing the PDF?

Because the archive is the PDF. French public-sector platforms and German ZUGFeRD receivers reject the whole file on envelope faults long before they read the XML, and a PDF/A document that is not self-contained can render differently in ten years’ time — which matters when a tax audit asks what the invoice said.

Why is the download a few megabytes?

The engine is the whole checker — an XPath 2.0 evaluator, a Schematron runner, the CEF rule artefacts, an XML schema description and a PDF parser — compiled to one WebAssembly module. It is fetched once per browser and cached, after which the page works with the network unplugged.

Can I check invoices in bulk instead of one at a time?

Yes, off the browser: einv check dist/invoices/*.pdf audits a directory, exits non-zero on the first rejection so a release fails, and -json gives the same report this page renders. See CLI & libraries.

Is the tool really free?

Yes, with no account. The engine is open source (MIT, embedding the European Commission’s EUPL-1.2 rule artefacts unmodified). Paid work sits elsewhere: hosted pipelines, batch checking and invoice generation. If anything about this page changes, it will say so here.