eliDocs
API Reference

GET /v1/rulesets

GET/v1/rulesets

Public, keyless reference for the ruleset versions and artifact hashes Beliq pins per supported format. No API key, no quota cost.

GET /v1/rulesets is the machine-readable mirror of what the docs and landing page publish: the active ruleset version for each supported format, the ruleset channels you can pin, any announced ruleset change that has not taken effect yet, and the ruleset-hash catalog you cross-check a validation result against. It is the discovery counterpart to validation artifacts and verify a hash.

Access

Access

This endpoint is public. It takes no API key, does not count against your monthly quota, and touches no database or engine. It stays IP-rate-limited like other keyless traffic. The response is a constant projection of the coverage data Beliq ships, so it is safe to poll and cache.

rulesets.sh
curl https://api.beliq.eu/v1/rulesets

The endpoint accepts no query parameters.

Response

Response

A 200 returns the standard success envelope with four arrays under data:

{
  "success": true,
  "data": {
    "rulesets": [ /* one entry per publicly-supported format */ ],
    "channels": [ /* selectable ruleset channels */ ],
    "scheduledChanges": [ /* announced bumps not yet in force */ ],
    "artifacts": [ /* the ruleset-hash catalog */ ]
  }
}

rulesets[]

One entry per format Beliq supports on the API surface. Each entry separates the two version axes: specVersion is the format spec a document declares; rulesetVersion is the artefact release Beliq pins for that format, and the only axis that can move under you.

The entry is a pin, not a per-document prediction. A format with profiles picks its Schematron arm from the document’s own CustomizationID, so which artefacts ran for one document is what that response’s rulesetArtifacts lists. Verify against that, not against the entry.

Field Type Meaning
format string Format identifier, for example xrechnung, factur-x, peppol-bis.
label string Human-readable format name.
standard string The standard the format derives from, for example EN 16931 CIUS - UBL & CII.
authority string The body that publishes the ruleset, for example KoSIT.
region string The country or region the format serves.
specVersion string Spec/display axis: the format spec version a document declares.
rulesetVersion string Ruleset/artefact axis: the artefact release Beliq pins for the format. The audit anchor.
rulesetArtefact string Provenance label for the artefact, for example XRechnung Schematron.
versionKey string Stable handle for the ruleset axis. Joins an entry to its rows in artifacts[].
verificationTier string | null How rigorously the format’s validation is backed. One of conformance-verified, builder-round-trip, xsd-structural, or null (only for a format that runs no validation artifact).
rulesProvenance string Where the business rules come from: authority-conformance, authority-artifact, community, beliq-authored, or none.
verificationBadge string The public trust badge derived from rulesProvenance: authority-verified, independently-rule-checked, or structure-checked. The same label the coverage cards show, so you can render it without re-implementing the mapping.
releaseDate string | null Release date of the pinned artefact, YYYY-MM-DD, or null.
repo string | null Source repository of the authority artefact, or null.
tag string | null Release tag in that repository, or null.
retained object[] Versions of this format’s artefact still on disk but no longer served, oldest first. Empty for a format whose artefact has never had a breaking bump. See retained[] below.

retained[]

What is still reachable after a breaking bump, and for how long. Every entry is a version Beliq once served as latest and has kept on disk since, so an exact Beliq-Ruleset: <versionKey>:<version> pin still reproduces a verdict issued under it.

A format inside a notice period has an empty retained[]: the outgoing release is still what rulesetVersion names, so there is nothing behind it yet.

Field Type Meaning
version string The retained rulesetVersion. Pin it as Beliq-Ruleset: <versionKey>:<version>.
releaseDate string | null YYYY-MM-DD the authority released this version, or null if it publishes none.
servingFrom string YYYY-MM-DD Beliq started serving this version as latest.
retainedUntil string | null YYYY-MM-DD after which this version is no longer served at all, or null if nothing retires it. The last day an exact pin resolves; after it, the pin returns a 422.
supersededMandatoryOn string | null YYYY-MM-DD the authority made this version’s successor mandatory, or null if it published none. Once it has passed, Beliq-Ruleset: previous no longer resolves to this version.

The two dates are separate promises and they close on different days. retainedUntil is Beliq’s, about the files: until then the exact pin works. supersededMandatoryOn is the authority’s, about the network: after it, a document built to this version is rejected by the receiving corner, so previous stops choosing it for you and the validation response sets rulesetFellBack: true. A pin names a version; previous asks Beliq to choose one, and Beliq will not choose a ruleset the network already rejects. See when the authority supersedes a retained ruleset.

Peppol BIS Billing 3.0 is where the two come apart today: supersededMandatoryOn is 2026-08-17 and retainedUntil is 2027-03-03, 6.5 months later. Plan migrations against retainedUntil, and pin the exact version rather than the channel if what you need is to reproduce a verdict after the authority has moved on.

retainedUntil here is the same date scheduledChanges[] reports as retiredOn while a bump is pending. The two blocks answer different halves of the same question: scheduledChanges[] covers a bump that has not happened yet, retained[] covers the versions the bumps that already happened left behind.

verificationTier reflects how the format is backed, not its compliance status:

  • conformance-verified: verdict parity against the authority’s own per-rule test corpus.
  • builder-round-trip: a real business-rule Schematron runs, evidenced by builder round-trips and the authority’s positive samples (no per-rule corpus published upstream).
  • xsd-structural: structural XSD validation only; no machine-readable business rules exist for the format.

channels[]

The ruleset channels selectable via the Beliq-Ruleset header on POST /v1/validate. Static: the two channels exist regardless of format.

Field Type Meaning
id string latest or previous.
label string Display label.
description string When the channel applies, including the fallback behaviour of previous.

scheduledChanges[]

A ruleset bump Beliq has announced and vendored but is not serving yet. Until effectiveOn, rulesets[] keeps reporting the outgoing version, because that is the ruleset your documents are actually judged against. This block is how you see the change coming.

Only a breaking bump appears here, and only one announced ahead of the day it takes effect: a safe bump rolls straight into latest, and a breaking bump announced on the day it lands has no future date to publish (see ruleset versioning). So the array is empty most of the time, and a row exists only between the announcement and the effective date.

A row appears for every artefact that judges a claim Beliq carries on this surface, not only for the artefacts named as a versionKey in rulesets[]. The two France CTC overlays are the case that distinguishes those: they judge Factur-X extended-ctc-fr documents and any request passing franceCtc=true, and they are listed in artifacts[] below, but no rulesets[] entry names either as its versionKey.

Field Type Meaning
versionKey string The artefact whose ruleset changes. Joins to the matching rulesets[] entry.
formats string[] The format identifiers this artefact judges, for example ["factur-x"]. Several formats can share one artefact; the bump happens once. Wider than “formats naming it as versionKey”: an overlay running under a format’s profiles moves that format’s verdicts too.
capabilities string[] The capability identifiers this artefact judges, for example ["franceCtc"]. A bump can reach you through a capability and no format at all, so read both lists.
from string The rulesetVersion serving today.
to string The rulesetVersion that starts serving on effectiveOn.
effectiveOn string YYYY-MM-DD. The date latest moves from from to to.
noticePublishedOn string | null YYYY-MM-DD the change was announced, or null if not recorded yet.
retiredOn string | null YYYY-MM-DD after which from is no longer served at all, or null if nothing retires it.

Nothing is scheduled today, so the array above is empty. While a bump is pending, a row looks like this:

{
  "versionKey": "france_ctc_schematron",
  "formats": ["factur-x"],
  "capabilities": ["franceCtc"],
  "from": "1.3.1",
  "to": "1.4.0.03",
  "effectiveOn": "2026-11-20",
  "noticePublishedOn": "2026-08-20",
  "retiredOn": "2027-05-16"
}

retiredOn is the later of the two dates here and the one to put in your calendar. effectiveOn changes what the default gives you, and you can opt out of that by pinning Beliq-Ruleset: previous or an exact version. retiredOn is when the exact-pin half of that escape hatch closes: after it, a pin on from returns a 422.

The channel half can close earlier, and retiredOn does not bound it. previous stops reaching from on retiredOn or on the authority’s own mandatory date for to, whichever comes first, and then resolves to the current ruleset and sets rulesetFellBack: true. The two dates are 5.5 months apart on Peppol BIS Billing 3.0 today: 3.0.20 left the channel on 2026-08-17 and stays pinnable until 2027-03-03. Plan the migration against retiredOn, and pin the exact version rather than the channel if what you need is to reproduce a verdict after the authority has moved on.

The same sunset date reaches you per request as rulesetSunsetsOn in a POST /v1/validate body, but only once you are actually pinned to the outgoing ruleset. This block is the earlier signal: it is here from the announcement onwards, whether or not you have pinned anything.

artifacts[]

The ruleset-hash catalog: every rule artifact that can run for a publicly-supported format, with the SHA-256 of its exact file bytes. This is the allowlisted public subset of the engine’s registry. Formats Beliq carries on no public surface run pinned artifacts that are intentionally omitted here.

Field Type Meaning
key string Artifact key, for example en16931_cii_schematron. Usually matches a ruleset entry’s versionKey, but not always: the base Schematron, the EN 16931 syntax schemas, a format’s severity configuration and the French CTC overlays all run without being any format’s versionKey. Cross-check on all three fields, never on key alone.
version string The registry label for the exact file. It may carry a format prefix, for example XRechnung-2.6.0 for the pack a ruleset entry names as 2.6.0 in rulesetVersion.
fileSha256 string Lowercase-hex SHA-256 of the artifact file, 64 characters.

A Schematron family compiles to more than one XSLT (a CII arm and a UBL arm), so one key and version can appear on several rows with different fileSha256 values. The same goes for ubl_xsd, one row for the Invoice root and one for the CreditNote root, and for facturx_schematron, whose rows include each Factur-X profile’s schema.

One format’s rulesetArtifacts also spans more than its own pack. An XRechnung document is judged by the EN 16931 base rules, the KoSIT XRechnung Schematron, and KoSIT’s severity configuration, which decides whether a given rule fires as an error or a warning. All three are listed here, so all three are verifiable.

Before any of those rules run, every EN 16931 document is checked against its syntax schema, and that schema is one of the rows too: cii_xsd (UN/CEFACT CII D16B) for a CII document, cii_xsd_d22b (CII D22B) for a French EXTENDED-CTC-FR document, ubl_xsd (OASIS UBL 2.1) for a UBL document, and the profile’s own schema, listed under facturx_schematron, for a Factur-X document. A document the schema rejects never reaches a Schematron, so its rulesetArtifacts names the schema alone.

A request can add to that set too. Passing franceCtc=true, or sending a document that carries a French Flux 2 BusinessProcess code (S8, B8, M8), runs the BR-FR-CTC overlay on top of whatever else judged the document, and the EXTENDED-CTC-FR overlay on top of that for the Factur-X extended-ctc-fr profile. Both are listed here for the same reason: what judged your document has to be checkable, whichever arms ran.

Example

Example

{
  "success": true,
  "data": {
    "rulesets": [
      {
        "format": "xrechnung",
        "label": "XRechnung",
        "standard": "EN 16931 CIUS - UBL & CII",
        "authority": "KoSIT",
        "region": "Germany",
        "specVersion": "3.0.2",
        "rulesetVersion": "2.6.0",
        "rulesetArtefact": "XRechnung Schematron",
        "versionKey": "xrechnung_schematron",
        "verificationTier": "conformance-verified",
        "rulesProvenance": "authority-conformance",
        "verificationBadge": "authority-verified",
        "releaseDate": "2026-08-31",
        "repo": "itplr-kosit/xrechnung-schematron",
        "tag": "v2.6.0",
        "retained": [
          {
            "version": "2.5.0",
            "releaseDate": "2026-01-31",
            "servingFrom": "2026-04-15",
            "retainedUntil": "2027-06-11",
            "supersededMandatoryOn": null
          }
        ]
      }
    ],
    "channels": [
      {
        "id": "latest",
        "label": "Latest",
        "description": "The current ruleset for each format, the default when no Beliq-Ruleset header is sent."
      },
      {
        "id": "previous",
        "label": "Previous",
        "description": "The ruleset retained before the most recent breaking change, per format. A retained ruleset becomes selectable on its bump's effective date, and stops being offered on this channel once the authority makes its successor mandatory. An exact version pin still reaches it until its sunset date. Where a format has none selectable, for either reason, previous resolves to latest and the response flags rulesetFellBack."
      }
    ],
    "scheduledChanges": [],
    "artifacts": [
      {
        "key": "en16931_cii_schematron",
        "version": "1.3.16",
        "fileSha256": "0b234dea2bbfee739b7761e607a992c17fab88773014ef56355b6158cfb1cc53"
      },
      {
        "key": "xrechnung_schematron",
        "version": "XRechnung-2.6.0",
        "fileSha256": "aa7d495e02990d88a9dc91b5eceb3349f7ee5565241d93ef99e90e1760fdd70f"
      },
      {
        "key": "xrechnung_schematron",
        "version": "XRechnung-2.6.0",
        "fileSha256": "30e64d8bddf0bebded89e2bedab0b4856f0c4f1e852bd303e1957a7d627c0e6c"
      },
      {
        "key": "xrechnung_severity_overrides",
        "version": "2026-08-31",
        "fileSha256": "3db6bcddfd30cc9d51ac7c6c156ae2621c27d471a65f9db98db5c3b081ab6713"
      }
    ]
  }
}
Verifying a validation result

Verifying a validation result

Every POST /v1/validate response for a publicly-supported format carries a rulesetSha256 and its rulesetArtifacts components. To confirm the ruleset that judged you is the one Beliq pins for everyone:

  1. Check that each component in your response’s rulesetArtifacts appears in artifacts[] here (match on key, version, and fileSha256).
  2. Reproduce rulesetSha256 yourself: sort the "<key>@<version>=<fileSha256>" lines, join them with newlines, and take the SHA-256.

The reproduction needs only the values in your own response, so it works for any result, a document the syntax schema rejected included. For the national XSD formats and the EN 16931 syntax schemas, which Beliq vendors byte for byte, you can also reproduce fileSha256 straight from the publisher’s own download. See how verification works and verify a hash.

Related