W System / Blog / Read incoming XRechnung / ZUGFeRD / Factur-X invoices as JSON
Read incoming XRechnung, ZUGFeRD and Factur-X invoices as JSON
Short answer: German businesses have had to accept e-invoices since 1 January 2025, and those arrive as UBL XML, CII XML or a ZUGFeRD / Factur-X PDF with XML inside. You don't need two XML parsers and a PDF extractor to get the data into your own model. Below you'll find which fields matter, what trips up home-grown parsers, and one HTTP call that turns any of the three into the same JSON (seller, buyer, dates, totals, VAT breakdown, IBAN, lines), with a real example.
What arrives in the inbox
| Format | What it is | Where the data is |
|---|---|---|
| XRechnung (UBL) | German CIUS of EN 16931, UBL 2.1 Invoice or CreditNote | the XML file itself |
| XRechnung (CII) | same rules, UN/CEFACT Cross Industry Invoice syntax | the XML file itself |
| ZUGFeRD 2.x / Factur-X | PDF/A-3 with the invoice XML (CII) embedded | an attachment inside the PDF (factur-x.xml, zugferd-invoice.xml, xrechnung.xml) |
| Peppol BIS Billing 3.0 | EN 16931 UBL over the Peppol network | the XML file itself |
What trips up home-grown parsers
- Two syntaxes, one meaning. UBL calls the seller
cac:AccountingSupplierParty; CII calls itram:SellerTradeParty. The EN 16931 business terms (BT-*) are the same, so map both to one model. - Credit notes. UBL credit notes use a different root and
CreditNoteLine; CII uses type code 381 on the same structure. - The PDF is a container. For ZUGFeRD / Factur-X the legally relevant data is the embedded XML, not the visible PDF text. Read the XML; don't OCR the page.
- Amounts are decimals as text. Keep them as strings or Decimal; floats lose cents in VAT sums.
- Several bank accounts. An invoice can carry more than one payment means and IBAN; the example below has two.
- Reading is not checking. A file that parses can still break BR-CO-15 (total with VAT = without VAT + VAT) or BR-DE-15 (buyer reference). Validate before you book.
One call: e-invoice in, JSON out
Disclosure: I'm the maker of this API (W System). POST https://api.wsystem.dev/einvoice/parse takes the raw file (application/xml or application/pdf) or JSON {"xml": "..."} / {"base64": "..."} and returns one JSON shape for UBL, CII and ZUGFeRD / Factur-X. Values come back as written; it does not validate (use POST /einvoice/validate for the EN 16931 / XRechnung rules). Free for 20 calls a day per IP, or get a free API key (500 units/month); without a key past that, $0.01 per call via x402. AI agents can use the MCP tool parse_einvoice on the W System MCP server.
# official CEN example invoice (EN 16931 validation artefacts 1.3.17, examples/ubl-tc434-example1.xml)
curl -X POST "https://api.wsystem.dev/einvoice/parse" -H "Content-Type: application/xml" --data-binary @ubl-tc434-example1.xml
# a ZUGFeRD / Factur-X PDF works the same way
curl -X POST "https://api.wsystem.dev/einvoice/parse" -H "Content-Type: application/pdf" --data-binary @invoice.pdf
No code yet? Drop the file into the free in-browser validator and click Read as JSON: it calls the same endpoint and shows the fields plus the full JSON (free tier, no key).
Real response from the live API (27 October 2026), lines 3 to 20 left out:
{
"syntax": "ubl",
"document_type": "invoice",
"profile": "EN 16931",
"customization_id": "urn:cen.eu:en16931:2017",
"container": {"container": "xml"},
"invoice": {
"invoice_number": "12115118",
"issue_date": "2015-01-09",
"type_code": "380",
"currency": "EUR",
"due_date": "2015-01-09",
"seller": {"name": "De Koksmaat", "vat_id": "NL8200.98.395.B.01", "legal_registration_id": "57151520",
"address": {"street": "Postbus 7l", "city": "Velsen-Noord", "postal_code": "1950 AB", "country": "NL"}},
"buyer": {"name": "ODIN 59", "address": {"street": "POSTBUS 367", "city": "HEEMSKERK", "postal_code": "1960 AJ", "country": "NL"},
"contact": {"name": "Dhr. J BLOKKER"}},
"totals": {"line_total": "229.60", "total_without_vat": "229.60", "vat_total": "20.73",
"total_with_vat": "250.33", "amount_due": "250.33"},
"vat_breakdown": [
{"category": "S", "rate": "6", "taxable_amount": "183.23", "tax_amount": "10.99"},
{"category": "S", "rate": "21", "taxable_amount": "46.37", "tax_amount": "9.74"}
],
"payment": [
{"means_code": "30", "remittance_information": "Deb. 10202 / Fact. 12115118", "iban": "NL57 RABO 0107307510"},
{"means_code": "30", "iban": "NL03 INGB 0004489902"}
],
"lines": [
{"id": "1", "name": "PATAT FRITES 10MM 10KG", "quantity": "2", "unit": "EA", "unit_price": "9.95",
"net_amount": "19.90", "vat_category": "S", "vat_rate": "6", "seller_item_id": "166022"},
{"id": "2", "name": "PKAAS 50PL. JONG BEL. 1KG", "quantity": "1", "unit": "EA", "unit_price": "9.85",
"net_amount": "9.85", "vat_category": "S", "vat_rate": "6", "seller_item_id": "661813"}
... 18 more lines
]
},
"line_count": 20,
"note": "Values are read as written in the XML (strings, no rounding or recomputation). Reading does not check validity: use POST /einvoice/validate for the EN 16931 / XRechnung rules. Not tax advice."
}
Example file: CEN eInvoicing-EN16931 validation artefacts 1.3.17. The CII version of the same invoice (CII_example1.xml) returns the same values with "syntax": "cii". A ZUGFeRD PDF returns "container": {"container": "pdf", "embedded_file": "factur-x.xml"}.
Read, then validate
curl -X POST "https://api.wsystem.dev/einvoice/validate" -H "Content-Type: application/xml" --data-binary @ubl-tc434-example1.xml
Parse to fill your booking form or match the invoice to a purchase order; validate to decide whether to accept it or ask the supplier for a corrected one.
Get a free API key (500 units a month, no card) and point your inbox handler at /einvoice/parse.
Questions and answers
Do German businesses have to receive e-invoices?
Yes. Since 1 January 2025 every business in Germany must be able to receive structured e-invoices (EN 16931, e.g. XRechnung or ZUGFeRD/Factur-X from the EN 16931 profile up) for domestic B2B supplies; a mailbox for the files is enough to accept them. Issuing becomes mandatory in steps from 2027. See the BMF FAQ on e-invoicing and the W System Germany deadlines page. Receiving is the part most invoicing, bookkeeping and DMS products have to build first.
Which formats does POST /einvoice/parse read?
UBL 2.1 Invoice and CreditNote (incl. XRechnung UBL and Peppol BIS Billing 3.0), UN/CEFACT CII (incl. XRechnung CII), and ZUGFeRD / Factur-X PDFs, where it extracts the embedded XML (factur-x.xml, zugferd-invoice.xml, xrechnung.xml) and reads that. All three return the same JSON shape.
Does it validate the invoice?
No. Parsing only reads values as written: amounts stay strings, nothing is rounded or recomputed, and an invoice that breaks the business rules still parses. To check the EN 16931 and XRechnung business rules (BR-*, BR-DE-*) call POST /einvoice/validate, or paste the file into the free e-invoice validator on wsystem.dev.
What fields come back?
Syntax, document type, profile and CustomizationID; invoice number, type code, currency, issue and due date, notes; seller and buyer (name, VAT ID, legal registration ID, address, contact); references; totals (line total, without VAT, VAT, with VAT, prepaid, amount due); the VAT breakdown per category and rate; payment means with IBAN and remittance text; every line (quantity, unit, price, net amount, VAT category and rate, item IDs); and embedded attachments.
How do I send a PDF?
Send the raw file with Content-Type: application/pdf, or JSON {"base64": "..."}. XML can go raw (application/xml) or as JSON {"xml": "..."}. A PDF without an embedded invoice XML returns HTTP 400 (bad_input), because a plain PDF is not an e-invoice. Maximum file size is 5 MB.
What does it cost?
It shares the free tier with the other W System endpoints: 20 calls a day per IP without a key, or a free API key with 500 units a month. Without a key past the free tier it is $0.01 per call via x402 (USDC on Base). AI agents can call the same parser as the MCP tool parse_einvoice.
Is the invoice stored?
No. The document is parsed in memory and not kept; only a usage counter (endpoint and status) is kept. See the privacy policy on wsystem.dev.
Related
- Germany e-invoicing deadlines 2025–2028
- Free e-invoice validator (EN 16931, XRechnung, Peppol BIS 3)
- EU e-invoice API: validate, create and route
- EN 16931 and XRechnung validation rules
- MCP server (parse_einvoice tool)
Facts checked 2026-10-27. W System is the maker of this product. Not affiliated with the European Commission. Not legal or tax advice.