> Source: https://upvera.tech/guides/timestamp-a-file-opentimestamps/
> 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.

[Guides](/guides/)How-to

Guide · · For founders · Day 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.

## 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

```bash
pip3 install opentimestamps-client
ots --version
```

We used version `v0.7.2`.

### 2\. Stamp the file

```bash
ots stamp notes.txt
```

The client reports each calendar it reached:

```text
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

```bash
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

```bash
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](/guides/verify-opentimestamps/).

### 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](https://github.com/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](/roots/).

## Sources

-   [OpenTimestamps client](https://github.com/opentimestamps/opentimestamps-client): installation, commands and privacy notes.
-   [opentimestamps-client on PyPI](https://pypi.org/project/opentimestamps-client/): the package installed above.
-   [opentimestamps.org](https://opentimestamps.org): a browser stamper and verifier.
-   [upvera-co/ledger-roots](https://github.com/upvera-co/ledger-roots): the day files and proofs in the example.

## Related

[Guide**How to verify an OpenTimestamps proof**Check an .ots proof with the official client, read pending and success results, and know what a timestamp proves and what it does not.Anyone checkingRead](/guides/verify-opentimestamps/)[Guide**How to verify a hash chain of daily records**Verify a real chain of daily digests, step by step, with about 20 lines of JavaScript you can run in your browser.Anyone checkingRead](/guides/verify-hash-chain/)[UTR-26-03**Day Roots**Sealed every minute. Rooted every day.System reportRead](/roots/)
