UpveraTechnology
Guide· For foundersDay Roots

How to timestamp a file with OpenTimestamps

Short answer

Install the OpenTimestamps client, run ots stamp on the file, and keep the small .ots file it writes next to the original. Only a digest of the file leaves your machine, sent to public calendar servers that anchor it in a Bitcoin block within a few hours. Run ots upgrade after that, so the proof carries the full path and no longer depends on the calendars.

Updated
Reading
4 min
The need
Get independent proof that a file existed by a certain time, without publishing the file.
Plain text
/guides/timestamp-a-file-opentimestamps.md

#What you get, and what leaves your machine

A timestamp proves that a file's exact bytes existed no later than a certain time. You keep the file; anyone you later show it to can check the date with free, open tools and without trusting you.

The client hashes the file locally with SHA-256, adds a random value to the digest and sends the result to a few public calendar servers. The calendars collect many digests, combine them into one value and put that value into a Bitcoin transaction. You never send the file, and you don't need a wallet or coins.

#Step by step

1. Install the client

pip3 install opentimestamps-client
ots --version

We used version v0.7.2.

2. Stamp the file

ots stamp notes.txt

The client reports each calendar it reached:

Submitting to remote calendar https://a.pool.opentimestamps.org
Submitting to remote calendar https://b.pool.opentimestamps.org
Submitting to remote calendar https://a.pool.eternitywall.com
Submitting to remote calendar https://ots.btc.catallaxy.com

It writes notes.txt.ots beside the file, under a kilobyte. To stamp several files, list them all, as in ots stamp a.txt b.txt; each file gets its own .ots.

3. Look inside the proof

ots info notes.txt.ots

The first line is the digest the proof commits to, which should equal shasum -a 256 notes.txt. The lines after it are hash operations, and each path ends in PendingAttestation with a calendar's address. Pending means a calendar has promised to anchor the digest but hasn't yet.

4. Upgrade it a few hours later

ots upgrade notes.txt.ots

Run right after stamping, the client says each calendar is still pending and ends with Failed! Timestamp not complete. That is expected. Once a calendar's transaction is in a Bitcoin block, the same command fetches the missing steps, writes them into your .ots and keeps the old file as .bak. From then on the proof can be checked against Bitcoin alone, even if every calendar goes offline.

5. Keep both files together

The proof is worthless without the original bytes. Store the file and its .ots side by side, and don't open and resave the file: a different line ending is a different digest.

#A real proof, before and after the upgrade

Upvera's day file for October 19, 2026 is public, with its proof beside it. The first version of 2026-10-19.json.ots was 910 bytes, and ots info showed four paths, each ending in a PendingAttestation. The next day's run upgraded it in place. The file grew to 4,883 bytes, and its four paths now end in BitcoinBlockHeaderAttestation for blocks 972290, 972291, 972300 and 972315. Both versions are in the repository's history, so you can compare them yourself.

#Common mistakes

  • Never upgrading. A pending proof depends on the calendars keeping their promise. Upgrade once, and keep the upgraded copy.
  • Changing the file after stamping. Even a trailing newline breaks the match. Stamp the final version, or stamp each version.
  • Publishing the .ots of a guessable file. The proof contains the file's SHA-256. For a short or predictable file, such as a yes or no answer, someone holding the proof could test guesses against it. Keep such proofs private until you reveal the file, or add random text to the file before stamping.
  • Reading the time as a creation date. A timestamp is an upper bound. The file may be much older than the block.
  • Assuming the stamp says who made the file. It doesn't. Sign the file as well if authorship matters.

#Questions

How long does it take?

A few hours, according to the client's documentation. Calendars batch many digests into one transaction rather than paying for one per file.

Do I need my own Bitcoin node?

Not to stamp or upgrade. To verify independently, you need a node the client can reach, and a pruned node is enough. See How to verify an OpenTimestamps proof.

What if I lose the .ots file?

You can stamp the file again, but the new proof will show the later date. The original date can't be recovered without the original proof.

Can I stamp a folder?

Stamp a file that lists the folder's contents with their digests, or stamp each file. A single digest over a list is how Upvera stamps a whole day.

#How Upvera does it

Upvera Day Roots publishes one canonical JSON file per day to upvera-co/ledger-roots. The publishing job stamps each new day file with the official client and, on a later run, upgrades earlier proofs and commits the larger .ots. The file for a day carries that day's root and the digest of the day before, so one stamp also fixes everything the day's root covers. The design is in the Day Roots report.

#Sources