Receiving mandatory since 1 January 2025

XRechnung and ZUGFeRD by API that pass on the first try

Check an invoice right here against the official KoSIT rule set — free, no sign-up, every error in plain language. For software teams: a REST API that turns JSON into valid XRechnung (UBL and CII) and ZUGFeRD, and keeps up with the rule changes.

Start free, no card required: validation never counts, 25 generated invoices per month.

Validation report

Request

$ curl -X POST api.normapi.de/v1/validate \
    -H 'Content-Type: application/xml' \
    --data-binary @invoice.xml

Response

"acceptable": false

BR-CO-16Amount due for payment does not add up

Generate

$ curl -X POST api.normapi.de/v1/invoices \
    -H 'Content-Type: application/json' \
    --data-binary @invoice-data.json \
    -o invoice.xml

200 invoice.xml validated before it leaves the API

Rule setv2026-08-31

Validate an invoice

No file chosen
Or paste XML

XML or PDF, up to 5 MB — or just drop a file here. No sign-up, no allowance to spend.

Your file is processed in memory and discarded immediately. We never store invoice content.

No invoice at hand?

One click checks the file right here — downloading is optional.

  • ValidValid invoice (UBL)

    Passes validation cleanly. A good starting point for your own mapping.

    File ↓
  • ValidValid invoice (CII)

    The same invoice in the second permitted syntax, UN/CEFACT CII.

    File ↓
  • ValidValid invoice (ZUGFeRD PDF)

    A hybrid of readable PDF and embedded CII invoice — produced by NormAPI generation, verified like every sample.

    File ↓
  • BR-DE-15Buyer reference missing

    Without BT-10 — for public-sector invoices this holds the Leitweg-ID.

    File ↓
  • BR-DE-2Seller contact missing

    The BG-6 contact group is absent entirely — the most common mapping gap.

    File ↓
  • BR-CO-16Amount due does not add up

    The amount due contradicts the totals — the classic rounding bug.

    File ↓
  • BR-DE-18Skonto notation malformed

    PROZENT=2 instead of PROZENT=2.00 — the notation started but not followed.

    File ↓
  • SchemaSchema error: invoice number missing

    Fails at the XML schema. The business rules are never evaluated — an empty error list here does not mean "nothing wrong".

    File ↓
  • Not checkedA profile with no validation scenario (Factur-X MINIMUM)

    Declares MINIMUM, which is not an EN 16931 invoice. No scenario matches, so no rule runs — the outcome is neither valid nor invalid but "not checked".

    File ↓

Samples and details on the validator page →

The deadlines

  1. Since 1 January, every company must be able to receive e-invoices.

  2. Companies with more than €800,000 prior-year turnover must issue e-invoices.

  3. The obligation extends to every company.

Transition rules and exemptions in the guide →

What NormAPI does

Two endpoints against one rule set. Nothing is transmitted — no Peppol access point, no mail delivery, no archiving.

Generate

Send invoice data as JSON, receive a valid XRechnung (UBL or CII) or ZUGFeRD document, conforming to EN 16931.

Validate

Upload a file and get a readable list of what is wrong — not just Schematron codes.

Rulesets

Every response names the version it was checked against, in the X-Normapi-Ruleset header. We keep up with new releases.

How do I know the generated invoice is valid?

Because it is checked before it leaves the API. Every generated document goes through the same KoSIT validator an uploaded file does — not a reimplementation, but KoSIT’s own tool against the official configuration. A 200 means it passed.

That this is not a given is something we measured rather than asserted. Both datasets are CC BY 4.0:

When the rules change

The XRechnung rule set is updated roughly twice a year. We email you when a new release lands and what it changes for your invoices. Nothing else — no marketing.

Unsubscribe any time with one click. Details in the privacy policy.