PRACTICAL GUIDE

Invoice validation: record the ruleset before comparing results

By ApiVect ·

Keep profiles, ruleset versions and synthetic fixtures together. Build useful regression tests and distinguish a replay from a fresh validation.

Invoice validation: record the ruleset before comparing results

An invoice that passed last month can produce different findings after a ruleset change. Before investigating a regression, establish what was tested: the exact fixture, selected profile and validation rules. A timestamp and a green HTTP status alone leave too much uncertainty.

Separate publication, mandatory use and your own observation

OpenPeppol's release notes list Peppol BIS Billing 3.0.21 as published on 20 May 2026 and mandatory to use from 17 August 2026. Those are different dates. Neither tells you when a particular service deployed its implementation or when your invoice was validated.

Record the upstream release reference separately from the ruleset returned by your validation run. ApiVect's current published example and deployed implementation identify the bundle as peppol-3.0.21_cen-1.3.16_20260911. Treat that complete string as a version identifier, not as an upstream publication date or a promise about a future run. Read the value returned each time.

Choose the profile deliberately

ApiVect supports peppol-bis-billing-3, en16931-ubl and ubl-2.1-schema, plus auto detection from supported document identifiers. Store both your requested profile and the returned profile. An automatic choice is useful information to preserve when investigating a result.

The schema-only profile checks XML structure; it does not establish EN16931 or Peppol business-rule conformance. ApiVect runs the business-rule stages only after the UBL 2.1 schema check succeeds. Read stages to see which checks actually ran, rather than assuming every response reached every layer.

Keep a small, private test record

Use versioned synthetic fixtures in your own test repository. Record the fixture identifier, exact byte hash, request time and response summary. Keep invoice contents, personal details and API keys out of logs. The following is an illustrative application-owned summary for a synthetic passing case. It is not a new ApiVect response format or a result from a live request:

{
  "fixture": "synthetic-invoice-baseline-v1",
  "requestedProfile": "peppol-bis-billing-3",
  "observed": {
    "profile": "peppol-bis-billing-3",
    "ruleset": "peppol-3.0.21_cen-1.3.16_20260911",
    "stages": ["ubl-2.1-xsd", "en16931-1.3.16",
               "peppol-bis-billing-3.0.21"],
    "valid": true,
    "findingCodes": [],
    "truncated": false
  }
}

For an invalid case, preserve each finding's code and severity alongside valid and truncated. ApiVect sanitises diagnostic messages and omits input-derived XML paths. Link a rule code to the matching official rule documentation; do not expect a message to reproduce your invoice values. A truncated finding list is not a complete list of failures.

Compare a baseline and a controlled change

Build a small regression set: a valid baseline, a structurally invalid document and a business-rule failure. Change one aspect at a time and document the intended outcome. For example, alter a required identifier in a synthetic copy while preserving the original fixture. Check whether the result reached business-rule validation before interpreting its findings.

After a ruleset update, compare versions, stages, validity and finding codes. Review changed outcomes against the upstream release notes and the specific rule. Avoid assertions against the entire diagnostic sentence or finding order unless your application has a documented reason to depend on them.

Distinguish a replay from a fresh validation

ApiVect can replay the stored response for the same body, profile and idempotency key within 24 hours. That replay is not a fresh execution under a newer ruleset. Give an intentionally new validation its own key. If an earlier request has an uncertain outcome, follow the documented replay procedure before deciding to create another operation.

A completed validation can return HTTP 200 with valid: false, and it consumes one validation unit. Plan your test runs accordingly. Validation also does not transmit an invoice through Peppol or determine its legal or tax treatment.

Build your invoice workflow with ApiVect

ApiVect provides the commercial validation tools behind this guide. Check the field contract and use the existing Python or Node.js examples to capture your own results.

Sources and further reading

Sources, version identifiers and product coverage checked on 6 October 2026. This is practical guidance, not a new standards release announcement.

← More news and guides · Browse the guide library