← TOOLS

Decision Receipt verifier

Every KYTGate decision produces a signed Decision Receipt. Paste one here, or a whole evidence pack, and the signature is checked in your browser against the public key at /api/v1/receipt-key. The receipt itself is never uploaded. You do not need to trust KYTGate to run this check.

A second, optional check answers what a signature cannot: whether the receipt existed when it says it did. It looks the receipt up in the daily Merkle root published at /attestations and folds the inclusion proof in your browser. That one sends the receipt id, and only the id.

No receipt to hand? Load the sample below, or download it. It is a real receipt in the same format a tenant gets, and its signature verifies. It is signed by a key whose private half we publish alongside it. We do this on purpose. Anyone can mint a sample, so holding one proves nothing and a sample cannot be mistaken for evidence of a decision. A tenant’s receipts are signed by a key that never leaves the runtime.

To see the document your auditor will ask for, download the sample Evidence Pack. It is the same PDF a customer’s case produces, from the same code, with every page marked as a sample. The receipt above is the one inside it, so you can lift it out and check it here.

Verify against a specific public key (optional)
Was it written when it says it was?

A signature proves the content. It cannot prove the date, because whoever holds the key can sign something later. KYTGate publishes a daily Merkle root over its receipts at /attestations; this fetches the inclusion proof and folds it here. Unlike the check above, it sends the receipt id to KYTGate, and nothing else.

What is being verified

The signature covers the canonical form of the receipt: the signature field removed, object keys sorted recursively, serialized as compact JSON, UTF-8 encoded, signed with Ed25519. Any change to any field (the decision, a signal, a list snapshot hash, a timestamp) invalidates it.

A valid signature proves integrity: the record is what KYTGate produced at decision time. It does not prove the decision was right. For that, read the coverage matrix in the receipt: which checks were COMPLETE, which were MISSING or NOT_AVAILABLE, and which policy version governed.

What the anchor adds

The signature is made with a key KYTGate holds, so on its own it cannot rule out a receipt signed later and dated earlier. A competent auditor will raise that objection first. Every receipt is therefore hashed into an RFC 6962 Merkle tree once a day and the root is published and never changed. The leaf is SHA-256(0x00 || "kytgate.receipt.v1\n" || canonical receipt without the signature || "\n" || the signature), and inner nodes are SHA-256(0x01 || left || right).

An anchor proves a receipt existed by the time its root was published, and has not changed since. It does not prove the decision was right, and it says nothing about receipts that are not in a batch. A root we publish ourselves is a tamper-evident log rather than third-party proof. It is worth recording today’s root somewhere we do not control.

Verifying without this page

Both checks are also published as a dependency-free open-source package, so an auditor can run them on their own machine against their own copy of the root: npx kytgate-verify receipt.json --root <the root you recorded>. Source and the full algorithm at npmjs.com/package/kytgate-verify; with --offline plus a key and proof captured earlier it never touches the network.

Auditors who prefer their own tooling can reproduce the check with any Ed25519 library: fetch the SPKI public key, canonicalize as described, and verify the base64 signature after the ed25519: prefix. The evidence pack downloaded from a case includes these instructions verbatim.

Run these checks on every deposit, automatically

KYTGate screens each crypto deposit and withdrawal against the OFAC, UK and EU lists and the USDT/USDC issuer freezes, decides under your written policy, and keeps a signed record an auditor can check without us.

Start free sandboxTalk to usSee pricing

API key in two minutes, 50 screenings a month free, no card. Security · Live status · Methodology