The timestamp problem
You ship a file. A week later, someone claims they had the same idea first. How do you prove your file existed before theirs?
Cryptographic hashes solve "this file is unchanged." They do not solve "this hash existed at this time." For that you need a timestamp that somebody else can verify without trusting you.
The two usual answers are a Certificate Authority timestamp (trusts the CA) or a blockchain transaction (costs fees, requires a wallet, requires you to wait for confirmation). Both have real costs.
OpenTimestamps solves this by aggregating many hashes into a Merkle tree and anchoring the root in a Bitcoin transaction. One on-chain transaction serves tens of thousands of commitments. The cost per hash approaches zero. The trust model is Bitcoin's own hash rate.
PowForge Witness (PFWIT) puts an HTTP endpoint in front of this pipeline.
How it works
Every 10 minutes, the PFWIT pipeline:
- Collects all SHA-256 hashes submitted since the last batch
- Builds a Merkle tree from those hashes (leaves are the raw hashes)
- Submits the Merkle root to four OTS calendar servers (alice.btc.calendar.opentimestamps.org, bob, finney, catallaxy)
- Stores the batch with each leaf's inclusion path
The OTS calendars aggregate roots from many services and anchor them to Bitcoin roughly every hour. Once a Bitcoin block confirms the calendar's aggregation transaction, every root in that batch has a provable timestamp tied to that block height.
For individual hashes, the proof chain is:
your_hash → Merkle inclusion path → batch_root → OTS proof → Bitcoin block header
The endpoint
curl -s https://captcha.powforge.dev/api/pfwit/certificate/YOUR_SHA256_HEX
Replace YOUR_SHA256_HEX with the 64-character hex SHA-256 of whatever you want to timestamp. The response looks like this:
{
"pfwit_version": 1,
"found": true,
"hash": "a3f9...",
"batch_id": 4,
"merkle_root": "7e2a...",
"leaf_index": 12,
"merkle_proof": ["ab3c...", "11d4...", "..."],
"anchored_at": "2026-05-23T14:03:11.000Z",
"ots_status": "submitted",
"ots_proof_hex": "004f...",
"ots_download_url": "https://captcha.powforge.dev/api/witness/proof/4",
"verify_command": "curl -s \"https://...\" -o proof.ots && ots verify proof.ots"
}
When ots_status is confirmed, the proof has a Bitcoin block attestation. The verify_command in the response is a copy-paste-ready command to independently verify the OTS proof using the ots CLI tool from the OpenTimestamps reference implementation.
Try it now
Pick a file. Hash it. Submit.
# Hash your file
sha256sum myfile.txt
# 3f79bb7b435b05321651daefd374cdc681dc06faa65e374e38337b88ca046dea myfile.txt
# Submit to PFWIT (just the hex, no prefix)
HASH="3f79bb7b435b05321651daefd374cdc681dc06faa65e374e38337b88ca046dea"
curl -s https://captcha.powforge.dev/api/pfwit/certificate/$HASH
If the hash is not yet in a batch, you will get "found": false. Submit the hash to the ingest endpoint first:
# Ingest (add to next batch)
curl -s -X POST https://captcha.powforge.dev/api/pfwit/ingest \
-H "Content-Type: application/json" \
-d "{\"hash\": \"$HASH\"}"
Then wait up to 10 minutes for the next batch cycle, and the certificate endpoint will return your proof.
Verify independently
The whole point is you should not have to trust PowForge to use this. Download the OTS proof file and verify it yourself:
# Install opentimestamps-client
pip install opentimestamps-client
# Download and verify
curl -s "https://captcha.powforge.dev/api/witness/proof/BATCH_ID" -o proof.ots
ots verify proof.ots
When the Bitcoin block is confirmed (1-2 hours after submission), ots verify will tell you which Bitcoin block height attests to the existence of the Merkle root, which includes your hash.
You can then check that block independently on any Bitcoin block explorer. The OTS proof file is self-contained: it contains the Merkle path from the calendar's aggregated root down to the Bitcoin block header, serialized in the standard OTS binary format.
What this is good for
Code signing without a CA. Hash your release binary and get a Bitcoin-anchored timestamp. Nobody can backdate a timestamp that is already in a Bitcoin block.
Research priority. Hash a preprint, submit it, get the OTS proof. If someone claims you copied their work, the Bitcoin timestamp is objective.
Audit logs. Hash a database export or a log file at end-of-day and anchor it. The chain proves you had that exact data at that exact time.
Contract snapshots. Hash the text of an agreement at signing time. Neither party can retroactively claim the document said something different.
What this is not
A database timestamp that says you signed something. A notary service. A legal instrument. It is a cryptographic proof that a specific 256-bit hash was committed to a Merkle tree at a specific time, and that tree root is embedded in the Bitcoin ledger. The legal weight of that proof depends entirely on jurisdiction and context. On its own it is a mathematical fact. What that fact is worth to a court is a separate question.
The falsifier
I am filing a hypothesis: at least one publisher requests a witness retrieval via GET /api/pfwit/certificate/:hash by 2026-06-22. If nobody outside my home IP calls that endpoint in 30 days, the hypothesis is falsified and I will say so explicitly. Progress on this hypothesis is visible by checking the endpoint — if it responds, the service is live.
If you try it and it works, or does not work, I want to know. Open an issue at the GitHub mirror or reply here.
All code is MIT. The OTS proof format is an open standard. The calendar servers are operated by the OpenTimestamps project and independent parties. The pipeline runs on PowForge infrastructure at captcha.powforge.dev.
Top comments (0)