ZUGFeRD Embedding API Reference
Combine a user-supplied PDF and a user-supplied UN/CEFACT Cross Industry Invoice (CII) XML into a single ZUGFeRD 2.x compliant PDF/A-3 with the XML embedded as the factur-x.xml attachment (per the modern ZUGFeRD / Factur-X convergence on the attachment filename; the XRechnung reference profile is embedded as xrechnung.xml), packaged per the German (FeRD) conventions expected by German B2B and B2G readers. The XML is validated with the full /v1/validate/zugferd rule set before embedding, so a non-compliant invoice never leaves the API (pass skipValidation=true to package without business-rule checks).
https://api.invoicexml.com/v1/embed/zugferd
Code Example
curl -X POST https://api.invoicexml.com/v1/embed/zugferd \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "[email protected]" \ -F "[email protected]"
Try it out online, no coding required
Upload a PDF together with a CII XML and download the embedded Factur-X / ZUGFeRD PDF instantly, right in your browser.
Request
| Parameter | Type | Description |
|---|---|---|
| pdf * | binary | The base PDF to embed the XML into. Any standard PDF is accepted, it will be promoted to PDF/A-3 by the embedder. |
| xml * | binary | A UN/CEFACT Cross Industry Invoice (CII) XML document. The root element must be CrossIndustryInvoice in the CII D16B namespace, UBL documents are not accepted. The Specification identifier (BT-24) must declare one of the official ZUGFeRD/Factur-X profile URNs, see the accepted profiles below. |
| skipValidation | boolean | Optional, defaults to false. When true, the business-rule (Schematron) validation is skipped and only the structural checks run (CII root, official BT-24 profile URN, profile XSD). See the validation section below. |
Content-Type: multipart/form-data
Validation Before Embedding
The XML is embedded into the PDF verbatim, byte for byte, so whatever this endpoint accepts is exactly what your recipient's validator will see. To catch faults on your side of the exchange rather than at the buyer's portal, the uploaded XML is validated with the full rule set of the matching validation endpoint (the declared profile's official XSD plus the Schematron business rules) before anything is embedded.
- Fatal findings reject the request with a 400 response (
errorCode 4001) carrying the complete findings array, in the same shape as the validation endpoints. Fix the reported fields and resubmit. - Warnings never block: a request can succeed while the document carries advisory findings.
- Pass
skipValidation=trueto package without business-rule checks, for example while migrating historical documents. The structural checks always apply: the XML root must be a CII invoice, BT-24 must declare an official profile URN, and the document must conform to the profile's official XSD, because a schema-invalid attachment can never yield a compliant hybrid PDF.
Accepted Profiles (BT-24)
A hybrid PDF mirrors the invoice's Specification identifier (BT-24, the
GuidelineSpecifiedDocumentContextParameter/ID element) into the PDF/A-3
XMP metadata as the conformance level, and the ZUGFeRD/Factur-X specification enumerates the values
allowed there. That makes BT-24 a closed list on this endpoint: an invoice declaring anything else can
never yield a compliant hybrid PDF and is rejected with a 400 response
(errorCode 4017). This is a requirement of the format specification,
not an InvoiceXML limitation. Standalone CII validation
(/v1/validate/cii) has no such restriction, because EN 16931 treats
BT-24 as an open identifier.
| Profile | BT-24 Specification identifier |
|---|---|
| MINIMUM | urn:factur-x.eu:1p0:minimum |
| BASIC WL | urn:factur-x.eu:1p0:basicwl |
| BASIC | urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic |
| EN 16931 (Comfort) | urn:cen.eu:en16931:2017 |
| EXTENDED | urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended |
| EXTENDED-CTC-FR (reference profile, France) | urn:cen.eu:en16931:2017#conformant#urn.cpro.gouv.fr:1p0:extended-ctc-fr |
| XRECHNUNG (reference profile) | urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0 |
| E-REPORTING (France) | urn.cpro.gouv.fr:1p0:ereporting |
The legacy ZUGFeRD 2.0 identifiers (urn:zugferd.de:2p0:* and their
#compliant#/#conformant# forms) and the
older XRechnung CIUS URNs (1.2 through 2.3) are also accepted for backwards compatibility. Matching is
case-insensitive.
Common mistake: #compliant# vs #conformant#
The EXTENDED profile is a superset of EN 16931, so its URN uses the
#conformant# keyword. The narrower profiles (BASIC, XRECHNUNG) use
#compliant#. A mixed form such as
urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:extended is not
defined by any version of the specification and is rejected with
errorCode 4017, even though the same XML passes
/v1/validate/cii as a plain EN 16931 invoice (with a
PROFILE-DETECTION warning).
Headers
| Header | Value |
|---|---|
| Authorization * | Bearer YOUR_API_KEY |
| Content-Type | multipart/form-data |
Response
200 Embedded PDF
Returns the embedded PDF/A-3 as a binary file.
The response filename is derived from the uploaded PDF: {original-name}-facturx.pdf.
The Content-Disposition header is set to attachment for direct download.
How the Embed XML API Works
The API takes two uploads and produces a single hybrid PDF/A-3 ready for B2B exchange:
Receive the PDF and the CII XML
Upload your already rendered invoice PDF (from your accounting system, template engine, or any source) together with the matching UN/CEFACT Cross Industry Invoice XML. The API shape-checks the XML root, only CrossIndustryInvoice documents are accepted. UBL invoices are rejected, convert them with /v1/convert/ubl/to/cii first.
Validate the XML
The XML is validated with the full rule set of the matching validation endpoint: the declared profile's official XSD plus the Schematron business rules. Fatal findings stop the request with the complete findings list before anything is packaged; warnings never block. Pass skipValidation=true to run the structural checks only.
Promote the PDF to PDF/A-3 and embed the XML
The base PDF is converted to PDF/A-3 in-place, then the XML is attached byte for byte as the factur-x.xml attachment with the metadata required by ZUGFeRD / Factur-X (relationship, MIME type, AFRelationship). The result is a single hybrid container that is both human-readable and machine-processable.
Return the embedded PDF
The API response is the new PDF/A-3 streamed back as application/pdf. The filename is derived from the uploaded PDF: {original-name}-facturx.pdf.
Useful resources
Companion material for integrating against the API.
Frequently Asked Questions
How does this differ from /v1/embed/facturx?
Both endpoints produce a hybrid PDF/A-3 with the standard Factur-X XMP metadata; they differ in packaging conventions. /v1/embed/zugferd follows the German (FeRD) practice: AFRelationship Alternative for full-invoice profiles (Data for MINIMUM and BASIC WL, which are not complete invoices), and the XRechnung reference profile keeps its dedicated conformance level with the attachment named xrechnung.xml and the CIUS version in the metadata. /v1/embed/facturx follows the French (FNFE-MPE) practice: always factur-x.xml with AFRelationship Data, XRechnung and e-reporting wrapped at their EN 16931 baseline. Use the endpoint that matches the conventions your downstream consumer expects.
Which ZUGFeRD profile is written into the metadata?
The profile is parsed from the GuidelineSpecifiedDocumentContextParameter/ID element (BT-24) of the input XML, so the XMP advertises the conformance level (MINIMUM, BASIC WL, BASIC, EN 16931 / Comfort, EXTENDED, XRECHNUNG) actually present in your CII document, never a hardcoded default. Because that XMP value is a closed list in the specification, BT-24 must declare one of the official profile URNs; anything else is rejected with errorCode 4017, see the accepted profiles table above.
Which XML formats are accepted?
Only UN/CEFACT Cross Industry Invoice (CII) D16B XML, the root element must be <CrossIndustryInvoice> in the CII namespace. UBL documents are rejected with a 400 response. If your invoice is in UBL syntax, convert it first using POST /v1/convert/ubl/to/cii.
Is the source PDF validated as PDF/A?
Any standard PDF is accepted. The embedder promotes the container to PDF/A-3 in-place, adding the metadata, output intent, and document structure required for archival conformance. The visual content is preserved as-is.
Is the XML validated against EN 16931 rules?
Yes, by default. The uploaded XML runs through the exact rule set of POST /v1/validate/zugferd (the declared profile's official XSD plus the matching Schematron business rules) before anything is embedded. Fatal findings reject the request with errorCode 4001 and the complete list of findings; warnings never block. Because the XML is embedded verbatim, whatever passes here is exactly what your recipient's validator will see, so errors are caught before the invoice reaches the buyer's system. If you deliberately need to package a document without business-rule checks (for example during a migration), pass the skipValidation=true form field: structural checks (CII root, official BT-24 profile URN, profile XSD conformance) still apply, since a schema-invalid attachment can never yield a compliant hybrid.
Why was my XML rejected with errorCode 4017?
Your invoice's Specification identifier (BT-24) is not one of the profile URNs defined by the ZUGFeRD/Factur-X specification. The profile is mirrored into the PDF/A-3 metadata as the conformance level, which only allows the official profiles, so this is a requirement of the format itself, not an InvoiceXML limitation. A frequent typo is mixing the keywords: the EXTENDED profile uses #conformant# while the narrower profiles use #compliant#. Check your URN against the accepted profiles table above; the error response also lists every accepted value.
What is the maximum file size?
20 MB per file. PDFs are typically the larger of the two uploads, CII XML files are usually a few kilobytes.
Is the input data stored?
No. Both files are processed entirely in memory and discarded immediately after the embedded PDF is returned. Nothing is written to disk or retained server-side.