Finekot API
EN 16931 · XRechnung 3.0 · ZUGFeRD / Factur-X

ZUGFeRD validator API for PDF/A-3 invoices

€0.02 per check · No subscription, no contract.

Post the hybrid PDF as it is. The API finds factur-x.xml inside, reads the profile and checks the XML against the EN 16931 rules.

Request
curl -H "Authorization: Bearer $FINEKOT_KEY" -F file=@invoice.pdf https://api.finekot.com/v1/e-invoice
Response (shortened)
{
  "valid": true,
  "verdict": "technically_valid",
  "container": "pdf",
  "attachment": "factur-x.xml",
  "profile": {"name": "Factur-X / ZUGFeRD EN 16931 (COMFORT)"},
  "errors": 0, "warnings": 0,
  "issues": [],
  "cost": 0.02, "balance": 0.98
}
Price per call€0.02per check

No subscription, no contract.

create from JSON €0.04 · PDF → XRechnung €0.10

A subscription bills the same monthly plan for 10 invoices or 1,000. Here you prepay any amount and pay per call; unused credit stays.

10 free checks a day · €1 free with a key · then €0.02 per check

Check node-zugferd output in Node.js

Use the EN16931 or BASIC profile in node-zugferd: MINIMUM and BASIC WL are not EN 16931 invoices and do not meet the German requirement.

Node.js 18+ · node-zugferd
// pdfA: the PDF/A-3 returned by node-zugferd
//   const pdfA = await invoice.embedInPdf(pdf, { … })
const form = new FormData();
form.append("file", new Blob([pdfA], { type: "application/pdf" }), "invoice.pdf");

const res = await fetch("https://api.finekot.com/v1/e-invoice", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.FINEKOT_KEY}` },
  body: form,
});
const rep = await res.json();
console.log(rep.attachment, rep.profile.name, rep.verdict);
// factur-x.xml  Factur-X / ZUGFeRD EN 16931 (COMFORT)  technically_valid
for (const i of rep.issues) console.log(i.severity, i.rule, i.location);
if (!rep.valid) process.exitCode = 1;

Validate an e-invoice

Official EN 16931 and XRechnung rules. Errors with rule id, message and location.

10 free checks a day · €1 free with a key · then €0.02 per check

Processed on servers in Germany (Hetzner, Falkenstein). The uploaded file is checked in memory and not stored.

Result

The verdict, profile, totals and every rule violation appear here.

How the PDF is checked

The attachment is found by name (factur-x.xml, zugferd-invoice.xml, xrechnung.xml) and returned in the attachment field. Since 2025 the XML is the leading part of a ZUGFeRD invoice in Germany (BMF FAQ, question 12a).

The XML is checked with EN 16931 1.3.17; the XRECHNUNG profile also gets KoSIT XRechnung schematron 2.6.0. PDF/A-3 conformance of the container is not checked: use veraPDF for that.

A plain PDF without an attachment returns 422 pdf_no_xml_attachment and is not charged.

Price in plain numbers

A prepaid balance, no subscription. Charged only for a successful answer; errors are free.

One validationper document€0.02
One e-invoice built from JSONXML or Factur-X PDF€0.04
PDF invoice → XRechnung / ZUGFeRDread €0.06 + build €0.04€0.10

A new key comes with €1 of free credit: 50 validations.

Pack€5 250 validations or 50 PDF conversions
Pack€20 1 000 validations or 200 PDF conversions

Credits never expire. No subscription.

Apple Pay, Google Pay or card on the monobank page. The key is created for you if you have none.

Your key and balance—

No key in this browser yet.

For developers

Same checks over REST and MCP. One header, JSON out.

validate
curl https://api.finekot.com/v1/e-invoice \
  -H "Authorization: Bearer fk_live_…" \
  -F file=@invoice.xml

# → {"valid":false,"errors":2,"issues":[{"rule":"BR-DE-15",…}]}
# X-Cost: 0.02
create
curl https://api.finekot.com/v1/e-invoice \
  -H "Authorization: Bearer fk_live_…" \
  -H "Content-Type: application/json" \
  -d '{"op":"create","output":"pdf","invoice":{…}}'

# → Factur-X PDF url + validation report · X-Cost: 0.04
MCP
claude mcp add --transport http finekot https://api.finekot.com/mcp --header "Authorization: Bearer fk_live_…"

API guides