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.
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
- 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.
- 2An AI writes a converterThe AI writes a small program, map.py, that turns that kind of invoice into a Peppol e-invoice.
- 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.
- 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)
| Invoice | EU checker errors, per try | AI calls | AI cost | Time |
|---|---|---|---|---|
| Official CEN example invoice (CII format) | 6, 5, no invoice (crash), 1, then 0: approved | 5 | $0.030 | 66 s |
| Stripe test-mode invoice | Broken XML, 2, then 0: approved | 3 | $0.022 | 54 s |
| Billing-app spreadsheet export (CSV, European decimals, two VAT rates) | 0 on the first try: approved | 1 | $0.005 | 17 s |
| A caterer's PDF invoice (read by the AI, every number checked against the PDF with no AI) | 5, then 0: approved | 3 | $0.013 | 40 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.