ZUGFeRD API — Generate & Validate Factur-X Invoices
Add ZUGFeRD to your software without implementing PDF/A-3 packaging, embedded CII XML, profile rules, and validation logic yourself. Generate and validate compliant hybrid invoices through one API — for developers integrating German e-invoicing.
- PDF + XML in one file
- 6 profiles
- One POST
No credit card required · 500 free trial invoices, 30-day expiry.
Get an API key instantly and generate your first ZUGFeRD PDF in under a minute.
- ZUGFeRD profiles
- 6
- Container format
- PDF/A-3
- Embedded XML
- EN 16931
- Data retention
- 0
JSON Input
Canonical invoice data
InvoiceSpec Engine
Maps to EN 16931 & validates
Compliant Output
One file, two readers, same data
The document below is a real ZUGFeRD PDF/A-3 generated by the engine from a single canonical JSON invoice. The PDF page is what a person reads; the XML is what software reads — extracted from inside that exact PDF.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><rsm:CrossIndustryInvoice xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100" xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"><rsm:ExchangedDocumentContext><ram:BusinessProcessSpecifiedDocumentContextParameter><ram:ID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</ram:ID></ram:BusinessProcessSpecifiedDocumentContextParameter><ram:GuidelineSpecifiedDocumentContextParameter><ram:ID>urn:cen.eu:en16931:2017</ram:ID></ram:GuidelineSpecifiedDocumentContextParameter></rsm:ExchangedDocumentContext><rsm:ExchangedDocument><ram:ID>INV-DEMO-001</ram:ID><ram:TypeCode>380</ram:TypeCode><ram:IssueDateTime><udt:DateTimeString format="102">20250701</udt:DateTimeString></ram:IssueDateTime></rsm:ExchangedDocument><rsm:SupplyChainTradeTransaction><ram:IncludedSupplyChainTradeLineItem><ram:AssociatedDocumentLineDocument><ram:LineID>1</ram:LineID></ram:AssociatedDocumentLineDocument><ram:SpecifiedTradeProduct><ram:Name>Consulting Services</ram:Name></ram:SpecifiedTradeProduct><ram:SpecifiedLineTradeAgreement><ram:NetPriceProductTradePrice><ram:ChargeAmount>150.0</ram:ChargeAmount><ram:BasisQuantity>1</ram:BasisQuantity></ram:NetPriceProductTradePrice></ram:SpecifiedLineTradeAgreement><ram:SpecifiedLineTradeDelivery><ram:BilledQuantity unitCode="C62">10</ram:BilledQuantity></ram:SpecifiedLineTradeDelivery><ram:SpecifiedLineTradeSettlement><ram:ApplicableTradeTax><ram:TypeCode>VAT</ram:TypeCode><ram:CategoryCode>S</ram:CategoryCode><ram:RateApplicablePercent>19</ram:RateApplicablePercent></ram:ApplicableTradeTax><ram:SpecifiedTradeSettlementLineMonetarySummation><ram:LineTotalAmount>1500.00</ram:LineTotalAmount></ram:SpecifiedTradeSettlementLineMonetarySummation></ram:SpecifiedLineTradeSettlement></ram:IncludedSupplyChainTradeLineItem><ram:ApplicableHeaderTradeAgreement><ram:BuyerReference>991-12345-67</ram:BuyerReference><ram:SellerTradeParty><ram:Name>Acme GmbH</ram:Name><ram:SpecifiedLegalOrganization><ram:ID>HRB98765</ram:ID></ram:SpecifiedLegalOrganization><ram:DefinedTradeContact><ram:PersonName>Max Mustermann</ram:PersonName><ram:TelephoneUniversalCommunication><ram:CompleteNumber>+49 30 12345678</ram:CompleteNumber></ram:TelephoneUniversalCommunication><ram:EmailURIUniversalCommunication><ram:URIID>billing@acme.de</ram:URIID></ram:EmailURIUniversalCommunication></ram:DefinedTradeContact><ram:PostalTradeAddress><ram:PostcodeCode>10115</ram:PostcodeCode><ram:LineOne>Musterstr. 1</ram:LineOne><ram:CityName>Berlin</ram:CityName><ram:CountryID>DE</ram:CountryID></ram:PostalTradeAddress><ram:URIUniversalCommunication><ram:URIID schemeID="9930">DE123456789</ram:URIID></ram:URIUniversalCommunication><ram:SpecifiedTaxRegistration><ram:ID schemeID="VA">DE123456789</ram:ID></ram:SpecifiedTaxRegistration></ram:SellerTradeParty><ram:BuyerTradeParty><ram:Name>Example Corp</ram:Name><ram:PostalTradeAddress><ram:PostcodeCode>75001</ram:PostcodeCode><ram:LineOne>12 Rue de Rivoli</ram:LineOne><ram:CityName>Paris</ram:CityName><ram:CountryID>FR</ram:CountryID></ram:PostalTradeAddress><ram:URIUniversalCommunication><ram:URIID schemeID="9930">FR12345678901</ram:URIID></ram:URIUniversalCommunication></ram:BuyerTradeParty></ram:ApplicableHeaderTradeAgreement><ram:ApplicableHeaderTradeDelivery><ram:ActualDeliverySupplyChainEvent><ram:OccurrenceDateTime><udt:DateTimeString format="102">20250701</udt:DateTimeString></ram:OccurrenceDateTime></ram:ActualDeliverySupplyChainEvent></ram:ApplicableHeaderTradeDelivery><ram:ApplicableHeaderTradeSettlement><ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode><ram:SpecifiedTradeSettlementPaymentMeans><ram:TypeCode>30</ram:TypeCode><ram:PayeePartyCreditorFinancialAccount><ram:IBANID>DE89370400440532013000</ram:IBANID></ram:PayeePartyCreditorFinancialAccount></ram:SpecifiedTradeSettlementPaymentMeans><ram:ApplicableTradeTax><ram:CalculatedAmount>285.00</ram:CalculatedAmount><ram:TypeCode>VAT</ram:TypeCode><ram:BasisAmount>1500.00</ram:BasisAmount><ram:CategoryCode>S</ram:CategoryCode><ram:RateApplicablePercent>19</ram:RateApplicablePercent></ram:ApplicableTradeTax><ram:SpecifiedTradePaymentTerms><ram:Description>Payment due</ram:Description></ram:SpecifiedTradePaymentTerms><ram:SpecifiedTradeSettlementHeaderMonetarySummation><ram:LineTotalAmount>1500.00</ram:LineTotalAmount><ram:TaxBasisTotalAmount>1500.00</ram:TaxBasisTotalAmount><ram:TaxTotalAmount currencyID="EUR">285.00</ram:TaxTotalAmount><ram:GrandTotalAmount>1785.00</ram:GrandTotalAmount><ram:DuePayableAmount>1785.00</ram:DuePayableAmount></ram:SpecifiedTradeSettlementHeaderMonetarySummation></ram:ApplicableHeaderTradeSettlement></rsm:SupplyChainTradeTransaction></rsm:CrossIndustryInvoice>
You shouldn't have to maintain PDF/A-3 and ZUGFeRD internals
Your application sends structured invoice data. InvoiceSpec handles the supported profile, embedded XML, PDF/A-3 packaging, and validation underneath — and keeps that implementation current as ZUGFeRD and EN 16931 evolve.
Generate ZUGFeRD
Send a canonical JSON invoice; receive a ZUGFeRD PDF/A-3 document with the EN 16931 CII XML embedded inside it (Content-Type: application/pdf). The example below uses a real minimal invoice body and the default EN16931 (COMFORT) profile — swap in your API key and it runs.
curl -X POST https://api.invoicespec.com/v1/invoice/zugferd \-H "Authorization: Bearer YOUR_API_KEY" \-H "Content-Type: application/json" \--output invoice-zugferd.pdf \-d '{"invoice":{"invoiceNumber":"INV-DEMO-001","issueDate":"2025-07-01","invoiceTypeCode":"380","currencyCode":"EUR","buyerReference":"991-12345-67","seller":{"name":"Acme GmbH","legalRegistrationIdentifier":"HRB98765","vatIdentifier":"DE123456789","electronicAddress":"DE123456789","electronicAddressSchemeId":"9930","postalAddress":{"addressLine1":"Musterstr. 1","city":"Berlin","postcode":"10115","countryCode":"DE"},"contact":{"contactPoint":"Max Mustermann","telephone":"+49 30 12345678","email":"billing@acme.de"}},"buyer":{"name":"Example Corp","electronicAddress":"FR12345678901","electronicAddressSchemeId":"9930","postalAddress":{"addressLine1":"12 Rue de Rivoli","city":"Paris","postcode":"75001","countryCode":"FR"}},"deliveryInformation":{"actualDeliveryDate":"2025-07-01"},"paymentInstructions":{"meansCode":"30","creditTransfer":{"accountIdentifier":"DE89370400440532013000"}},"documentTotals":{},"vatBreakdowns":[{"vatCategoryCode":"S","vatCategoryRate":19}],"invoiceLines":[{"lineIdentifier":"1","quantity":10,"unitCode":"C62","priceDetails":{"netPrice":150},"lineVatInformation":{"vatCategoryCode":"S","vatRate":19},"itemInformation":{"name":"Consulting Services"}}]},"config":{"spec":"zugferd","syntax":"cii","profile":"EN16931"}}'
The response is the real PDF/A-3 shown in the demo above — a styled, human-readable invoice page with the EN 16931 CII XML embedded as the ZUGFeRD AF attachment.
Validate ZUGFeRD
Check an existing ZUGFeRD PDF against PDF/A-3 conformance and the embedded CII XML's ZUGFeRD profile rules before you send it. Upload the PDF and an optional version; the validator extracts the embedded XML, checks conformance, and returns a structured validation report.
curl -X POST https://api.invoicespec.com/v1/invoice/zugferd/validate \-H "Authorization: Bearer YOUR_API_KEY" \-F "file=@invoice-zugferd.pdf" \-F 'request={"version":"2.5.2"}'
{"valid": false,"version": "2.5.2","syntax": "CII","summary": { "errors": 1, "warnings": 0, "information": 0 },"issues": [{"severity": "ERROR","code": "BR-DE-15","message": "An electronic address (BT-34) of the Seller is required."}],"requestId": "req_01HXYZ..."}
A failed validation is not an HTTP error — the endpoint returns 200 OK with valid: false and a structured issue list.
No signup required — upload a ZUGFeRD PDF and validate it directly in the browser.
Validation-error handling
Validation errors are returned as data, not as HTTP failures, so you can handle them programmatically. Each issue carries a normalized severity (ERROR, WARNING, INFORMATION), the official rule code (e.g. BR-DE-15), and a human-readable message. Inspect the issues array, map each finding back to the offending invoice field, and re-run generation or validation once corrected.
Supported ZUGFeRD profiles
ZUGFeRD (Factur-X) profiles are layers on top of the EN 16931 semantic model. All six profiles — MINIMUM, BASICWL, BASIC, EN16931 (COMFORT, the default), XRECHNUNG, and EXTENDED — are generated from the same canonical invoice data.
MINIMUM
GeneratableFactur-X MINIMUM — a below-EN16931 booking aid. The embedded XML carries only header-level data (seller, buyer, totals); line items are suppressed from the XML but still rendered on the visual PDF page.
BASICWL
GeneratableFactur-X BASIC WL (Without Lines) — same as MINIMUM but allows a buyer reference. Line items are suppressed from the embedded XML; the PDF still shows full line data.
BASIC
GeneratableFactur-X BASIC — a subset of EN 16931 with no data loss. Suitable when the recipient only needs the core invoice data.
EN16931 (COMFORT)
Generatable · defaultFactur-X EN16931 / COMFORT — the default profile. Matches the EN 16931 semantic model exactly, so the generated PDF carries the full invoice fidelity the DTO provides.
XRECHNUNG
GeneratableFactur-X XRECHNUNG — EN 16931 plus the German CIUS rules. Use when the recipient expects a ZUGFeRD container that also satisfies the XRechnung conformance level.
EXTENDED
GeneratableFactur-X EXTENDED output is supported for the currently modeled invoice fields. The EXTENDED URN is stamped, but ZUGFeRD-specific BT-X extension fields (logistics service fees, line-level ship-to parties, sales agents, etc.) are not yet exposed by the InvoiceSpec input model.
Typical integration workflow
From structured invoice data to a compliant ZUGFeRD PDF/A-3 ready for your existing delivery workflow — the engine handles the PDF rendering, XML embedding, and rule checking.
- 1
Send structured invoice data
POST a canonical JSON invoice to /v1/invoice/zugferd. No PDF or XML hand-authoring — the engine maps your data to the EN 16931 model and selects the ZUGFeRD profile from your config (default EN16931 / COMFORT).
- 2
Engine generates and validates
InvoiceSpec maps your data to EN 16931, serializes it as CII D16B XML, renders a styled, human-readable invoice page to PDF/A-3, and embeds the CII XML as the ZUGFeRD AF attachment.
- 3
Validate before you send
POST an existing ZUGFeRD PDF to /v1/invoice/zugferd/validate. The validator extracts the embedded CII XML, checks PDF/A-3 conformance, and validates the XML against the ZUGFeRD profile rules.
- 4
Handle the result
A valid generation comes back as a PDF/A-3 binary; a failed validation returns 200 OK with a structured issue list you can act on programmatically.
Frequently asked questions
What is a ZUGFeRD invoice?
ZUGFeRD (Factur-X) is the German hybrid e-invoice format: a PDF/A-3 document that carries a human-readable invoice page and the machine-readable EN 16931 CII XML embedded as an attachment. One file serves both a person reading it and software consuming it — the structure required for German e-invoicing compliance.
Which ZUGFeRD profiles can I generate?
MINIMUM, BASICWL, BASIC, EN16931 (COMFORT, the default), XRECHNUNG, and EXTENDED. All six are generated from the same canonical EN 16931 invoice data. MINIMUM and BASICWL suppress line items from the embedded XML (the PDF still shows full line data); EXTENDED stamps the URN but does not model extension-only fields.
How are validation errors returned?
Validation failures are not HTTP errors. The endpoint returns 200 OK with valid: false and a structured issues array (severity, code, message), so you can surface and fix each finding programmatically. The validator checks PDF/A-3 conformance and the embedded CII XML against the ZUGFeRD profile rules.
What is the relationship between the PDF and the XML?
The PDF/A-3 container is the deliverable; the EN 16931 CII XML is embedded inside it as the ZUGFeRD/Factur-X Associated File (AF) attachment, with XMP metadata declaring the relationship. The XML is the authoritative machine-readable invoice; the visible PDF page is the human-readable view of the same data. The engine generates both from a single canonical invoice so they never diverge.
Is this only for German invoices?
InvoiceSpec currently focuses on German e-invoicing. ZUGFeRD is the German hybrid PDF format built on the European EN 16931 semantic model, which is also available as a first-class capability with its own endpoints. XRechnung, the German XML-only format, has its own dedicated landing page and endpoints. Additional countries and delivery networks would only be listed here once they are actually supported.
Start with 500 free trial invoices
Generate and validate ZUGFeRD invoices against the real API — no credit card required to get started.
- PDF + XML in one file
- 6 profiles
- One POST
API key in seconds — first ZUGFeRD PDF in under a minute.