# Peppol BIS Billing 3.0 validator

Source: https://veriport.io/guides/peppol-bis-billing-3-validator (published 2026-10-28)

`POST https://veriport.io/api/v1/einvoice/validate` runs a Peppol BIS Billing 3.0 document through the same three layers an access point checks before it sends: the UBL 2.1 XML schema, the CEN EN 16931 business rules (release 1.3.16) and OpenPeppol's PEPPOL-EN16931-UBL rules (release 3.0.21), and answers with the published rule ids and messages. On the evidence set, this check and the KoSIT validator running the same Peppol rules named the same rules on every file. 5 calls a check; 4 free checks a day without a key on the [free validator](/tools/peppol-validator).

- Belgium has required structured B2B e-invoices over Peppol since 1 January 2026; the format is Peppol BIS Billing 3.0.
- The rules are evaluated in-process from the files OpenPeppol and CEN publish, vendored verbatim with their SHA-256; nothing is reimplemented by hand.
- A Belgian participant is addressed by its enterprise number under scheme 0208; PEPPOL-COMMON-R043 checks its mod-97 key.
- The validator checks; it does not send. Sending needs a certified Peppol access point (Recommand, e-invoice.be and others).

## What is checked, in order

- **XML schema**: UBL 2.1 Invoice or CreditNote (the OASIS schemas the KoSIT configuration ships). An element out of order or unknown to UBL fails here as `XSD` with the line.
- **EN 16931**: the CEN business rules (BR-*, BR-CO-* arithmetic, the VAT category rules, BR-DEC-* decimals, BR-CL-* code lists, UBL-CR-* syntax).
- **Peppol BIS 3.0**: PEPPOL-EN16931-R* (one note, a buyer reference or an order reference, the electronic addresses, no empty elements…), the code lists (PEPPOL-EN16931-CL*), PEPPOL-COMMON-* identifier checks and the national rules OpenPeppol carries (DE-R, NL-R, NO-R …).
- **Veriport’s own practice checks**, as warnings only and marked `source: "veriport"`: the Belgian structured communication +++123/4567/89002+++ (mod 97), Belgian rates 21/12/6 %, an enterprise number that differs from the VAT number.

## Does it agree with the reference validator?

The evidence script (`pnpm validate:official`, published on the [product page](/einvoice-api)) writes ten Belgian Peppol samples through the API and runs them through the KoSIT validator configured with the same UBL schema, CEN rules and PEPPOL-EN16931-UBL 3.0.21 (compiled with SchXslt), then through this validator. All ten were accepted by both, and broken documents (a wrong 0208 key, two notes, a misordered element, a unit code outside the code list) were rejected by both with the same rule ids.

## The request and the answer

Send the XML as the raw body or as the `file` field of a multipart form. The answer says `valid`, the profile it detected, and lists `errors` and `warnings` with the rule id, the XPath of the element and the published message.

```bash
curl -X POST "https://veriport.io/api/v1/einvoice/validate" \
  -H "Content-Type: application/xml" \
  --data-binary @invoice.xml
```

```json
{
  "valid": false,
  "profile": "peppol-bis",
  "format": "peppol-bis",
  "syntax": "ubl",
  "container": "xml",
  "errors": [
    {
      "rule": "PEPPOL-COMMON-R043",
      "severity": "fatal",
      "path": "/ubl:Invoice/cac:AccountingSupplierParty/cac:Party/cbc:EndpointID",
      "message": "Belgian enterprise number MUST be stated in the correct format.",
      "source": "peppol-ubl"
    }
  ],
  "warnings": []
}
```

> A report is charged whether the document is valid or not; an unreadable file (not XML, a PDF without embedded data) is refused with 422 `einvoice_unreadable` and costs nothing.

## Creating Peppol BIS files instead

`POST https://veriport.io/api/v1/einvoice/create` with `"format": "peppol-bis"` writes Peppol BIS Billing 3.0 for a Belgian seller (v1): enterprise-number endpoints under 0208 derived from the VAT number when you give none, the structured communication as payment reference, the franchise mention for the small-business scheme, intra-Community supplies and the EU reverse charge. The file is checked by these rules before it is returned (20 calls).

## Questions

### Is this the official Peppol validator?

No: it runs the official rule files, published by OpenPeppol and CEN, in a validator of its own, and the evidence compares it with the KoSIT validator file by file. The Peppol network itself validates at the sending access point.

### Are the Belgian rules included?

The Peppol release carries no Belgian national rule set; the Belgian specifics are the 0208 identifier check (PEPPOL-COMMON-R043, published) and Veriport’s own checks of Belgian practice, reported as warnings.

### Can it check a CII Peppol file?

Yes: a CII document claiming Peppol BIS 3.0 is checked with the CEN CII rules and PEPPOL-EN16931-CII 3.0.21; UBL is what Belgian access points exchange.

### Is my file stored?

No. It is read in memory for the request; the usage row keeps the endpoint and the profile, never content.

## Read next

- [Free Peppol validator](https://veriport.io/tools/peppol-validator)
- [The e-invoice API: formats, evidence, prices](https://veriport.io/einvoice-api)
- [EN 16931 rules explained](https://veriport.io/guides/en-16931-business-rules-explained)
- [Reference: create, validate, parse](https://veriport.io/docs/einvoice)

## Sources

- Peppol BIS Billing 3.0 — specification, identifiers, code lists and rules — https://docs.peppol.eu/poacc/billing/3.0/ (2026-10-28)
- Peppol BIS Billing 3.0 release 3.0.21: PEPPOL-EN16931-UBL.sch and the CEN files it ships — https://github.com/OpenPEPPOL/peppol-bis-invoice-3/tree/3.0.21/rules/sch (2026-10-28)
- EN 16931 validation artefacts 1.3.16 (UBL and CII schematron, the business rules BR-*) — https://github.com/ConnectingEurope/eInvoicing-EN16931/releases/tag/validation-1.3.16 (2026-10-28)
- SPF BOSA — e-invoicing between Belgian businesses, structured (Peppol BIS) since 1 January 2026 — https://efacture.belgium.be/fr (2026-10-28)
- KoSIT validator (the reference validator for XRechnung), release 1.6.3 — https://github.com/itplr-kosit/validator (2026-10-28)
