OPERATIONAL anchoring on mainnet · 0/300 anchors this hour no issues in 8h 10m report a problem

📄 Notary — proof of existence

Timestamp any file on-chain without revealing it — a track, a video master, a photo, a contract, a dataset. Hash it locally (in your browser, or yourself) and send only the 64-char fingerprint; later, re-hash to prove the document existed at or before the block's timestamp.

Any file — audio, video, image, document, archive. It never leaves your browser.

— or paste text to timestamp (no JavaScript needed) —

privacyonly the sha256 is sent — the file never leaves your machine
on-chainOP_RETURN bsv.cx not1 <sha256>

Endpoints

POST /n{ "hash": "<sha256hex>" } or { "content": "text" }
GET /n/:hashJSON proof
GET /n/:hash/viewhuman proof page
printf '%s' "my document" | sha256sum
curl -X POST https://bsv.cx/n -H 'content-type: application/json' -d '{"hash":"<that hash>"}'

Verify it yourself

What this proves — and the one catch for media

provesThese exact bytes existed at or before the block's timestamp. Any file type — SHA-256 does not care whether it is a contract or a master recording.
the catchRe-encoding changes the hash. A PDF usually travels byte-identical, but audio and video rarely do — most platforms transcode on upload. So this proves your master existed on a date; it will not match a re-encoded copy someone else is holding. Keep the exact file you hashed.
not provedWho made it, who owns it, or that anything claimed about it is true. If you want authorship on the record, sign a statement — we timestamp the claim, we never vouch for it.

Re-hash your file with SHA-256 and confirm it matches. The anchor's OP_RETURN carries bsv.cx / not1 / <hash>, and the block timestamp bounds when it existed.

🧾 Batch — thousands for one anchor

Timestamp thousands of fingerprints for the price of one transaction: they're committed to a single Merkle root (RFC 6962 — domain-separated, single SHA-256, promote-odd), and only the root is anchored. Every item still gets an inclusion proof you can verify independently.

on-chainOP_RETURN bsv.cx not2 <merkleRoot>
limitup to 3000 hashes per batch (413 above)
POST /n/batch💳 paid { "hashes": ["<sha256hex>", …] } or { "contents": ["…"] }
GET /n/:hash/proofinclusion proof (leaf + audit path) — free
GET /n/b/:rootbatch summary — free

Free vs paid

Notarizing one file at a time (POST /n above) is free. Bulk batching is paid, because every batch spends a real on-chain anchor — see pay-per-call. Verification is free and always will be: proofs, batch summaries and records need no token, because a proof nobody can check is not a proof.

price3000 sat buys 10 calls; one call covers 300 hashes
at full size3000 hashes = 10 calls = 1 satoshi per timestamped file
re-submittingan identical batch performs no new anchor, so the call is refunded rather than charged twice

Unpaid requests get an HTTP 402 with an invoice. The pay-per-call docs walk through the three-step loop, and scripts/batch-demo.ts is a working client.

# 1. quote (no token) -> 402 with an invoice
curl -X POST https://bsv.cx/n/batch -H 'content-type: application/json' -d '{"hashes":["<sha256hex>"]}'

# 2. pay it, then batch with the token
curl -X POST https://bsv.cx/n/batch -H "authorization: Bearer <token>"   -H 'content-type: application/json' -d '{"hashes":["<sha256hex>","…"]}'

Fold a proof's audit path into a root and confirm the anchor's OP_RETURN carries bsv.cx / not2 / <root>. A standalone, dependency-free verifier ships in scripts/verify-proof.ts.

← back to bsv.cx