Verify receipts offline
Last updated: 2026-10-10
You do not need to trust our server to check a receipt. A single-file checker (Node.js 20 or later, no dependencies) verifies the Ed25519 signature and the payload against our public keys.
Get the checker
curl -O https://vehcdj664efetfrsolne5umanq.srv.us/dl/verify-receipt.mjs
node verify-receipt.mjs --selftest
https://vehcdj664efetfrsolne5umanq.srv.us/dl/index.json lists the checker (verify-receipt) with its URL, size and sha256, so you can check the file you downloaded.
Check a receipt
node verify-receipt.mjs '<receipt>' --issuer https://still-rapids-9yt7.here.now
This fetches https://still-rapids-9yt7.here.now/.well-known/jwks.json and checks that the receipt's iss and key id belong to that issuer. The issuer is a fixed address that does not change when the service moves, so a receipt keeps verifying after the service address changes. Always pin --issuer (or a key file you trust): without it, the key location comes from the receipt itself.
To work fully offline, save the keys once and pass the file:
curl -o jwks.json https://still-rapids-9yt7.here.now/.well-known/jwks.json
node verify-receipt.mjs '<receipt>' --jwks jwks.json --issuer https://still-rapids-9yt7.here.now
Pass - instead of the receipt to read it from standard input.
Output
JSON {valid, reason?, kid, tier, payload}. Exit code 0 means valid, 1 invalid, 2 a usage error.
Doing it yourself
A receipt is a compact JWS: header.payload.signature, each base64url. Check that the header has alg EdDSA and typ attestpage-evidence+jws, find the key in the JWKS whose kid matches the header's kid, and verify the Ed25519 signature over header.payload. Then check that iss is the issuer you expect. Field meanings are in How it works.