Verify the ledger yourself
Every platform in this market says its audit trail can be trusted. Ours can be checked. Record the hash below today, and you can prove later that not one historic quote was altered, without asking us for anything and without taking our word for it.
Live
Current head of the chain
Read straight from the running ledger. It changes with every quote priced.
Head hash
loading…
Keep it with today's date. That single string commits to every entry written so far.
How it works
Each entry seals the one before it
When a quote is priced, the database computes a SHA-256 digest over that entry's contents and the previous entry's digest, before the row is written. Change any field of any historic entry and its digest no longer matches, and neither does every digest after it. The break is visible at the exact entry.
The canonical form is deliberately plain, so any language can rebuild it:
sha256(
chain_index | id | created_at | vertical |
components(key=true|false, sorted by key, comma separated) |
premium(0.00) | status | matrix_version | distributor_id | prev_hash
)
No JSON formatting, no key-order dependence, no locale. The first version of this used PostgreSQL's own JSON output and was replaced, because a chain only one database can rebuild is a claim rather than evidence.
distributor_id is inside the digest, not beside it. Attribution that sat outside
the hash could be reassigned after the fact with every digest still verifying — which would
make the chain evidence of what was quoted but not of who quoted it.
Do it yourself
Four commands, none of which need us
The verifier shares no code with the database. It rebuilds every digest in Node.
# 1. today: save the whole signed attestation, not just the hash
curl -s https://api.riskrouter.eu/api/v1/ledger/attestation > 2026-09-20.json
node tools/verify-attestation.mjs 2026-09-20.json
# 2. any time: export your own entries and the chain they sit inside
curl -s -H "Authorization: Bearer $RISKROUTER_API_KEY" \
https://api.riskrouter.eu/api/v1/ledger/export > export-2026-09-20.json
# 3. check it. the first proves we signed this head, the second proves
# your entries are what produces it
node tools/verify-attestation.mjs export-2026-09-20.json
node tools/verify-ledger.mjs export-2026-09-20.json
# 4. months later: a head you recorded must still come out of history
node tools/verify-ledger.mjs export-2027-03-01.json --expect-head <hash from step 1>
A mismatch at step 4 means history changed. There is no version of that sentence where we get to explain it away.
Step 2 used to read differently. It told you to pull the rows out of the database with a Supabase key — a credential you will never hold, because ours never leaves the Worker. So the independent check this page promised was one no customer could actually run. A proof that needs the operator’s cooperation is not a proof, it is a courtesy, and we would rather say that plainly than leave the old instruction sitting there looking reassuring.
Save the whole response rather than copying the hash out of it. The signature is what turns a
string you typed into a commitment we made: it covers the head hash, the entry count and the
time together, so none of the three can be changed afterwards without the signature failing.
The public key is in anchors/signing-key.json in the repository. Checking against
a key we hand you at the moment you check would prove nothing, if we are the thing in question.
Break it yourself
Change a premium and watch the chain refuse it
Four entries, chained exactly as the real ledger chains them — same canonical form, same SHA-256, computed in your browser. Edit any premium below. The entry you touch stops matching its own digest, every entry after it stops linking, and the head moves. Nothing here talks to us, and nothing you type leaves the page.
| # | Vertical | Premium €/mo | Digest | Status |
|---|
Head after your edits: …
The download is the part worth doing. Run the independent verifier over it and Node reaches the same conclusion this page did — including the entry number where it broke:
node tools/verify-ledger.mjs rows.json
Two implementations that share no code agreeing on where history was altered is the whole
argument. A test in this repository asserts that the function running in your browser and the
one in tools/verify-ledger.mjs produce byte-identical canonical strings, so the
demonstration cannot quietly drift away from the thing it demonstrates.
Continuity
What you keep if RiskRouter stops existing
This is a one-person company. You should ask what happens to your audit trail the day it stops, and the answer should not depend on our goodwill on that day.
An export you have already downloaded keeps working after we are gone. It contains:
- Every one of your entries in full, so each digest can be rebuilt from its own content.
- The
(chain_index, row_hash, prev_hash)of every entry in the ledger — opaque digests, no one else’s content — which is what links your entries to the head. - The signed attestation for that head, and the id of the key that signed it.
The verifier is forty lines of standard-library Node in a public repository, the public key
stays in anchors/ including after any rotation, and neither needs a server to
run. Download an export once a month and you hold evidence that outlives the company that
issued it. That is the opposite of lock-in, and it is deliberate: a product whose value
depends on you being unable to leave is a product we would not want to sell.
Honest limits
What this does and does not prove
| Claim | Status |
|---|---|
| A historic entry was altered or deleted | Detectable by anyone holding an earlier head |
| Entries were re-ordered or a gap introduced | Detectable |
| An entry was fabricated and inserted into the past | Detectable |
| A quote was never written at all | Not detectable. A chain proves what is there, not what is missing |
| The premium was correct when it was quoted | Separate control: the rating matrix is versioned and stamped on every entry |
| Someone rebuilt the whole chain from scratch | Detectable against any head recorded beforehand. node tools/verify-anchors.mjs export.json checks a ledger against every head published in anchors/, and a rebuild cannot reproduce one taken before it. Residual limit: that directory is ours, so a rebuild plus a force-push could remove the anchor too — not from a copy you already hold, which is the reason to keep one |
| We deny ever having published the head hash you hold | Every attestation is signed. One you saved is ours whether we like it or not |
| A head hash was published before the entries it covers existed | Not yet — but no longer only our word. Since 20 September 2026 the 13 September anchor is committed to three independent OpenTimestamps calendars, and those proofs are in anchors/. They are pending: a calendar has undertaken to include the digest, and no block has confirmed it. ots upgrade is what turns that into a Bitcoin timestamp, and until it is run this row stays no |
The last row is the honest one, and it is the reason the row above it matters. Publishing the head is the commitment; a signature means we cannot later say we never made it; keeping your own copy is what makes it binding. What none of that establishes is when — our timestamp is still our word. Anchoring heads with a third-party notary would settle that, and it has not been done.