Tersign head asking… ledger asking Shows this page's sections as plain markdown, built in your browser from the page itself. The agent manifest is https://tersign.ai/llms.txt.

Public verification

Check a record.

Paste a record's digest. This page asks the ledger, and prints the ledger's own answer: whether it holds the record, and whether that record's counter-signed chain link checks out. No account needed. Nothing in the answer is re-checked in your browser; the seal is drawn from the digest you pasted.

No digest to hand? Check the genesis record, the first on the ledger, counter-signed on 2026-07-11, and a self-signed demo.

the ledger, asked from this pageasking
SEAL no digest
Engraved from the digest you pasted. The seal is for the eye; the digest is the proof. A fingerprint, not an approval.

Rely on a range.

A single record checks free, on this page or offline. A party that relies on a chain it did not write can buy a ledger-signed statement over one range of it: the chain commitments before and after the range, so whoever holds the range's records can check that they are exactly the set counter-signed there.

Price
$0.10 per statement, the same for every payer
Paid in
USDC on Base over x402 (eip155:8453, amount 100000, 6 decimals), with no account
Range
up to 5,000 records of one chain, ending at or before the sequence number of the record you hold
Released
only after the payment settles; the bytes are the same for every payer
GET https://tersign.ai/v1/receipts/{digest}/statement?from={from}&to={to}

Answers 402 with a PAYMENT-REQUIRED header: scheme exact, network eip155:8453, the USDC contract 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913, amount 100000 ($0.10). {digest} is a record you hold; to may not exceed its sequence number.

GET https://tersign.ai/v1/receipts/{digest}/statement?from={from}&to={to}
PAYMENT-SIGNATURE: <signed payment>

The same request with the signed payment. Answers 200 with {statement, statementDigest, signature, signer}: the signature is the ledger key's personal_sign over "tersign-chain-statement-v1:" + statementDigest, where statementDigest is the keccak-256 of the statement's canonical JSON as llms.txt specifies it, and it recovers to the address at /v1/ledger.

What a statement establishes

  • Which records were counter-signed on that chain at ledger sequence from to to, and in what order.
  • A commitment anchor covering the range, when the ledger can check one against its stored records before it signs: the earliest confirmed one, else the earliest still pending, with its status.

What it does not establish

  • Anything about records never submitted to the ledger, or that the issuer issued no others.
  • Issuer-sequence gaps and duplicates are reported only for records whose counter-signed link binds the issuer's numbering; no link does yet, so today every record is reported as unbound.
  • Record content, tax treatment, or compliance with any law; and its own signature adds no earlier time.
  • The two things that still rest on Tersign (/independence): that the address at /v1/ledger is Tersign's, and that Tersign keeps one history per chain.

Check it without this page.

To check without relying on this page, take the receipt itself (for the genesis record, the artifact object of /v1/genesis, not the response around it) and run npx tersign verify <receipt.json> --signer <issuer address> (or python3 -m tersign verify): it recovers the EIP-712 signature on your machine and compares it with an issuer address you obtained through a channel you trust. An evidence bundle's chain links, chain commitment and anchor relation are recomputed offline by the bundle verifier (/verify/latest/); pass it --signer with the ledger address from /v1/ledger to bind authorship. The same address is also pinned off this domain, as provenance.ledger_signer in the public tersign-py repository's tests/vectors/p1-live-genesis-receipt.json: a second place to check it.

npx tersign verify <receipt.json> --signer <issuer address>
python3 -m tersign verify <receipt.json> --signer <issuer address>
curl -s https://tersign.ai/v1/genesis | jq .artifact > genesis.json && npx tersign verify genesis.json --signer 0x36f82906859E5B0bd076069f8cdfAea355358b14

The genesis record's payload signature, recovered on your machine and compared with the address it names as payer: it is a self-signed demo, so that address is Tersign's own.

npx tersign verify 0xe5874f1ffe87f0a6dd9eb157730f67b86ee4538b125fe30fcc4e165213dd3fc4 --ledger https://tersign.ai

Asks the ledger about the genesis record from your own machine. The answer is the ledger's own, as on this page; the commands above check a signature on your machine.

GET https://tersign.ai/v1/receipts/{digest}/verify

The same answer as JSON, for machines. No account.

GET https://tersign.ai/v1/records/{digest}/context

Record context, for the writer of a receipt or action record on its own chain, with the account's API key as a Bearer token; a record on another account's chain answers 403. It returns the record as submitted, its counter-signature and chain position, the anchor facts the public check gives, any payment reference, compliance block and refund rows, and the legal name and jurisdiction the account declared, labelled "declared by the account, not verified by Tersign". A notCovered list names what the record does not establish. Not tax or legal advice.

POST https://tersign.ai/v1/account/identity

How an account declares the legal name and jurisdiction its records are attributed to (Terms §4.1): {"legalName":"…","jurisdiction":"GB"} with the API key, or signed with the chain key for an account that has none (the steps are in llms.txt). Kept as declared by the account, not verified by Tersign.

Try it on an archive its holder rewrote.

The claim-file drill holds one synthetic evidence archive in three states: as written, with the last record deleted, and with the last record moved one hour earlier and re-signed with the holder's own key, each time after the holder rewrote every file it controls. The checker in it is the published bundle verifier; its README shows how to compare that copy with the release at its content address.

The clone needs git and the network once; the checks then run offline, with Python 3 alone
git clone --depth 1 https://github.com/tersignhq/claim-file-drill
cd claim-file-drill
python3 verify/verify_bundle.py intact
python3 verify/verify_bundle.py record-omitted
python3 verify/verify_bundle.py back-dated

Each run ends with this verdict line, as the drill's README gives it:

  • intactVERDICT: PASS (integrity-only) — the bundle is internally consistent, but signer identity was read from the bundle itself. Its ledger key is a published test key (SIGNER above), so no --signer value establishes authorship of this archive.
  • record-omittedVERDICT: FAIL (1): anchors.leafForCommitment
  • back-datedVERDICT: FAIL (2): record[4].countersig, anchors.leafForCommitment