API documentation
Receiving invoices
Both endpoints accept an incoming ZUGFeRD/Factur-X PDF — as
multipart field pdf (file) or form field
pdfBase64. Nothing is created and nothing is stored.
POST /v1/read — read (deserialize)
Extracts the embedded CII XML and returns the invoice as a full JSON object
in the eunormia schema —
the same schema /v1/convert accepts as input.
You can process the result directly or feed it back into a conversion
unchanged (round-trip).
Response: {"standard": "facturx", "invoice": {…}, "xml": "<rsm:CrossIndustryInvoice…"}.
The raw XML is included in case you need fields beyond the schema.
Not a readable e-invoice PDF → 422.
POST /v1/validate — validate
Validates the PDF against the double gate: veraPDF (PDF/A-3) and the EN 16931 Schematron. Optionally in addition:
| Field | Description |
|---|---|
kosit=true | Official KoSIT validator (XRechnung/DE) as a third gate. |
frCtc=true | French CTC rules (FNFE-MPE) as a fourth gate. |
Response: {"valid": true|false, "verapdf": {…}, "xml": {…}, "kosit": {…}?, "frCtc": {…}?, "sha256": "…"}.
Each gate reports result (PASS/FAIL/UNAVAILABLE)
and, on FAIL, the concrete failures. A check module that is not
installed honestly reports UNAVAILABLE — never a silent PASS.
Try it in the browser: validation page.
Quickstarts
cURL — /v1/read
curl -X POST https://eunormia.com/v1/read -F 'pdf=@eingang.pdf'
cURL — /v1/validate (+ KoSIT + FR-CTC)
curl -X POST https://eunormia.com/v1/validate \
-F 'pdf=@eingang.pdf' -F 'kosit=true' -F 'frCtc=true'
C# (HttpClient)
using var client = new HttpClient();
var form = new MultipartFormDataContent {
{ new ByteArrayContent(File.ReadAllBytes("eingang.pdf")), "pdf", "eingang.pdf" }
};
var resp = await client.PostAsync("https://eunormia.com/v1/read", form);
var doc = System.Text.Json.JsonDocument.Parse(await resp.Content.ReadAsStringAsync());
var number = doc.RootElement.GetProperty("invoice").GetProperty("number").GetString();