Skip to content

For developers

E-invoicing API: XRechnung, ZUGFeRD, Factur-X, Peppol BIS, FA(3)

Last reviewed SUPPORTED WITH LIMITATIONS

KRONENWERK does not have a separate "e-invoice generation" endpoint. Structured e-invoices are produced and validated at the moment an invoice is issued in the product, in the format the seller's country requires: XRechnung or ZUGFeRD in Germany, Factur-X in France, Peppol BIS Billing 3.0 UBL in Belgium, FA(3) XML in Poland. Your integration creates the draft with POST /invoices/drafts and receives invoice.issued when the validated document exists. Separately, a free, anonymous checker at POST /api/v1/meta/pruefen validates any file against a country's rules and stores nothing.

How structured formats are produced from a draft

A draft holds facts: seller, buyer, lines, dates, currency. When a person issues it, the country module of the seller's legal entity turns those facts into the document that country expects and validates the result before the invoice number is spent. The same facts produce a PDF for the reader and a structured file for the machine; which structured syntax and which profile depends on the country and on the company's settings.

  1. The tax verdict is computed from the facts (seller and buyer country, business or consumer, kind of supply) and the buyer's VAT ID is checked against VIES. A verdict of "requires input" stops issuance until a person decides.
  2. The country module renders the structured document — UBL, CII, PDF/A-3 with embedded CII, or FA(3) XML.
  3. The document is validated with the rules that country publishes. A German document runs through the KoSIT Schematron rules and is cross-checked with the Mustang library; the validators that ran are recorded with the result.
  4. Only if validation passes is the number spent, the archive row frozen and invoice.issued queued for your webhook endpoint.

This is why the API stops at the draft. A document that fails validation is a document a person needs to fix, and the fields that decide the format are settings of the legal entity, not parameters of a request. The reasoning is set out on the invoice API page.

Per-country behaviour at issuance

Seller countryStructured format producedSyntaxValidationTransportStatus
GermanyXRechnung or ZUGFeRD (EN 16931 profile), chosen in the company's settingsUBL or CII (XRechnung); PDF/A-3 with embedded CII (ZUGFeRD)KoSIT Schematron, cross-checked with MustangEmail or download; German law names no transmission routeSUPPORTED
FranceFactur-XPDF/A-3 with embedded CIIEN 16931 rules for the profileDownload and email; transmission through a plateforme agréée is not yet production-readyGeneration SUPPORTED; transmission NOT YET READY
BelgiumPeppol BIS Billing 3.0UBL 2.1EN 16931 and Peppol BIS rulesPeppol through an accredited access point provider (Storecove), once connected in Settings → DeliverySUPPORTED WITH LIMITATIONS
PolandFA(3)FA(3) XML (not an EN 16931 document)FA(3) schema and rulesKSeF 2.0 module built, environment-dependent, not used against production KSeFGeneration SUPPORTED WITH LIMITATIONS; transmission NOT YET READY
Canada, United StatesNone — no structured mandate existsPDF with national tax rulesTax rules onlyEmail or downloadSUPPORTED

XRechnung, ZUGFeRD, Factur-X and Peppol BIS are all implementations of the European semantic model EN 16931; ZUGFeRD and Factur-X are technically the same hybrid standard, published jointly by FeRD and FNFE-MPE. FA(3) is Poland's own schema and is not an EN 16931 syntax. The formats are compared on e-invoice formats; the German choice is explained on XRechnung vs ZUGFeRD.

What the API exposes about e-invoices

Less than you might expect, and the list is exact.

  • POST /invoices/drafts starts the draft that will become the structured document. It accepts customerId only.
  • GET /invoices and GET /invoices/{number} return the issued invoice's frozen figures: number, documentType, buyer, currency, issuedOn, dueOn, deliveredOn, net, tax, gross, outstanding, paymentState, overdue, cancelled, creditNote, paidOn, recordedAt.
  • The invoice.issued webhook reports that a validated document now exists, with invoiceId, number, documentType, buyerName, issueDate, dueDate, currency, netMinor, taxMinor, grossMinor, amountDueMinor and paymentState.

Not exposed, and not reachable at any scope: the XML or PDF file itself, the validation report of an issued invoice, the tax verdict's reasoning, the Peppol or KSeF transmission state, and any endpoint that issues, sends or cancels. The files are downloaded in the product; transmission is configured and observed there. Whether a future version of the API adds file download is not promised here.

The free checker: POST /api/v1/meta/pruefen

The checker validates one file against one country's rules and answers with a structured verdict. It needs no account and no API key, and it keeps nothing — not the file, not a digest, not a row. It exists because every German business has had to accept structured e-invoices since 1 January 2025 and most have no way to tell whether the one that just arrived is valid; charging for that check would be charging for compliance itself. The browser version is at check an e-invoice.

The request is multipart/form-data with two parts: datei (the file) and land (the ISO country code whose rules apply: DE, FR, BE, PL, CA or US). The country is required. It used to default to Germany, and a Belgian invoice checked against German rules gets a confident answer that is confidently wrong.

curl -X POST https://kronenwerk.org/api/v1/meta/pruefen \
  -F "datei=@rechnung.xml" \
  -F "land=DE"
{
  "istERechnung": true,
  "lesbar": true,
  "gueltig": false,
  "format": "XRechnung (UBL)",
  "profil": "urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0",
  "zusammenfassung": "…",
  "lieferant": "Beispiel GmbH",
  "nummer": "2026-0041",
  "rechnungsdatum": "2026-08-28",
  "waehrung": "EUR",
  "nettoMinor": 89000,
  "steuerMinor": 16910,
  "bruttoMinor": 105910,
  "fehler": [
    { "schwere": "…", "quelle": "…", "regel": "BR-DE-15", "ort": "…", "meldung": "…" }
  ],
  "hinweise": [],
  "leseprobleme": [],
  "validatoren": ["KoSIT validationtool …", "…"]
}

The three booleans answer three different questions. istERechnung: is this a structured e-invoice at all, as opposed to a plain PDF or an image. lesbar: could the document be read into an invoice. gueltig: does it pass the country's rules. A plain PDF is istERechnung: false and not an error. fehler and hinweise are lists of findings, each with a severity, the validator that raised it, the rule identifier, a location and a message. leseprobleme lists extraction problems, validatoren the validators that actually ran, so that a partial check is visible as partial. The totals are present only when the document adds up; a document that does not is already a finding, and showing no total beats showing a guess. Values of format, profil and zusammenfassung depend on the file and are illustrative above.

Limits of the checker

  • Files larger than 25 MB are refused with 413 before a byte is parsed. A real e-invoice with its embedded XML is a few hundred kilobytes.
  • Requests are rate-limited per client address: a budget of 5 checks that refills at one check per 60 seconds. Beyond that the answer is 429 with a Retry-After header and a JSON body saying how long to wait. The checker is a tool for people and occasional scripts, not a bulk validation service.
  • Nothing is stored, so there is no history and no link to return to. Keep the response if you need it.
  • The checker validates; it does not decide legal questions. Whether a document that passes is also a correct invoice for VAT purposes in your situation requires professional confirmation.

Receiving structured invoices

The same readers behind the checker are used inside the product: incoming XRechnung, ZUGFeRD/Factur-X and UBL documents are read into bills with their supplier, number, date and totals, and their validation result is stored with the bill. That inbound path is not exposed on the public API today; bills recorded in the product are reported outward by the purchase.recorded webhook with purchaseId, kind, documentNumber, supplierName, supplierId, documentDate, dueDate, currency, netMinor, taxMinor and grossMinor. German receiving obligations are explained on receiving e-invoices in Germany.

How KRONENWERK handles this

SUPPORTED WITH LIMITATIONS Generation and validation of XRechnung, ZUGFeRD, Factur-X, Peppol BIS UBL and FA(3) at issuance are part of the product (e-invoicing). The API's part of that is the draft, the read-back and the webhook, on the Enterprise plan (pricing). The checker is free for everyone. Transport is where the limitations sit: Peppol sending and receiving go through an accredited access point provider (Storecove) once the company is connected in Settings → Delivery — KRONENWERK is not itself a Peppol Access Point; French transmission through a plateforme agréée is planned via Storecove's approved-platform capability and is not yet production-ready; the Polish KSeF 2.0 module has not been used against the production KSeF. Each is covered on its own page: Peppol integration, KSeF integration, and the format guide for developers at EN 16931 for developers.

Frequently asked questions

Can I generate an XRechnung or Factur-X file through the API?

Not directly. You create a draft with POST /invoices/drafts; the structured file is generated and validated when a person issues the draft in the product, and invoice.issued tells you it exists.

Can I download the XML or PDF of an issued invoice through the API?

No. GET /invoices/{number} returns the frozen figures, not the file. Files are downloaded in the product.

Does the checker store my invoice?

No. Nothing is kept — not the file, not a digest, not a log row with its contents. The response is the only record.

Which countries does the checker support?

The land parameter accepts the countries KRONENWERK has a compliance module for: DE, FR, BE, PL, CA and US. It is required; there is no default.

Is FA(3) an EN 16931 format?

No. FA(3) is Poland's national schema for KSeF and carries no EN 16931 profile identifier. XRechnung, ZUGFeRD, Factur-X and Peppol BIS Billing 3.0 are EN 16931 implementations.

Sources

  1. KRONENWERK developer documentation read on
  2. KoSIT — XRechnung (standard, Schematron and validator) read on
  3. FeRD — ZUGFeRD standard (profiles, PDF/A-3, CII) read on
  4. FNFE-MPE — Factur-X read on
  5. OpenPeppol — Peppol BIS Billing 3.0 (May 2026 release) read on
  6. Ministry of Finance (Poland) — KSeF 2.0 environments read on

Start integrating

Read the quickstart Reference

Read next