To prove a file existed at a point in time, you record a fingerprint of that exact file with something outside your control, at that moment, and keep what you get back. Every method follows that pattern. The differences show up later, on the day someone actually checks: what you still need to have, and who still needs to be reachable, for the proof to hold up.
This page goes through each method from that later point. A proof is made once and checked long afterward, often by someone who has never dealt with whoever issued it. For each method's mechanics and trust model laid out side by side, see Proof of Existence: How Each Method Works and What a Third Party Has to Trust.
The first thing you need to keep: the exact original file
Every digital method starts the same way. You compute a SHA-256 hash of the file, a 256-bit fingerprint written as 64 hex characters:
sha256sum contract.pdf
Change one byte and the hash comes out completely different. The hash also reveals nothing about what's in the file, so you can share it with a service without sharing the document.
This has a practical consequence that matters under every method. A proof is tied to the bytes, not to the content as a person would describe it. A PDF that's been re-saved, a photo that's been re-compressed or a spreadsheet that's been re-exported is a different file with a different hash, and the proof won't match it. Keep the original exactly as it was when you hashed it. If that file is gone, every method below has nothing to check against.
What each method leaves you holding
Notarization
A notary public witnesses a signature and confirms who signed. The record is the notarized document, plus the notary's own record where one is kept. A notarization covers the signing on a document. It isn't tied to the bytes of a digital file unless the file's hash is written into the document being notarized.
What you need later: the notarized document and, if it's challenged, the notary's record or testimony. What the person checking has to trust: the notary.
RFC 3161 timestamping authority
RFC 3161 is an IETF standard. Your client sends a TimeStampReq containing the hash to a Timestamping Authority, such as DigiCert, Sectigo or FreeTSA. The authority signs the hash with its private key and sends back a TimeStampToken. OpenSSL handles both ends:
openssl ts -query ...
openssl ts -verify ...
What you need later: the token, the original file, and the authority's certificate chain to check the signature against. What the person checking has to trust: that authority's key and its certificate chain.
Hosted blockchain anchoring service
A vendor takes your hash through an API and anchors it to a public chain for you. Mechanically, the record ends up on a ledger that no single party operates. What you hold afterward depends on what the vendor gives you.
If you get the transaction id plus enough data to connect your hash to it, anyone can check the record on a public block explorer without the vendor. If verification only works through the vendor's own portal, the vendor has to stay online for as long as the proof matters. Before relying on one, get answers to three questions. Which chain does it anchor to? Can a proof be verified without the vendor? What do you hold if the vendor becomes unavailable?
Anchoring it yourself on a public ledger
You can skip the vendor entirely. OpenTimestamps is an open-source Bitcoin timestamping protocol that uses calendar servers and Merkle aggregation. It's a protocol and toolset you operate yourself, with no hosted certificate page, no managed verification URL for a non-technical third party and no vendor to contact. You can also write the hash into a transaction yourself. That means running a wallet, paying network fees and guarding a private key.
What you need later: the proof file, the original file and the public chain. What the person checking has to trust: the ledger. The tradeoff is operational. You run the tooling, and so does anyone who checks, because there's no page you can send to someone non-technical.
What ProofLedger does differently
ProofLedger has one engine: hash the bytes with SHA-256, anchor the hash, return a proof. There's no pipeline for specific file types. The file stays on your machine, and only the hash is recorded on chain, whatever the file's type or size.
Each proof is anchored on Polygon in its own public transaction, usually within a minute. Polygon is the only chain. Bitcoin anchoring was discontinued on 2026-10-15, and the few proofs anchored on Bitcoin before then keep that record on their own certificate.
For each proof you get three things, each meant for a different kind of reader:
- A certificate and a public verify page. These are a link you can send to someone who will never install anything. The verify page looks the proof up in ProofLedger's records.
- A proof bundle. This is everything needed to verify that proof without ProofLedger: the hash, the chain, the transaction id and the anchor time, in the verify-proof file format. The API returns it for any proof you own, and every anchored webhook payload includes it.
- The Polygon transaction itself. It's public, and anyone can look it up on a block explorer.
The bundle and the transaction are the parts that don't depend on ProofLedger. If you have them and the original file, you can check the proof without contacting the company.
From code, submitting a hash is a single call. POST /api/v1/proof uses a Bearer key from Account > API Keys and takes a body of {"sha256": "<64 hex chars>"}, with an optional filename label and an optional external_id. The external_id is your own record id, so retrying a request returns the same proof instead of creating a new one. The response is a 201 containing id, sha256, status, created_at, duplicate_of, certificate_url and verification_url. To submit many files at once, POST /api/v1/proofs/batch takes up to 100 hashes per call. GET /api/v1/proofs finds a proof by external_id, or lists the proofs anchored since a given time. Signed webhooks notify you when an anchor lands. The full reference is at proofledger.io/api.html.
Verifying a proof yourself
There are three ways to check a ProofLedger proof, depending on who's checking and how far they want to rely on ProofLedger.
With a browser. Open the proof's verify page. This is the quickest check, and it reads ProofLedger's records.
With only the hash. The public verify endpoint needs no account and no key:
sha256sum contract.pdf
curl "https://proofledger.io/api/v1/verify?hash=<the 64 hex characters>"
Without a key it allows 120 requests per hour per IP. With a key, that key's limit applies instead.
Without ProofLedger at all. Install the verify-proof package:
pip install verify-proof
It compares the file with the proof bundle on your own machine, with no network call. Then take the transaction id from the bundle, look it up on a Polygon block explorer, and confirm that the transaction and its time match the bundle. Nothing in this check goes through ProofLedger. Someone you've never met can do it with the file, the bundle and a public explorer.
A successful check proves one specific thing: this exact file existed, in this exact form, no later than the anchor time. It doesn't show who made the file or when it was first created, and it gives no legal right. It also can't be backdated. The date a proof can show is the date the hash was anchored, so the anchor has to be made before anyone questions the file, not after.
Which fits your situation
Each method above asks the person checking to rely on something. Choose based on what you're comfortable having them depend on.
If the evidence is a notary's act, it's tied to a document and a person, and it covers a file's bytes only if the hash was written into that document. If it's an authority's signature, the checker relies on that authority's key and certificate chain. If verification runs through a vendor's portal, that vendor is a dependency for as long as the proof matters. If you run the protocol yourself, you take on the operational work, and everyone who checks needs the tooling too.
ProofLedger is built so that two kinds of reader can check the same proof. There's a link that someone non-technical can open, and a bundle a technical reader can check against a public Polygon transaction without asking ProofLedger anything. You can submit hashes from your own code through the v1 REST API or from a CI release workflow, and the file never leaves your machine. If you're adding proof of existence to software that stores files for its users, proofledger.io/platforms has the quickstart. Plans and limits are listed at proofledger.io/pricing.html. ---