Both tools anchor a SHA-256 hash to the Bitcoin blockchain. Neither stores your file. That's where the similarities end. OpenTimestamps is an open-source protocol with a client you run and a proof format you manage. ProofLedger is a managed service that handles the anchoring, stores the proof record, and gives you a public URL anyone can use to verify it. The decision comes down to what you need the proof to do after you create it, and who needs to be able to verify it.
What OpenTimestamps is and how it works
OpenTimestamps is an open-source Bitcoin timestamping protocol created by Peter Todd. It defines a standard for proving that a hash existed at or before a specific Bitcoin block height.
The mechanism works like this. You run the OpenTimestamps client locally (available in Python, JavaScript, Java, and Rust). You submit your file or its hash to a public calendar server. The calendar server aggregates incoming hashes into a Merkle tree at regular intervals, then anchors the Merkle root to Bitcoin by embedding it in a transaction. Once that transaction confirms, your hash is provably connected to that block's timestamp through the Merkle path.
The output is an .ots file. That file contains the Merkle proof path connecting your specific hash to the Bitcoin block header. To verify later, you need three things: the original file, the .ots file, and access to block header data (either through a Bitcoin full node or by querying the calendar server). The OpenTimestamps client walks the Merkle path, recomputes the root, and confirms it matches what's embedded in the block.
There is no hosted certificate page per proof. There is no verification URL you can hand to opposing counsel, a claims adjuster, or an auditor who hasn't installed the client. Verification is a technical operation requiring the client and either Bitcoin node access or a calendar query. OpenTimestamps is a protocol and toolset you operate. There is no vendor to call, no managed infrastructure backing the proof, and no SaaS layer on top. That's by design. The project is deliberately minimal: anchor a hash, produce a verifiable proof file, done.
Bitcoin-only. No Polygon layer, no dual-chain anchoring.
What ProofLedger does differently
ProofLedger anchors to two blockchains. Polygon handles near-instant anchoring. Bitcoin handles a daily batch, built with Merkle proofs for the same cryptographic depth OpenTimestamps provides on its single chain. One submission gets you both.
The file never leaves your machine. Only the hash goes on-chain. That part is architecturally the same. What's different is what comes back after the anchor.
ProofLedger returns a proof record with a public verification URL. Anyone can hit that URL without installing anything. An attorney verifying opposing evidence, an adjuster auditing a claim, a forensic consultant reviewing chain-of-custody documentation: they open a browser, enter the proof URL or file hash, and get a signed confirmation that the hash was anchored to both chains at a specific time.
There's also a local offline path. The verify-proof PyPI package lets you verify a proof JSON locally without touching any ProofLedger server. The REST API (BUSINESS tier) lets you build anchoring into your own workflow programmatically: submit a hash, get back a proof ID and certificate URL. A GitHub Action is available for CI/CD pipelines.
Evidence packs organize proofs by claim, case, or matter, with loss dates and pre/post indicators. That's useful for insurance and legal workflows where grouping across a matter matters.
Verifying a proof yourself
With OpenTimestamps:
Install the Python client:
pip install opentimestamps-client
Stamp a file and produce the .ots proof:
ots stamp document.pdf
Once the calendar has anchored and Bitcoin has confirmed, upgrade the stamp to pull in the full Merkle path:
ots upgrade document.pdf.ots
Then verify:
ots verify document.pdf.ots
The client checks the Merkle path in the .ots file against block header data. You need the original file and the .ots file together. Lose either one and verification isn't possible.
With ProofLedger:
Install the verify-proof package:
pip install verify-proof
Hash a file locally:
verify-proof hash document.pdf
Verify against a proof file:
verify-proof verify document.pdf --proof document_proof.json
Or verify in Python directly:
from verify_proof import hash_file, load_proof, verify_proof
file_hash = hash_file("document.pdf")
proof = load_proof("document_proof.json")
result = verify_proof(file_hash, proof)
if result["verified"]:
print(f"Anchored at: {result['anchored_at']}")
print(f"Bitcoin tx: {result['tx_id']}")
else:
print(f"Not verified: {result['error']}")
The proof.json file is returned when you anchor through ProofLedger. Verification runs entirely offline. The package makes no network calls. It confirms that your file's hash matches what's in the proof record and that the proof's internal Merkle structure is consistent. Confirming the transaction actually exists on-chain is a separate step that requires a blockchain explorer.
For any party who isn't running code: the public verify URL is accessible in any browser. No installation, no client, no technical prerequisites.
Which fits your situation
OpenTimestamps is a protocol that anchors a hash. The proof lives in a file you manage. For any verification to happen later, that file has to be present, it has to have traveled with the original document through every handoff, and the person verifying needs the client or a calendar server query. That's the dependency chain you accept when you adopt the toolset. For technically equipped teams doing internal verification, it's a manageable dependency. For workflows where the proof needs to move beyond your own team to other parties who didn't create it, the coordination overhead compounds at every handoff.
There's also the single-chain question. Bitcoin's finality is well-established. But in an admissibility argument under FRE 901(b)(9), where the court is evaluating the reliability of the process that produced the output, having two independent chains confirming the same timestamp changes the foundation you can lay. Polygon and Bitcoin are operated by entirely separate sets of validators. An identical anchor timestamp across both chains is a stronger corroboration argument than one chain and a Merkle path.
ProofLedger is built for workflows where the proof has to be accessible to people who didn't create it. When an adjuster, opposing counsel, or a forensic auditor needs to verify evidence without installing anything or receiving a separate proof file from you, the public verify URL handles that. The proof exists independent of any file on your machine. It doesn't get separated in transit. It doesn't depend on the recipient's toolchain.
The REST API and GitHub Action let you embed anchoring into existing pipelines without changing how files are managed. Evidence packs keep proofs organized by matter, which matters when a single claim involves dozens of timestamped files with different loss dates.
If your team controls both sides of verification and can maintain the .ots file through its full lifecycle alongside the source document, that workflow stays within OpenTimestamps' model. But the moment the proof needs to travel to an external party, an auditor, a regulator, or the other side of a dispute, you're asking them to adopt the same client and file-management discipline you've maintained. That's a different ask than sending a URL.
ProofLedger is designed for that handoff.