eliDocs
Compliance

Ruleset versioning

How Beliq versions its validation rules, how to choose which ruleset runs via channels and the Beliq-Ruleset header, and how ruleset changes are classified and announced.

Beliq judges every invoice against pinned authority artifacts — Schematron and XSD bundles published by the standards bodies. Those artifacts have versions, and they change over time. Two independent version axes decide which rules apply to your document:

  • The spec axis — the standard the document itself declares (for example XRechnung 3.0, via its CustomizationID). Beliq detects this from the document; it is not something you set.
  • The ruleset axis — the specific version of the rule artifacts Beliq bundles to check that spec. This page is about the ruleset axis: how it is versioned, how you choose which version runs, and how changes are announced.

For the exact artifacts and versions in force right now, see Validation artifacts.

Ruleset channels

Ruleset channels

A channel is a symbolic name for “which ruleset version to run, per format”, so you never hard-code version numbers. There are two:

Channel What it selects
latest The current ruleset for each format. This is the default — used when a request sends no Beliq-Ruleset header.
previous The ruleset retained before the most recent breaking change, per format. Retention is gated on breaking changes (see How rulesets change), so a format with no breaking bump behind it has nothing to retain: there previous resolves to latest and the response flags rulesetFellBack. XRechnung resolves it to Schematron 2.5.0 with the 2026-01-31 severity table, and Factur-X (1.08) and the two France CTC overlays (1.3.1) to the packs they served before the 2026-09-10 bump. Peppol BIS Billing 3.0 falls back: its retained 3.0.20 is superseded and only an exact pin still reaches it.

The selectable channels are also listed by the keyless GET /v1/rulesets endpoint, in its channels array.

Choosing which ruleset runs

Choosing which ruleset runs

Ruleset selection resolves with a fixed precedence, highest first:

  1. The Beliq-Ruleset request header (per call) — a channel, or an exact per-format pin.
  2. Your organisation’s default channel.
  3. The system default, latest.

Organisation default

In the dashboard, Settings → Default ruleset channel sets the channel every API key in your organisation validates against when a request sends no Beliq-Ruleset header. Only owners and admins can change it. This is the org-wide baseline — leave it on latest unless you have a specific reason to pin.

It takes a channel (latest or previous) and nothing else. An exact version pin is a per-request header only; see Pinning an exact version for why.

Per request

Send a Beliq-Ruleset header with the channel name to override the org default for a single call:

curl -X POST "https://api.beliq.eu/v1/validate?format=auto" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/xml" \
  -H "Beliq-Ruleset: previous" \
  --data-binary @invoice.xml

The header is effective on POST /v1/validate only. /v1/generate, /v1/convert, and /v1/parse accept it but ignore it — they always run the current bundled artifacts and do not perform Schematron verdict selection. To see which artifact versions those routes used, read the X-Version-Block response header (compact JSON with the same version fields as the validate body).

Pinning an exact version

Instead of a channel, the header takes a comma-separated list of exact per-format pins, written <artifactKey>:<version>:

curl -X POST "https://api.beliq.eu/v1/validate?format=auto" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/xml" \
  -H "Beliq-Ruleset: facturx_schematron:1.08" \
  --data-binary @invoice.xml

The separator is a colon. A pin is not a key=value assignment, and one written that way is rejected with a 400 naming the expected shape.

A few things worth knowing before you pin:

  • A pin and a channel are mutually exclusive. Send one or the other, not both.
  • Artifact keys come from GET /v1/rulesets — the versionKey on each entry of rulesets[], and the key on each entry of artifacts[]. They are stable identifiers like facturx_schematron or xrechnung_schematron, not format names.
  • Up to 32 pins per request, and naming the same key twice with different versions is an error.
  • An unavailable version returns 422, with the versions that are available listed in the error message. Retention is bounded, so a version you pinned today will eventually stop being served — see rulesetSunsetsOn below.
  • A pin is per request only. The organisation default takes a channel, not a pin, so pinning an exact version across every call means sending the header every time. That is deliberate: a channel keeps meaning something after the next bump, whereas an org-wide exact pin would quietly stop resolving the day that version retires.

Prefer previous if what you want is “keep today’s rules while I adapt” — it needs no version numbers and survives the next bump. Reach for a pin when you need one specific artifact version, typically to reproduce an earlier verdict exactly. A pin is also the only thing that keeps working once an authority makes the successor mandatory: see When the authority supersedes a retained ruleset.

Seeing which ruleset ran

Seeing which ruleset ran

Every response tells you exactly what was applied:

Field / header What it reports
Beliq-Ruleset-Resolved (response header) The ruleset that was actually applied to the request.
rulesetChannel (body) The channel applied — latest or previous — present when a channel was selected via the header, or when your org default is previous.
rulesetFellBack (body) true when previous was requested and the format had no retained ruleset for the channel to reach, so the request fell back to latest. Either nothing is retained, or what is retained has been superseded. Present only alongside rulesetChannel.
rulesetSunsetsOn (body) The date the retained ruleset serving this request stops being served, when one did. Retention is bounded, so a pin is not permanent: after this date an exact pin returns 422. It bounds the pin, not the channel, which can stop reaching the version earlier.

For the concrete artifact versions and checksums that judged your document, the response also carries the per-format version fields and the rulesetSha256 fingerprint. See Validation artifacts → API response metadata and Verify a hash.

How rulesets change

How rulesets change

Beliq does not auto-update validation artifacts — every version bump is reviewed and tested before rollout. Changes fall into two classes:

  • Safe — a false-positive fix, a rule relaxation, a code-list addition, a refactor. A document that passed before still passes. Safe changes roll straight into latest, with no retained previous.
  • Breaking — a change that can make a previously-valid document newly invalid. Breaking changes are announced on the day they take effect at the latest, and the outgoing ruleset stays selectable for at least 6 months from that day, so you can pin to it while you adapt.

The public record of what changed and when is the Validation artifacts → Version changelog. Beliq also runs a nightly content-SHA drift check against every pinned artifact and opens a tracking issue if an authority re-publishes an artifact without bumping its version.

Beliq announces a bump ahead of the day it takes effect where the authority’s own timetable allows one, and there is no guaranteed period: OpenPEPPOL made BIS Billing 3.0.21 mandatory 89 days after publishing it, and KoSIT ships XRechnung Schematron with no advance notice at all. What is guaranteed is the 6 months on the way out. When a bump is announced ahead, it is machine-readable: GET /v1/rulesets lists it under scheduledChanges with the version it moves to, the date it takes effect, and the date the outgoing ruleset stops being served at all. rulesets[] keeps reporting the outgoing version until the date, because that is what your documents are still judged against. Every artifact that judges a publicly-carried claim is listed, including the overlays that run without being any format’s versionKey, so polling the endpoint is enough to find out ahead of the date rather than on it.

When the authority supersedes a retained ruleset

Retention has two halves and they do not always end on the same day.

An authority can make a new ruleset version mandatory on its network, at which point a document built to the version before it no longer clears, whatever Beliq retains. From that date previous stops reaching the retained version: a channel asks Beliq to choose a ruleset for you, and Beliq will not choose one the receiving corner already rejects. Requests on previous resolve latest and set rulesetFellBack: true.

The exact pin is unaffected and keeps resolving until the version’s retirement date. That is the point of the distinction: a pin names a version, so it is the right tool for reproducing an earlier verdict after the network has moved on, which is a thing you may legitimately need to do. A channel is the wrong tool for it.

Peppol BIS Billing 3.0 is the case in force today. OpenPEPPOL made Schematron 3.0.21 mandatory on 2026-08-17, so previous no longer reaches 3.0.20, while peppol_bis_billing_schematron:3.0.20 stays pinnable until 2027-03-03. No other authority Beliq carries publishes a mandatory date, so XRechnung, Factur-X and the France CTC overlays keep resolving previous to their retained packs for the full window.

Related
  • Validation artifacts — the exact artifacts, versions, sources, and checksums in force now.
  • Verify a hash — reproduce rulesetSha256 and cross-check the ruleset against the public catalog.