Generate Factur-X Electronic Invoices
Last updated November 2, 2026
PDFMonkey can generate electronic invoices: PDF documents that carry a structured, machine-readable XML version of the invoice alongside the visual layout. The first supported specification is Factur-X (also known as ZUGFeRD in Germany), the Franco-German hybrid e-invoicing standard at the heart of the French e-invoicing reform.
You keep full control of how the invoice looks — it’s a regular PDFMonkey template — while PDFMonkey takes care of producing and embedding the compliant XML for you, with validation at every step.
What is Factur-X?
factur-x.xml file that accounting software and government platforms can process automatically. The result is a single PDF/A-3 file that works for both humans and machines.How it works #
- You apply a Compliance Format to your template (for example Factur-X 1.08 EN 16931 (FR-CTC Flux 2)).
- When generating a document, you send your invoice data in the document’s
payload, following the structure defined by the format. - PDFMonkey validates your data against the format’s structure and business rules (totals must add up, VAT breakdowns must be consistent, and so on).
- PDFMonkey renders your template into a PDF as usual, generates the XML from your payload, and embeds it into the final PDF/A-3 file.
- The generated document is a compliant hybrid invoice, ready to send to your customers or to an e-invoicing platform.
No XML knowledge is required — you only deal with JSON, like for any other PDFMonkey document.
Step 1: Apply a compliance format to your template #
- Open your template in the Template Editor.
- Go to the Settings panel (available in both the code editor and the visual Builder).
- In the Compliance Format section, pick a format from the dropdown — for example Factur-X 1.08 EN 16931 (FR-CTC Flux 2).
- Confirm the change.
- Click Publish. Documents are generated from the published template, so the format only applies to new documents once it’s published.
Not available on the Free plan
Test data replacement
The sample payload demonstrates the full data structure expected by the format: invoice identification, seller and buyer details, line items, tax breakdowns, and totals. Use it as the reference when building your integration.
To remove a format, click Remove Format in the same section, then publish. Your customized test data is kept.
Step 2: Design your template #
Once the format is applied, design the visual side of the invoice like any other template, using the test data fields in your Liquid code or Builder bindings.
To check the XML that will be embedded, open the Debug menu in the Template Editor navbar and select Inspect generated XML. This shows the XML produced from your current test data — handy to verify the output before going live.
Step 3: Generate documents #
Generate documents exactly as you usually do — via the API, the Dashboard, or an integration. The only difference is that your payload must follow the data structure of the compliance format.
Here is a minimal Factur-X EN 16931 payload:
{
"invoiceNumber": "INV-2026-0042",
"invoiceType": "invoice",
"issueDate": "20260215",
"currency": "EUR",
"notes": [
{
"type": "recovery_fees",
"content": "Indemnité forfaitaire pour frais de recouvrement : 40 EUR."
},
{
"type": "late_payment_penalties",
"content": "Pénalités de retard : 3 fois le taux d'intérêt légal."
},
{
"type": "early_payment_discount",
"content": "Pas d'escompte pour paiement anticipé."
}
],
"seller": {
"name": "EvilMonkeys SAS",
"legalId": "892456123",
"legalIdScheme": "siren",
"vatId": "FR12892456123",
"email": "billing@evilmonkeys.io",
"address": {
"line1": "42 rue de la Documentation",
"city": "Paris",
"postCode": "75011",
"country": "FR"
}
},
"buyer": {
"name": "TechCorp SARL",
"email": "invoices@techcorp.fr",
"address": {
"line1": "8 avenue des Intégrations",
"city": "Lyon",
"postCode": "69002",
"country": "FR"
}
},
"lineItems": [
{
"lineNumber": "1",
"name": "PDF Generation API - Enterprise Plan",
"quantity": 1,
"unitPrice": 2500.0,
"vatCategory": "standard",
"vatRate": 20,
"total": 2500.0
}
],
"taxBreakdowns": [
{
"category": "standard",
"rate": 20,
"basisAmount": 2500.0,
"taxAmount": 500.0
}
],
"paymentMeans": {
"typeCode": "58",
"iban": "FR7630006000011234567890189"
},
"paymentTerms": {
"description": "Net 30",
"dueDate": "20260317"
},
"totals": {
"lineTotal": 2500.0,
"taxBasisTotal": 2500.0,
"taxTotal": 500.0,
"grandTotal": 3000.0,
"duePayable": 3000.0
}
}
Almost every field above is mandatory: drop one and the document is rejected. The exceptions are seller.legalIdScheme, optional but worth sending so the SIREN comes with its scheme, and paymentTerms, which needs only one of description or dueDate. Several of the mandatory fields are there because the seller is French: a French seller must supply its 9-digit SIREN in seller.legalId, an electronic address for itself and one for its buyer, and the three mandatory legal-mention notes (late-payment penalties, recovery fees, early-payment discount). Sellers established elsewhere are not subject to those rules and can send a shorter payload.
The full structure — optional fields, enums, conditional requirements — is documented in the sample test data applied to your template when you select the format.
One payload, two outputs
Validation #
PDFMonkey validates your data in several layers, at two different moments.
When you create the document, the payload is checked against the format:
- Structure — the payload must contain the required fields with the right types and formats (dates, country codes, currency codes, etc.).
- Business rules — the semantic rules of the specification are enforced: line totals must match quantity × unit price, tax breakdowns must be consistent with the totals, VAT exemptions must carry a reason, and more. For French sellers, the additional rules of the French e-invoicing reform are checked as well.
If either check fails, the document is not created: the API answers 422 Unprocessable Entity and lists the problems under errors.payload, naming the offending field or, for a business rule, its official rule code. Fix the payload and send it again.
During generation, two more checks run:
- XML conformance — the generated XML is checked against the official schema of the specification.
- Embedding conformance — after embedding, the final PDF is verified to be a proper hybrid invoice (PDF/A-3 structure, attachment metadata).
If either fails, the document moves to the failure status with a failure_cause explaining why. You retrieve it like any other generation failure: in the Dashboard, via the API, or through failure webhooks.
Nothing is silently dropped: unless you explicitly opt out of the final embedding check, a successfully generated document is a valid one.
Reading back the validation result #
After embedding, PDFMonkey writes the result of the final conformance check into the document’s metadata, under the _facturx_validation key — whether the check passed or not. You can read it back via the API or in the Meta data tab of the Document Editor:
{
"_facturx_validation": {
"conforms": true,
"profile": "EN 16931",
"failures": [],
"verified_at": "2026-06-04T10:30:45Z"
}
}
| Field | Type | Meaning |
|---|---|---|
conforms | Boolean | true when every structural check passed. |
profile | String or null | Profile detected in the embedded metadata: MINIMUM, BASIC WL, BASIC, EN 16931, EXTENDED, or XRECHNUNG. null if the metadata could not be read. |
failures | Array | Empty when conforms is true. Each entry has a machine-readable code (e.g. missing_attachment), a human-readable message, and a details object. |
verified_at | ISO 8601 timestamp | When the check ran. |
Use it as an audit trail: every generated invoice carries the proof of its own conformance check.
A failed embedding check normally fails the whole document. If you need the file anyway — to inspect what came out, or because you disagree with the verdict — set _facturx_ignore_invalid_embedding to true in the document’s metadata. The check still runs and _facturx_validation still records the failures; only the hard failure is suppressed. The resulting file is not a conformant Factur-X invoice, so don’t send it to an e-invoicing platform.
Output #
The generated document is a PDF/A-3 file with the invoice XML embedded as factur-x.xml. It behaves like any other PDFMonkey document: same download URL, same webhooks, same custom filename support.
Recipients can:
- Read it like a normal PDF.
- Process it automatically with any Factur-X / ZUGFeRD compatible software, which extracts the embedded XML.
Supported formats #
| Format | Profile | Version |
|---|---|---|
| Factur-X | EN 16931 | 1.08 (compatible ZUGFeRD 2.4) |
Factur-X is the first supported specification. Support for additional formats and profiles will expand over time — the workflow described on this page (apply a compliance format, send a conforming payload) will stay the same.
Frequently asked questions #
Do I need to write any XML?
No. You send JSON, as with any PDFMonkey document. The XML is generated and embedded automatically based on the compliance format applied to your template.
Can I use an existing template?
Yes. Apply a compliance format to it in the Template Editor settings and publish it. Keep in mind your test data will be replaced with a format-compliant sample, and your generation payloads will need to follow the format’s structure.
What happens if my invoice data is invalid?
Structural and business-rule problems are caught when you create the document: the API returns 422 Unprocessable Entity with the offending field or rule code, and no document is created. Problems found later, during XML generation or embedding, move the document to the failure status instead. Either way, fix the payload and send it again.
Is the output really compliant?
Yes. The XML is validated against the official specification schema and business rules, and the final PDF is verified to be a structurally correct PDF/A-3 hybrid invoice after embedding.
Does the conformance check run on every document I generate?
No. It only runs on documents that actually embed an XML invoice. Regular PDFs skip it entirely, and no _facturx_validation metadata is written.
Does this work with image output formats?
No. Electronic invoicing requires PDF output, since the XML is embedded in the PDF file itself.
Related pages #
- Generate PDFs with the API – end-to-end generation workflow
- Webhooks – get notified of generation success or failure
- Document Statuses – understand the generation lifecycle
- Set a Custom Filename – control the name of the generated file