Automation Blog Pricing Contact
POST /v1/validate/ubl

UBL Validation API

The InvoiceXML UBL validation API validates any UBL 2.1 invoice or credit note against the UBL XSD schema, EN 16931 Schematron, and — where the CustomizationID declares a Peppol or national CIUS profile — the corresponding overlay rules. The same multi-layer validation that a Peppol access point runs before accepting your document for network delivery.

Drop your UBL XML here

or browse files to upload

POST /v1/validate/ubl · Accepted: UBL 2.1 Invoice or CreditNote XML · Max 20 MB

Submit any UBL 2.1 Invoice or CreditNote XML. The API reads the CustomizationID element to detect your Peppol or national CIUS profile and automatically runs the correct XSD schema, EN 16931 Schematron, and profile-specific overlay rules. Every rule violation returned with its rule ID, severity, and the validation layer it came from — en16931 or the specific CIUS that fired it.

Validate UBL REST API Request

A single endpoint handles all UBL invoice and credit note profiles — document type and CIUS are detected from the submitted XML automatically:

Request
$ curl -X POST https://api.invoicexml.com/v1/validate/ubl \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "[email protected]"

# Also accepts UBL CreditNote documents
$ curl -X POST https://api.invoicexml.com/v1/validate/ubl \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "[email protected]"

Validate UBL API Response

Both valid and invalid documents return HTTP 200. The detectedProfile field tells you which CIUS the API validated against — critical when you are processing invoices from multiple trading partners who may declare different profiles in their CustomizationID. The documentType field confirms whether the submission was treated as an Invoice or CreditNote.

The layer field on each error distinguishes EN 16931 violations from Peppol BIS or CIUS-specific violations. A layer: peppol-bis error means your invoice satisfies the European standard but fails the Peppol network overlay — it will be rejected by your access point even though it is technically EN 16931 compliant.

Valid UBL Response

Response — valid invoice
// 200 OK
{
  "valid": true,
  "detail": "Your UBL invoice is Peppol BIS 3.0 compliant and meets the EN 16931 specifications.",
  "data": {
    "schemaValid": true,
    "schematronValid": true,
    "conformanceLevel": "EN16931",
    "detectedProfile": "Peppol BIS Billing 3.0",
    "documentType": "Invoice",
    "customizationId": "urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0"
  }
}

Invalid UBL Response

Response — invalid invoice
// 200 OK
{
  "valid": false,
  "detail": "Validation failed with 3 error(s)",
  "data": {
    "detectedProfile": "Peppol BIS Billing 3.0",
    "documentType": "Invoice",
    "customizationId": "urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0"
  },
  "errors": {
    "xml": [
      "[PEPPOL-EN16931-R004] Invoice type code should be 380 for a standard invoice.",
      "[BR-CO-14] Invoice total VAT amount must equal the sum of VAT breakdown amounts.",
      "[BR-61] If the payment means code is 30 or 58, a payment account identifier must be present."
    ],
    "friendly": [
      {
        "rule": "PEPPOL-EN16931-R004",
        "layer": "peppol-bis",
        "message": "The InvoiceTypeCode value is not 380. Peppol BIS 3.0 requires type code 380 for standard invoices. Use 381 for credit notes submitted as Invoice documents." },
      {
        "rule": "BR-CO-14",
        "layer": "en16931",
        "message": "The invoice total VAT amount does not match the sum of VAT breakdown amounts. Check that all tax subtotals are consistent with the TaxTotal." },
      {
        "rule": "BR-61",
        "layer": "en16931",
        "message": "Payment means code 30 or 58 requires a PaymentMeans/PayeeFinancialAccount/ID (IBAN). Add the payee IBAN to the payment means block." }
    ]
  }
}

What the UBL validation API checks

UBL 2.1 XSD Schema

Validates the document against the OASIS UBL 2.1 XSD schema — UBL-Invoice-2.1.xsd for Invoice documents and UBL-CreditNote-2.1.xsd for CreditNote documents. Catches structural errors in the cac: and cbc: component hierarchy, incorrect data types in monetary amounts and quantities, missing required elements, and namespace declaration errors. The document type is detected from the root element before the correct schema is applied.

EN 16931 Schematron

Validates all 200+ EN 16931 business rules against the UBL syntax. Includes the UBL-specific rule implementations: cac:TaxTotal/cbc:TaxAmount arithmetic (BR-CO-14), PaymentMeans account identifier rules (BR-61, BR-62), party address requirements (BR-07, BR-08), and VAT category conditional rules (BR-AE-05 through BR-E-02). Errors from this layer indicate European standard non-compliance.

Peppol BIS and National CIUS Rules

When the CustomizationID declares a Peppol or national CIUS profile, the API automatically runs the corresponding overlay Schematron on top of EN 16931. Peppol BIS 3.0 rules (PEPPOL-EN16931-Rxx codes) enforce network-specific constraints like invoice type code values and endpoint identifier schemes. National CIUS rules for NLCIUS, EHF, and PINT apply their own additional requirements. Errors from this layer will cause Peppol access point rejection even if EN 16931 passes.

CustomizationID Profile Detection

Reads the cbc:CustomizationID element to identify the declared CIUS and routes the document to the correct validation stack. A plain EN 16931 UBL invoice, a Peppol BIS 3.0 invoice, an NLCIUS invoice for Dutch public sector, and an EHF invoice for Norway all declare different CustomizationID values and require different Schematron artefacts. The API handles all of them from a single endpoint — no profile parameter required.

Response schema

Both valid and invalid documents return HTTP 200. The detectedProfile and customizationId fields confirm exactly which CIUS was validated — useful when processing invoices from trading partners across Belgium, Netherlands, Norway, and other Peppol markets who may declare different profiles. The layer field on each error tells you whether to fix an EN 16931 data problem or a Peppol network-specific configuration issue. Create/convert endpoints return HTTP 400 with the same errors structure on validation failure.

Field Type Description
Always present
validbooleanPrimary flag to branch on. true when the document passes UBL XSD, EN 16931 Schematron, and all applicable CIUS overlay rules.
detailstringHuman-readable summary including the detected profile name, e.g. "Your UBL invoice is Peppol BIS 3.0 compliant…"
data.conformanceLevelstringEN 16931 conformance level, e.g. EN16931.
data.detectedProfilestringHuman-readable profile name derived from the CustomizationID, e.g. Peppol BIS Billing 3.0, NLCIUS, EHF Billing 3.0, PINT.
data.documentTypestringInvoice or CreditNote — detected from the XML root element.
data.customizationIdstringFull CustomizationID URI read from the submitted XML, e.g. urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0.
Valid only
data.schemaValidbooleanUBL 2.1 XSD schema check passed for the detected document type.
data.schematronValidbooleanAll EN 16931 and applicable CIUS Schematron rules passed.
Invalid only
errors.xmlstring[]Raw Schematron messages with rule codes, e.g. "[PEPPOL-EN16931-R004] Invoice type code should be 380 for a standard invoice."
errors.friendlyobject[]Plain-language error objects for UI display.
friendly[].rulestringRule identifier, e.g. PEPPOL-EN16931-R004, BR-CO-14, BR-61.
friendly[].layerstringValidation layer: en16931 (European standard), peppol-bis (Peppol BIS overlay), nlcius, ehf, or pint for national CIUS rules.
friendly[].lineint?Invoice line item number from the InvoiceLine sequence, or null for document-level errors.
friendly[].messagestringHuman-readable error description referencing the UBL element concept in plain language — not the cac:/cbc: XPath.

Integrate UBL validation into your workflow

REST API

Call POST /v1/validate/ubl from any language. Invoice and CreditNote documents handled automatically. Returns structured JSON in under 2 seconds. Use the detectedProfile field to log which CIUS your Peppol trading partners are submitting — Belgium, Netherlands, Norway, and international partners often declare different profiles and a mismatch is a frequent source of silent Peppol delivery failures.

API docs

Zapier / Make / n8n

Validate UBL invoices received from your Peppol access point before they enter your AP system. Branch on the layer field in the friendly errors array — a peppol-bis error means a Peppol network configuration issue your supplier needs to fix, while an en16931 error means a data problem in the invoice itself. Route each type to a different notification workflow.

Automation integrations

CI/CD Pipeline

Peppol BIS releases CIUS updates quarterly. When OpenPeppol publishes a new version, the InvoiceXML validation rules update automatically — your pipeline catches PEPPOL-EN16931-Rxx regressions before non-compliant invoices reach your Peppol access point and generate confusing network rejection codes that have no obvious connection to the generation code change that caused them.

View cURL example

Complete UBL Toolkit

Everything you need to create, convert, validate, and preview UBL invoices — via REST API or online.

Build a validated UBL 2.1 XML from structured data — Peppol BIS Billing 3.0 compliant.

Validate UBL XML against EN 16931 and Peppol BIS Billing 3.0 Schematron rules.

Convert any PDF invoice into a Peppol-compliant UBL 2.1 XML using AI extraction.

Render a UBL XML as a human-readable PDF for review and approval.

Frequently Asked Questions

Which Peppol and UBL profiles does the validation API support?

The API automatically detects the profile from the CustomizationID element and applies the matching CIUS Schematron rules. Supported profiles include plain EN 16931 UBL, Peppol BIS Billing 3.0, NLCIUS (Netherlands), EHF Billing 3.0 (Norway), and PINT (Peppol International). Both Invoice and CreditNote document types are supported for all profiles.

Does the API validate UBL CreditNote documents as well as invoices?

Yes. UBL defines Invoice and CreditNote as separate document types with slightly different element constraints. The API detects the root element automatically — Invoice or CreditNote — and applies the correct XSD schema and Schematron rules for each. CreditNote-specific rules around negative amounts, reason codes, and document references are validated correctly.

Why does my UBL invoice pass EN 16931 validation but get rejected by the Peppol network?

EN 16931 and Peppol BIS 3.0 are two different validation layers. A document can satisfy all 200+ EN 16931 business rules and still fail the Peppol BIS overlay rules — for example PEPPOL-EN16931-R004 (invoice type code must be 380 for a standard invoice) or rules requiring specific Peppol endpoint identifier schemes. The InvoiceXML UBL validation API runs both layers automatically when the CustomizationID declares a Peppol profile, so pre-submission validation catches Peppol-specific failures before they reach the access point.

Ready to automate your invoices?

Start your 30-day free trial. No credit card required.

Get Started