Peppolsmith

About Peppolsmith

EU e-invoices from the billing data you already have

Peppolsmith turns the invoices your billing tool already produces into Peppol e-invoices, the structured format businesses in Belgium now have to use. An AI writes the converter and fixes it until the official EU checker finds no errors. Then two more checks, which the AI can't touch, make sure the e-invoice still says what you actually billed. Only then is anything released.

Try itSource on GitHub

The problem

Since 1 January 2026, Belgian businesses must send each other structured e-invoices over the Peppol network: a precise XML format that software can read, instead of a PDF.

Most small billing tools don't produce that. They export PDFs, spreadsheets (CSV) or their own data format (JSON). Someone has to write a converter, and a converter that is slightly wrong sends wrong invoices.

How it works

  1. 1You give it an invoiceOne invoice as you already have it: a PDF, a Stripe invoice, a spreadsheet export or a CII e-invoice. For a PDF, every number the AI reads is checked against the PDF with no AI.
  2. 2An AI writes a converterThe AI writes a small program, map.py, that turns that kind of invoice into a Peppol e-invoice.
  3. 3It runs locked, and fixes itselfThe program runs in a locked CreateOS sandbox with no internet. The official EU checker lists every error; the AI reads them and fixes its own code, up to 8 tries.
  4. 4Released only if 3 checks passThe EU rules, the totals and the company IDs. If any check fails, nothing is released, and the page says exactly why.

The three checks

  • Follows the official EU e-invoice rulesThe CEN EN16931 rules and the Peppol BIS Billing 3.0 rules, run by the official checker inside the sandbox.
  • The totals match the original billLines, net total, VAT per rate and amount due must equal what the customer was actually billed. No AI is involved in this check.
  • Every company ID comes from the original invoiceEvery company name, VAT number, Peppol ID and bank account must appear in the original invoice or the declared settings. Nothing invented. No AI is involved in this check.

Why the extra two checks matter

The official checker only checks that an invoice agrees with itself. It can't know what you actually billed.

An example from our tests: we take an approved e-invoice and drop its 10% discount, keeping every number consistent. Every official rule still passes. But the customer would be charged €614.68 instead of €553.21.

Peppolsmith compares the e-invoice with the original bill, sees the difference, and holds it back.

The discount dropped

Official EU rules
0 errors
The bill says
€553.21
The e-invoice says
€614.68

Held back

What you get

  • The e-invoiceThe Peppol XML file, ready for your Peppol access point.
  • A certificateWhich rules ran (with their versions and file hashes), the totals compared, the IDs traced, and which AI and sandbox were used.
  • A reusable converterThe approved converter turns the next invoice of the same kind in about 1.7 seconds, with no AI call.

Results from our recorded runs (17 Oct 2026)

InvoiceEU checker errors, per tryAI callsAI costTime
Official CEN example invoice (CII format)6, 5, no invoice (crash), 1, then 0: approved5$0.03066 s
Stripe test-mode invoiceBroken XML, 2, then 0: approved3$0.02254 s
Billing-app spreadsheet export (CSV, European decimals, two VAT rates)0 on the first try: approved1$0.00517 s
A caterer's PDF invoice (read by the AI, every number checked against the PDF with no AI)5, then 0: approved3$0.01340 s
  • Trying to fool the checks. We planted three converter bugs into an approved e-invoice: amounts in cents treated as euros, a dropped discount, and an invented buyer Peppol ID with a valid checksum. Each one passes every official rule, and each one is held back by the totals check or the ID check. The home page runs these live.
  • Converting with the AI off. The approved converters ran on a second Stripe test invoice and a second spreadsheet export. Both were approved in about 1.7 s with 0 AI calls.
  • Honest limits of the evidence. Across our 47 test runs, all 35 e-invoices that passed the official rules also matched their original, so the extra checks never caught a real AI slip; the planted bugs are the evidence that they would. Results vary from run to run: Stripe invoices reached approval in 13 of 14 runs, CSV exports in 6 of 6, PDFs in 6 of 6, and the hard official CEN example in 13 of 24 (most misses came before we improved the AI's feedback). Nothing was ever released without all three checks passing.

Declared settings

An invoice doesn't always carry everything a Peppol e-invoice needs, such as the Peppol IDs of seller and buyer. Those values come from declared settings for each format, and the ID check accepts them alongside the invoice itself. All of them are fictional, in valid formats.

Stripe invoices (JSON)

Seller name
Atelier Lumière BV
Seller VAT
BE0847193149
Seller endpoint scheme
0208
Seller endpoint ID
0847193149
Seller IBAN
BE71096123456769
Seller street
Rue de Flandre 12
Seller postcode
1000
Seller city
Brussel
Seller country
BE
Buyer endpoint scheme
0208
Buyer endpoint ID
0764221032
Buyer buyer reference
KAAI-TAPROOM-OPENING

CII e-invoices (XML)

Seller endpoint scheme
9930
Seller endpoint ID
DE1111111
Seller contact name
Accounts receivable
Seller contact telephone
+49 30 1111111
Seller contact email
invoices@seller.example
Buyer endpoint scheme
0088
Buyer endpoint ID
1111111111
Buyer buyer reference
SUBSCR571

Billing exports (CSV)

Seller name
Traiteur Vanneste BV
Seller VAT
BE0731602803
Seller endpoint scheme
0208
Seller endpoint ID
0731602803
Seller IBAN
BE68539007547034
Seller street
Groentemarkt 7
Seller postcode
9000
Seller city
Gent
Seller country
BE
Buyer endpoint scheme
0208
Buyer endpoint ID
0649375210
Buyer buyer reference
PO-2026-118

Built with

  • CreateOS Sandbox: the locked VM where the AI's code and the EU checker run, with the network off.
  • Stripe Projects: set up the whole stack from the Stripe CLI, including the AI model's key.
  • Qwen3-Coder 480B, through Featherless: the AI that writes and fixes the converter.
  • Vercel and Next.js: host and build this site.

Limits

  • Passing the CEN and Peppol rules is not delivery over the Peppol network, which needs an access point.
  • The sample invoices are labelled in the app: one official CEN example (unmodified), Stripe test-mode invoices we created, and CSV rows we wrote. Seller and buyer IDs are fictional; the CEN example's seller contact is our declared setting, because the example leaves it empty and Peppol's German rules require one.
  • Live runs are limited to one at a time and 60 a day, so the public site can't run up the AI bill.

Try itSource on GitHub