Validation API: first check in four steps
Send UBL or CII XML to POST /v1/validate and get a JSON report: schema check, EN 16931 rules, rule codes and locations. You only need curl or Node.js 18+.
Status: available at https://api.erechio.de (server in Nuremberg, Germany; status and measured availability). Good to know: the JSON field names and the detailed explanations in the response are in German; rule codes and the original rule messages are in English. The table in step 3 explains every field. The free test key is available to everyone; paid plans are currently available only to businesses based in Germany.
1. Get a free test key
Free, 50 documents per month, valid one month, no sign-up and no payment details. The page shows your key (starts with pk_test_) exactly once; we store only a hash of it. If today's instant keys are used up, request one by e-mail and you get a one-time pick-up link. Set both values as environment variables:
export ERECHIO_URL="https://api.erechio.de"
export ERECHIO_KEY="pk_test_…"
2. Send the sample invoice
Download the sample invoice with errors (UBL, sample data only) and send it:
curl -sS -X POST "$ERECHIO_URL/v1/validate" \
-H "Authorization: Bearer $ERECHIO_KEY" \
-H "Content-Type: application/xml" \
--data-binary @rechnung-mit-fehlern.xml
Use --data-binary, not -d: -d strips line breaks, so line numbers of schema errors no longer match.
Node.js 18+, no packages – file validate.mjs:
import { readFile } from 'node:fs/promises';
const file = process.argv[2] || 'rechnung-mit-fehlern.xml';
const res = await fetch(process.env.ERECHIO_URL + '/v1/validate', {
method: 'POST',
headers: { Authorization: 'Bearer ' + process.env.ERECHIO_KEY, 'Content-Type': 'application/xml' },
body: await readFile(file),
});
const r = await res.json();
if (res.status !== 200) { console.error('No validation:', res.status, r.fehler.code); process.exit(2); }
console.log(r.vollstaendig_validiert ? 'Fully validated' : 'Not valid: ' + r.fehler + ' error(s)');
for (const m of r.meldungen.filter(m => m.level === 'fehler')) console.log('-', m.code, m.location);
process.exit(r.vollstaendig_validiert ? 0 : 1);
3. Read the response
| Field | Meaning |
|---|---|
HTTP 200 | The validation ran. It does not mean the invoice is free of errors. |
vollstaendig_ | The field to rely on (“fully validated”). true = XML schema and all rules without errors, as the KoSIT validator accepts the file. Only send the invoice if true. |
regelpruefung_ | “Rule check passed”: the business rules report no error and the identifier matches a KoSIT profile. Can be true while the schema is violated. |
schemapruefung | Schema check: bestanden (passed) or fehlgeschlagen (failed). |
fehler, warnungen | Number of errors and warnings. Errors lead to rejection, warnings do not. |
meldungen[] | Messages: code (e.g. BR-CO-16; XSD = schema error), level (fehler error, warnung warning, hinweis info), text (original rule message), location (XPath, for schema errors the line), erklaerung (German explanation for frequent rules; English versions are under error codes). |
kontingent | Quota after this call: genutzt used, limit, rest remaining. |
regelstand | Identifier of the rule version used. |
Other status codes: 401 key missing or wrong · 400 body is not XML (forgot @ in curl) · 422 XML but not a UBL or CII invoice (for ZUGFeRD send the embedded XML, not the PDF) · 413 larger than 2 MB · 429 quota or 60 per minute reached · 503 time limit or overloaded. None of these count against the quota.
4. Validate your own invoice
- Same call with your file:
--data-binary @my-invoice.xmlornode validate.mjs my-invoice.xml. - Cross-check with the sample invoice without errors (KoSIT test file): it must return
vollstaendig_validiert: true. - Fix schema errors (
XSD) first, then the rule errors. - Without the API: the same check in the browser validator, the file stays on your computer.
Full reference: OpenAPI file · API reference.
Technical notes on the data format, not tax or legal advice. Whether VAT rate, supply and amounts are correct in substance is a question for your tax adviser.