Verifiable proof

The sealed evidence pack

A verdict without proof is an opinion. Every validation can emit a signed pack stating which document was judged, against exactly which rules, by which engine, and what it answered — verifiable by a third party without calling us.

What goes into the seal

Each layer contributes a fingerprint. The final seal covers them all: change one byte at any layer and the seal changes.

  1. 1

    The document

    SHA-256 of the submitted file, its size, format and profile. The document itself does not enter the pack — only its fingerprint.

  2. 2

    The floor

    The rule set identifier, its fingerprint, its effective date, and the fingerprint of every artifact executed.

  3. 3

    The engine

    The processor name and version, and whether the verdict was indeed issued against the manifest’s artifacts.

  4. 4

    The verdict

    The status and the number of errors, warnings and passed rules.

  5. 5

    Integrity

    The SHA-256 of a canonical form of the pack: an ordered sequence of lines, independent of JSON formatting.

  6. 6

    The signature

    An Ed25519 over that fingerprint, with the identifier of the key that produced it.

What a pack contains

This one was actually emitted by the pipeline. Its signing key is generated for the run and published in no JWKS: it shows the shape, it does not verify.

document.sha256
6ad797b11ee5f072bbfd3f41f9e03e4d5d037d1a1988fc7dcb221d082956f60f
ruleset.id
eu-en16931-2026-08
ruleset.sha256
3433666fbc3699ef3e194c56f4151c484f2b689cb9c352cfd269be1009b4c6e6
engine.version
saxon-12.5
verdict.status
needs_input
verdict
1 err · 0 warn · 65 pass
integrity.hash
8ea5a64a9154bb56678d8844bc3c9218c89efe81084bbe59bb958070c92e1d0c
signature.alg
EdDSA

This pack was issued against eu-en16931-2026-08. A published floor is immutable: the same file, pinned to that same identifier, returns the same verdict as long as the artifacts are retained — ten years, the fiscal archiving period.

The pack, field by field
{
  "version": "2",
  "sealed_at": "2026-08-21T02:14:52Z",
  "document": {
    "sha256": "6ad797b11ee5f072bbfd3f41f9e03e4d5d037d1a1988fc7dcb221d082956f60f",
    "bytes": 14619,
    "format": "pdf",
    "syntax": "cii",
    "profile": "urn:cen.eu:en16931:2017"
  },
  "ruleset": {
    "id": "eu-en16931-2026-08",
    "sha256": "3433666fbc3699ef3e194c56f4151c484f2b689cb9c352cfd269be1009b4c6e6",
    "sealed": true,
    "effective_from": "2026-08-01",
    "artifacts": [
      {
        "name": "saxon-he",
        "version": "12.5",
        "sha256": "98c3a91e6e5aaf9b3e2b37601e04b214a6e67098493cdd8232fcb705fddcb674"
      },
      {
        "name": "schematron-cen",
        "version": "1.3.16",
        "sha256": "f821ce9320acc219081197ec893d7d3e8276ccd011fdff56c50e4f08b5a72fd0"
      }
    ]
  },
  "engine": {
    "name": "factlint-saxon",
    "version": "saxon-12.5",
    "pinned": true
  },
  "verdict": {
    "status": "needs_input",
    "errors": 1,
    "warnings": 0,
    "passes": 65
  },
  "integrity": {
    "alg": "SHA-256",
    "hash": "8ea5a64a9154bb56678d8844bc3c9218c89efe81084bbe59bb958070c92e1d0c"
  },
  "signature": {
    "alg": "EdDSA",
    "key_id": "example-key-not-published",
    "value": "cuE7ZNrOutWJdM5Kan7QVorKx7hTP6ftIMjSBUaTOd-rUMZU4odsNMK1yiHduYHycnOoxp32qqrO6lvC61EyCg"
  }
}

How to verify a seal

  1. 1

    Recompute the fingerprint

    Rebuild the pack’s canonical form and take its SHA-256. It must equal the integrity.hash field.

  2. 2

    Fetch the public key

    The JWKS publishes active and revoked keys. The signing one is named by signature.key_id.

  3. 3

    Verify the signature

    A standard Ed25519 verification, with the library of your choice. Nothing proprietary, no dependency on us.

Or in one call
Ed25519
curl -X POST https://api.factlint.com/v1/evidence/verify \
  -H 'Content-Type: application/json' \
  -d @pack.json

Verification is free and keyless: it sends us no document and asks for no trust, so it is not billed.

https://api.factlint.com/.well-known/evidence-jwks.json

What people ask us

Can it be verified offline?

Yes, and that is the point. The pack carries everything needed; the public key is a static file to cache once. An Ed25519 verification touches no network. The endpoint exists for convenience, not because it is required.

What happens if Factlint disappears?

Packs already emitted stay verifiable: they depend on no service. What would disappear is the ability to emit new ones, and to replay a validation — the pack then proves what was judged, but nobody can redo it. That is why artifact fingerprints are in there: they name packages published elsewhere, at CEN, FNFE or KoSIT.

Is the document inside the pack?

No, only its fingerprint. A pack therefore reveals no customer name, no amount, no IBAN, and can circulate freely. In exchange, keeping the file is on you: without it, the fingerprint cannot be recomputed.

What legal weight does it carry?

It is technical proof, not a certification. The pack establishes what our engine did, when, and against which rules — and that none of it has been altered since. It does not make an invoice compliant, does not amount to a qualified electronic signature under eIDAS, and replaces no transmission obligation. What it brings to an audit or a dispute is traceability: which version of the rules applied that day, and what it answered.

Does a revoked key invalidate old packs?

No. A revoked key stays published in the JWKS, precisely so the packs it signed remain verifiable. Revocation says we no longer sign with it, not that what it signed stopped being true.

The full endpoint reference →