DEV Community

eleata team
eleata team

Posted on

How to validate Peppol BIS 3 invoices in 5 lines of Python (or Node, or Go)

Starting September 2026 every B2B invoice in France must be e-invoiced (Peppol/Factur-X). Germany has mandated XRechnung for B2G since 2020. Italy has been on FatturaPA since 2019. Spain's Verifactu rolls out 2025-2026.

If you build accounting software, an ERP, or any e-commerce flow that touches EU customers, you'll likely need to validate these invoice formats at some point. The two main open-source Schematron engines are phive (by Philip Helger of the EN16931 working group) and Mustang (by Jochen StΓ€rk and the FNFE-MPE working group). Both are great. Both ship as Java JARs or web forms β€” no API, no SDKs.

I built a thin REST API on top of Mustang 2.23.0 that gives you what's missing: SDKs, GitHub Action, and async batch.

The 5-line version

# pip install eleata-peppol
from eleata_peppol import Client

client = Client(api_key=os.environ["ELEATA_KEY"])
result = client.validate(format="peppol-bis-3", xml=open("invoice.xml", "rb").read())
print(result.valid, result.errors)
Enter fullscreen mode Exit fullscreen mode

That's it. Same Schematron rules CEN/OpenPeppol publish β€” equivalent accuracy to the phive reference web form.

Node version

import { Eleata } from "@eleata/peppol";
import fs from "node:fs";

const client = new Eleata({ apiKey: process.env.ELEATA_KEY! });
const result = await client.validate({
  format: "xrechnung-2.x",
  xml: fs.readFileSync("./invoice.xml"),
});

if (!result.valid) console.error(result.errors);
Enter fullscreen mode Exit fullscreen mode

In CI (GitHub Action)

- uses: eleata/validate-xrechnung-action@v1
  with:
    files: ./invoices/**/*.xml
    api-key: ${{ secrets.ELEATA_KEY }}
Enter fullscreen mode Exit fullscreen mode

Add a validates-in-CI badge to your README. Break the build before you ship a broken invoice.

What's in the box

  • POST /v1/validate (sync) and /v1/validate/batch (async + webhook callback)
  • 4 formats: Peppol BIS 3, XRechnung 2.x, Factur-X 1.07.2 (PDF/A-3 hybrid extracted natively), UBL 2.1
  • Public shareable validation reports at /r/{id}
  • 50 anonymized real EU invoice fixtures (CC0)
  • Free 200 validations/month, no credit card

Honest about scope

This is not a full Peppol Access Point β€” Ecosio, B2BRouter, Pagero do that. We are only the validator-as-an-API layer. If you need to send invoices through the Peppol network, you still need an Access Point.

Repos public on github.com/eleata. Live demo at peppol.eleata.io.

Curious to hear from anyone using a different validator (xrechnung-tooling, validator-fhir, InvoiceNavigator). What pain points hit you first when integrating?

Top comments (0)