B2B e-invoicing: next deadline 1 January 2027

ZUGFeRD and XRechnung through one API

From 1 January 2027, German businesses with more than €800,000 in prior-year turnover must issue structured B2B invoices; from 1 January 2028, all of them must. invoiceapi.io builds those invoices from your data — validated, archived and independently verifiable.

For developers who issue invoices from their own application and would rather not build format conformance, retention and traceability themselves.

  • Validated with the KoSIT validator and veraPDF
  • ZUGFeRD PDF/A-3U and XRechnung as XML
  • Invoices and backups stored in Germany

One call. Validated documents back.

One POST per invoice. The template fixes the layout and the seller profile; your payload carries the invoice itself.

POST /v1/templates/{id}/invoices
One endpoint per template.
Authorization: Bearer sk_test_…
sk_test_ for watermarked test invoices, sk_live_ for real ones. Same path, same validation, except that sk_live_ refuses the sample data.
Idempotency-Key
Send the same key and body again and you get the original invoice back, not a second one.
422 application/problem+json
Validation failed: the rule id comes back, and nothing is produced or archived.

You create an invoice profile and a template once, in the dashboard. After that every invoice is a single call. Test mode is the same path with an sk_test_ key.

curl -X POST https://invoiceapi.io/v1/templates/$TEMPLATE_ID/invoices \
  -H "Authorization: Bearer $INVOICEAPI_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d @rechnung.json

{
  "buyer": {
    "name": "Kunde AG",
    "vatId": "DE987654321",
    "electronicAddress": "rechnung@kunde.example",
    "address": {
      "line1": "Kundenweg 1",
      "city": "München",
      "postCode": "80331",
      "countryCode": "DE"
    }
  },
  "invoice": {
    "number": "R-2026-1001",
    "issueDate": "2026-07-01",
    "dueDate": "2026-07-31",
    "currency": "EUR",
    "buyerReference": "KND-2026-77"
  },
  "items": [
    {
      "name": "Beratung",
      "quantity": "8",
      "unit": "HUR",
      "unitPrice": "120.00",
      "vatRate": "19"
    }
  ],
  "payment": {
    "reference": "R-2026-1001"
  }
}

When validation fails you get the rule id back — in German and English for the 77 catalogued rules, with its BT code and payload path where the rule maps to one; for anything else, the raw, untranslated KoSIT text. Nothing is returned and nothing is archived.

Postman collection to import (JSON)

One payload, two formats

You send the invoice data once. Both formats are generated from it, validated, and archived.

rechnung.json

Your data

Buyer, lines and payment terms as JSON; seller and bank details come from the profile.

R-2026-1001.pdf

ZUGFeRD

PDF/A-3U with embedded CII XML. People see a document, systems read the data.

PDF/A-3U · CII XML

R-2026-1001.xml

XRechnung

Plain XML to EN 16931 — for public-sector buyers and anyone else who expects XML.

XML · EN 16931

Archive

Every document is stored and never re-rendered on read. You get back the same bytes that were validated.

SHA-256

How you can check all of this

Every claim on this page, stated so that you can check it yourself.

Formats
ZUGFeRD · XRechnung
ZUGFeRD as PDF/A-3U (Mustang), XRechnung as XML. Invoice currency is EUR.
Validation
KoSIT validator + veraPDF
KoSIT validator, plus veraPDF for PDF/A-3U conformance. Validation is a hard gate: if it fails, no file is produced. GET /v1/health reports the KoSIT validator and scenario versions currently running; after a passed check both also appear in validation.summary.
Location
Germany (Falkenstein, Nuremberg)
Server, database and invoice archive in Falkenstein, the encrypted backups in Nuremberg, both in Germany. On first use, the archive's endpoint and region are checked against a fixed list of permitted locations.
Retention
8 or 10 years
From the end of the calendar year, either 8 or 10 years. A legal hold suspends deletion.
Hash chain
SHA-256
One running SHA-256 chain per organisation, over the input data and the output files. A later alteration shows up when the chain is recomputed. GoBD-oriented.
Error messages
German + English
The 77 catalogued KoSIT rules come back as plain German and English sentences, with the EN 16931 BT code and payload path where the rule maps to one. An uncatalogued rule instead returns the raw, untranslated KoSIT report text.
Export
ZIP · CSV · proof
A ZIP with the original files, a CSV and a chain proof an auditor can recompute without us.

Free

€0 per month

50 Live documents per month
1 Invoice profile

Starter

€19 per month (net)

500 Live documents per month
1 Invoice profile

Pro

€49 per month (net)

2,500 Live documents per month
5 Invoice profiles

Business

€149 per month (net)

10,000 Live documents per month
Unlimited invoice profiles

Test mode does not count against the document allowance. Test invoices carry a TESTRECHNUNG watermark. All amounts are net. We charge no VAT; the reverse charge applies to businesses in the EU.

Test mode is free

Your first validated invoice starts here

Sign in with your email address, set up an invoice profile and a template, and call the API with an sk_test_ key. Test invoices go through the same validation as live ones and carry a TESTRECHNUNG watermark; only live invoices refuse the sample data.

  1. Sign in

    A sign-in code to your inbox. No password to create.

  2. Profile and template

    Seller details and layout, set up once in the dashboard.

  3. One API call

    Send your invoice data, get the validated documents back.

    POST /v1/templates/{id}/invoices