Factur-X / ZUGFeRD PDF generation API

You already have the invoice XML. What you still need is the hybrid PDF around it: a human-readable invoice, normalized to PDF/A-3, with the XML embedded as factur-x.xml. That is the whole job of POST /einvoice-to-pdf — same async queue, signed webhooks and Idempotency-Key as every other PDFik endpoint, on every plan.

Start for Free →E-invoicing docs

What is a Factur-X / ZUGFeRD hybrid invoice PDF?

One file, two readers. A person opens an ordinary invoice; accounting software reads the UN/CEFACT Cross-Industry Invoice (CII) XML attached inside the same PDF and books it without OCR or manual entry. Factur-X (France) and ZUGFeRD 2.x (Germany) are the same standard under two names, and it is the hybrid format used as both countries phase in mandatory B2B e-invoicing.

PDFik's part is deliberately narrow: you supply the XML, PDFik builds the hybrid PDF/A-3 around it. It never generates or alters invoice data.

Two ways to generate an e-invoice PDF/A-3

ModeYou sendHuman-readable halfBest for
Dedicated endpoint
POST /einvoice-to-pdf
The CII XML, optionally a profile and a templateBuilt from your XML by a block template (dashboard-designed or the built-in one)Billing systems that have the XML and no invoice design
einvoice option
on POST /url-to-pdf or POST /html-to-pdf
Your URL or HTML plus an einvoice block with the XMLYour own rendered page, normalized to PDF/A-3Teams that already render invoices and want to keep that design

Both paths validate the XML identically and produce the same kind of file: a PDF/A-3 with factur-x.xml inside. In both, the profile defaults to en16931; Idempotency-Key and free test mode work as on every other endpoint.

How the e-invoicing API works

  1. POST the XML (UTF-8, up to 1 MB) to /einvoice-to-pdf. It is validated against the official XSD of the declared profile first; invalid XML returns 422 with a documented error anchor and spends no quota.
  2. Receive 202 Accepted with a job_id — the render runs asynchronously on sandboxed Chromium workers.
  3. Poll the job or wait for the webhook — HMAC-signed, with retries and a dead-letter queue on every plan.
  4. Download the PDF/A-3; it carries your XML unchanged as factur-x.xml.

The XML travels inside a JSON string, so build the body from the file instead of quoting it inline. The Idempotency-Key is optional but recommended: a retry after a timeout returns the original job instead of a second one.

# invoice.xml is your UN/CEFACT CII file (EN 16931 profile)
jq -n --rawfile xml invoice.xml '{xml: $xml, profile: "en16931"}' > request.json

curl -X POST https://api.pdfik.net/einvoice-to-pdf \
  -H "X-API-Key: sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: inv-42" \
  -d @request.json

# 202 Accepted
{ "job_id": "8bfa5cc3-09ef-436f-80d4-a0eb867123aa", "status": "queued" }

Keeping your own design? Attach the same XML to a normal render on /html-to-pdf or /url-to-pdf:

{
  "html": "<h1>Invoice #90812</h1>…",
  "einvoice": {
    "profile": "en16931",
    "xml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>…"
  }
}

Delivery is the ordinary asynchronous flow described in the webhooks guide. Files are deleted within 24–48 hours; the per-file ceiling is 150 MB on every plan; every PDF carries Creator/Producer metadata of PDFik.net. Full request and response shapes are in the e-invoicing reference.

Factur-X profiles (EN 16931)

Five profiles are accepted: minimum, basicwl, basic, en16931 (the default) and extended. You declare one in the request, and the XML is validated against the official XSD of that profile — not a generic check. Credit notes (TypeCode 381) render with a CREDIT NOTE heading.

Block templates and language presets

The dedicated endpoint draws the visual invoice from a block template you design under Dashboard → E-Invoice (login required): logo, colours, 8 free fonts (sans, serif, mono, Lato, Open Sans, Roboto, Noto Sans, Noto Serif), page format A4 / A3 / A5 / Letter / Legal, page margins, editable field labels, and a live preview while you edit. Click Make default and the API uses that template whenever a request sends none; without a default, the built-in template applies.

  • 10 language presets — English, German, French, Italian, Spanish, Dutch, Polish, Portuguese, Czech, Ukrainian — across 14 locales for dates and amounts.
  • Common EN 16931 fields in designed blocks: buyer reference, order and contract references, delivery date, billing period, ship-to, SEPA/IBAN payment details, party contacts — laid out, not dumped as leftovers.
  • Credit notes (TypeCode 381) rendered with a CREDIT NOTE heading automatically.

Validation — and what a valid file does not prove

Every XML is validated against the official XSD of its declared profile before any quota is spent; a failure is a 422 with a documented error anchor, not a failed job you paid for. The output is checked in the release gate with veraPDF (PDF/A-3b) and Mustangproject (Factur-X structure).

The honest caveat: schema-valid does not mean tax-compliant. PDFik proves the container is well-formed; whether the invoice content — parties, amounts, VAT treatment, mandatory statements — is correct for your jurisdiction remains the caller's responsibility. PDFik will not fix an invoice; it will refuse a malformed one before charging you. We say this plainly because a green validator is easy to over-read.

Proof: the sample invoice, the file it produces, and how to check it yourself

Everything above is a claim. Here are the two files behind it — the EN 16931 invoice XML we publish as the example, and the hybrid PDF our API returned for exactly that file — plus the two commands that let you check the PDF yourself with the same open-source validators we use. Nothing here asks you to trust a screenshot of our own tooling.

1. The input — an EN 16931 CII invoice

An ordinary cross-border B2B invoice: a Polish seller, a German buyer, four line items, one VAT rate of 23%, a delivery date, SEPA payment details and payment terms. Net 309.00 EUR, VAT 71.07 EUR, gross 380.07 EUR. The company names, the VAT numbers, the IBAN and the BIC in it are placeholders — invented, and belonging to nobody.

<rsm:CrossIndustryInvoice
    xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
    xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
    xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
  <rsm:ExchangedDocumentContext>
    <ram:GuidelineSpecifiedDocumentContextParameter>
      <ram:ID>urn:cen.eu:en16931:2017</ram:ID>      <!-- must match "profile": "en16931" -->
    </ram:GuidelineSpecifiedDocumentContextParameter>
  </rsm:ExchangedDocumentContext>
  <rsm:ExchangedDocument>
    <ram:ID>INV-2026-0107</ram:ID>
    <ram:TypeCode>380</ram:TypeCode>                <!-- 380 invoice, 381 credit note -->
    <ram:IssueDateTime><udt:DateTimeString format="102">20260901</udt:DateTimeString></ram:IssueDateTime>
  </rsm:ExchangedDocument>
  …four line items, seller, buyer, delivery date, SEPA payment means…
      <ram:SpecifiedTradeSettlementHeaderMonetarySummation>
        <ram:LineTotalAmount>309.00</ram:LineTotalAmount>
        <ram:TaxTotalAmount currencyID="EUR">71.07</ram:TaxTotalAmount>
        <ram:GrandTotalAmount>380.07</ram:GrandTotalAmount>
        <ram:DuePayableAmount>380.07</ram:DuePayableAmount>
      </ram:SpecifiedTradeSettlementHeaderMonetarySummation>

Download the full XML — the exact file the PDF below was built from.

2. The output — the hybrid PDF/A-3

This is what POST /einvoice-to-pdf returned for that XML with the built-in English template. Open it in any reader and it is an invoice; open the attachments panel and there is one file, factur-x.xml, byte-identical to the input. Three details inside are worth checking, because they are the ones that are easy to get wrong:

  • the embedded file is named exactly factur-x.xml;
  • it is attached with the AFRelationship value Alternative — both halves carry the same invoice — and not the factur-x library's default of Data, which we keep only for minimum and basicwl, whose XML is not a complete invoice;
  • the XMP metadata carries the Factur-X extension with fx:ConformanceLevel spelled EN 16931 — with the space.

Download the Factur-X PDF/A-3.

3. Check it yourself

Two independent open-source tools, neither of them ours. veraPDF is, in its own words, "a purpose-built, open source, file-format validator covering all PDF/A and PDF/UA parts and conformance levels". Mustangproject is an APL2-licensed Java library and command-line tool that reads, writes and validates ZUGFeRD 2 / Factur-X. Both are free downloads; run them on the PDF above:

# 1. PDF/A-3b container — veraPDF (verapdf.org)
verapdf -f 3b --format xml sample-invoice.pdf | grep -o 'isCompliant="[a-z]*"'

# 2. Factur-X structure — Mustangproject (mustangproject.org)
java -jar Mustang-CLI.jar --no-notice --action validate --source sample-invoice.pdf \
  | grep -o '<summary status="[a-z]*"' | tail -1

One detail that costs people days: do not gate on Mustang's exit code. It tracks the XML half only — a file with a broken PDF/A container and valid XML still exits 0. Read the last <summary status="…"> in the report instead, which is why the command above pipes the report rather than checking $?. These two checks, read exactly this way, are our own release gate: a rendered Factur-X PDF has to pass both before an e-invoicing build ships.

What this proves is bounded, so we word it the same way every time: the output is validated with veraPDF and Mustang. That is a statement about the container and the structure. It says nothing about whether your amounts, VAT treatment or mandatory statements are right — that is the content of your invoice, and it stays yours.

Germany does not recognise MINIMUM or BASIC-WL

The German Federal Ministry of Finance says it in one sentence in its e-invoicing FAQ:

„Insbesondere die in Deutschland üblichen Formate XRechnung und ZUGFeRD ab Version 2.0.1 (mit Ausnahme der Profile MINIMUM und BASIC-WL) erfüllen die umsatzsteuerlichen Voraussetzungen für eine E-Rechnung.“

In English: the formats common in Germany — XRechnung, and ZUGFeRD from version 2.0.1 onward, with the exception of the MINIMUM and BASIC-WL profiles — meet the VAT requirements for an e-invoice. Source: bundesfinanzministerium.de — FAQ E-Rechnung (read 7 September 2026).

PDFik accepts minimum and basicwl because the standard defines them and some workflows use them as accompanying data. But we say what they are in three places: the 202 response repeats the warning in its detail, the docs profile table marks them as not a complete legal invoice, and this page marks them here. If the file has to work as an invoice in Germany, send basic, en16931 or extended.

What PDFik does not produce

"One API for e-invoicing" is a sales answer, not a true one. PDFik builds exactly one artefact: a Factur-X / ZUGFeRD hybrid PDF/A-3 around CII XML that you supply. It does not produce:

  • XRechnung — the German standard operated by KoSIT on behalf of the IT-Planungsrat. It defines invoice information as an XML data set, in UBL 2.1 or UN/CEFACT CII syntax, not as a PDF. We neither emit it nor check your XML against its rules (xeinkauf.de/xrechnung).
  • Peppol BIS Billing 3.0 — UBL Invoice and UBL Credit Note. We do not read UBL input and we are not a Peppol access point (docs.peppol.eu).
  • KSeF FA(3) — the Polish national structured-invoice format, which replaced FA(2) on 1 February 2026. We do not generate it and we send nothing to KSeF (ksef.podatki.gov.pl).

The input side is just as narrow: CII only, no UBL. If what you need is one of the three above, a Factur-X PDF is not the artefact — use a tool built for it, and come back for the PDF half if you still need one.

Want to repeat this with your own invoice? Paste the XML into the sandbox without an account, or create a free account — no credit card required — and make the same call with your own key.

Pricing: every plan, no add-on

E-invoicing is included on Free (100 PDFs/month, clean output), Starter $29, Pro $99 and Business $449 monthly, cheaper annually — no upgrade required. The rest of the contract does not change either: 150 MB per file, files deleted within 24–48 hours, signed webhooks with retries and a dead-letter queue, sandboxed Chromium with SSRF filtering. A rejected request spends no quota. Annual rates are on the pricing page.

Try it with your own invoice

No account yet? The sandbox on the home page takes pasted invoice XML and returns a real, watermarked Factur-X PDF through the same pipeline customers use — a few renders per day per visitor. If it looks right, create a free account and make the same call with your key.

Open the sandbox →Create a free account

FAQ

What is a Factur-X or ZUGFeRD PDF?

A hybrid e-invoice: one PDF/A-3 file that a person reads as an ordinary invoice and accounting software reads through the UN/CEFACT Cross-Industry Invoice XML embedded inside it as factur-x.xml. No OCR, no manual entry.

Is Factur-X the same as ZUGFeRD?

Yes. Factur-X (France) and ZUGFeRD 2.x (Germany) are the same standard under two names, and it is the hybrid PDF format used as both countries phase in mandatory B2B e-invoicing. One PDFik output serves either name.

Does the API generate the invoice XML for me?

No. PDFik never generates or alters invoice data. Your billing system or ERP emits the UN/CEFACT Cross-Industry Invoice XML; PDFik validates it against the official XSD of the declared profile, builds the human-readable PDF around it and embeds it unchanged.

Which Factur-X profiles does the e-invoice API support?

minimum, basicwl, basic, en16931 (the default) and extended. The XML is validated against the official XSD of the profile you declare before any quota is spent; invalid XML is a 422 with a documented error anchor.

Can I keep my own invoice design and still get a PDF/A-3 e-invoice?

Yes. Add the einvoice option to POST /url-to-pdf or POST /html-to-pdf: the page you render becomes the human-readable half, the output is normalized to PDF/A-3 and the XML is embedded as factur-x.xml.

Is a schema-valid Factur-X PDF automatically tax-compliant?

No. PDFik checks the XML against the official XSD and verifies the output in its release gate with veraPDF (PDF/A-3b) and Mustangproject (Factur-X structure). Whether the amounts, tax rates and parties are correct is the content of your invoice, and that stays your responsibility.

Does PDFik generate XRechnung, Peppol UBL or KSeF FA(3)?

No. PDFik builds one artefact: a Factur-X / ZUGFeRD hybrid PDF/A-3 around CII XML you supply. XRechnung is a standalone XML data set (UBL 2.1 or CII) operated by KoSIT; Peppol BIS Billing 3.0 is UBL; KSeF FA(3) is the Polish national structured-invoice format that replaced FA(2) on 1 February 2026. We generate none of them, we are not a Peppol access point, and the input side accepts CII only — UBL invoice XML is not supported.

Can I use the MINIMUM or BASIC WL profile for a German invoice?

No. The German Federal Ministry of Finance states in its e-invoicing FAQ that XRechnung and ZUGFeRD from version 2.0.1 meet the VAT requirements for an e-invoice, with the explicit exception of the MINIMUM and BASIC-WL profiles. PDFik accepts them because the standard defines them as accompanying data, and repeats the warning in the 202 response. For a real invoice, use basic, en16931 or extended.

Does e-invoicing cost extra, and does test mode work with it?

There is no separate price: e-invoicing is available on every plan, including Free — the output is the same clean PDF/A-3 everywhere. Invalid XML is rejected before any quota is spent, and test mode and Idempotency-Key work exactly as on the other endpoints.

Full request and error reference: docs.pdfik.net/einvoicing. Found something outdated? Tell us and we'll fix it.