Thousands of anchored documents, one download: exporting proofs in bulk

Anchoring one contract is easy: hash it, send the hash, keep the proof. Anchoring every invoice, delivery note or ticket a business produces is a different job. After a year you have hundreds of thousands of proofs, and one day an auditor, a court or a collection agency asks for the evidence behind a whole month of them. Downloading proofs one at a time is not an answer. This post shows how to get them out of TrustBeat in bulk, what the files contain, and why none of them need TrustBeat to be checked later.

Getting thousands of hashes in

Only hashes ever leave your systems — TrustBeat never sees or stores the documents. The batch endpoint takes up to 1,000 hashes per request (Developer plan and above). Give each one a client_ref: your own invoice number or document ID. It comes back in every export, and it is how you will find the right proof for the right file years from now.

curl -s https://api.trustbeat.eu/v1/anchor/batch \
     -H "Authorization: Bearer $TRUSTBEAT_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"hashes": [
           {"hash": "5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03",
            "client_ref": "invoice-2026-10-0001"},
           {"hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
            "client_ref": "invoice-2026-10-0002"}
         ]}'
# → 202 {"submission_id": "...", "accepted": [...], "total": 2}

Every ten minutes, all hashes submitted since the last run are combined into a Merkle tree, and its root gets one qualified RFC 3161 time-stamp. Each document's proof is that time-stamp plus the short path from its hash to the root. That is why volume is cheap: a thousand documents share one qualified time-stamp, and each proof still stands on its own.

Getting the proofs out: four ways

1. In the portal: Activity → Download ZIP

The Activity page lists everything you have anchored. Pick a date range and press Download ZIP to get one JSON proof bundle per anchored item, or Export CSV for an index: ID, hash, status, submission and anchoring time, label and client_ref. The CSV is the table of contents that maps each proof back to your own records. This is the quickest route for an occasional request covering a few hundred or a few thousand documents.

2. From the API: proofs plus evidence records

GET /v1/proofs/export returns the same ZIP to a script, and with evidence_records=true it adds the RFC 4998 evidence record (.ers) of each document anchor — the standard format for long-term proof of existence, about 2 KB per document.

# Every proof for one day, plus the RFC 4998 evidence record of each document anchor
curl -s -H "Authorization: Bearer $TRUSTBEAT_API_KEY" \
  "https://api.trustbeat.eu/v1/proofs/export?from=2026-10-01T00:00:00Z&to=2026-10-01T23:59:59Z&evidence_records=true" \
  -o trustbeat-proofs-2026-10-01.zip

unzip -l trustbeat-proofs-2026-10-01.zip
#   trustbeat-proof-01M5….json              one proof bundle per anchor
#   trustbeat-evidence-record-01M5….ers     one RFC 4998 evidence record per document anchor

One request covers up to 30 days, and only anchored items are included — anything still waiting for its batch is skipped, so export a period once it is over. This export is meant for occasional requests. If you anchor tens of thousands of documents a month, do not pull them yourself: use daily packages.

3. At high volume: a package for every day, built for you

With daily evidence packages, TrustBeat builds one archive per day of everything you anchored that day, about six hours after the day ends, once every evidence record in it is final. Nothing to schedule or page through on your side: you list the packages and download them.

# The daily packages for October
curl -s -H "Authorization: Bearer $TRUSTBEAT_API_KEY" \
  "https://api.trustbeat.eu/v1/packages?from=2026-10-01&to=2026-10-31"
# → per day: status (READY once built), anchor_count, its parts with size and sha256, expires_at

# Download a part — the API redirects to a 15-minute link — and check it against its sha256
curl -sL -H "Authorization: Bearer $TRUSTBEAT_API_KEY" \
  "https://api.trustbeat.eu/v1/packages/<id>/parts/1" -o trustbeat-2026-10-01.zip
sha256sum trustbeat-2026-10-01.zip

A package is organised by anchoring batch, so each qualified time-stamp is stored once, not once per document, and it carries its own checksums and verification guide:

manifest.json          the day, counts, the SHA-256 of every part
checksums.txt          the SHA-256 of every file in the package
VERIFY.md              how to verify everything offline, step by step
batches/<batchId>/
  batch.json           Merkle root, tree size, TSA, anchoring time
  anchor-token.der     the batch's qualified RFC 3161 time-stamp, unmodified
  evidence-token.der   the time-stamp behind the evidence records
  proofs/<id>.json     one proof per document
  records/<id>.ers     one RFC 4998 evidence record per document

A package's day is the day its batches were anchored, in UTC — a hash submitted at 23:58 is anchored in the midnight batch and belongs to the next day. Packages stay downloadable for a limited period (90 days unless agreed otherwise), so copy each one into your own archive. Daily packages are switched on per account: ask us and tell us the day to start from.

4. For long-term archiving: the preservation export package

If the evidence has to stay checkable for years, or move to another provider one day, use the export-import package (ETSI TS 119 511, clause 7.16). It is available in the portal under Preservation Export (pick a month) and from the API:

curl -s -D headers.txt -H "Authorization: Bearer $TRUSTBEAT_API_KEY" \
  "https://api.trustbeat.eu/v1/preservation/export?from=2026-10-01T00:00:00Z&to=2026-11-01T00:00:00Z" \
  -o trustbeat-export-2026-10.zip

# The package's SHA-256, as TrustBeat recorded it, and as you received it
grep -i x-package-sha256 headers.txt
sha256sum trustbeat-export-2026-10.zip
manifest.json                     every object: hash, client_ref, times, profile, preserve_until
objects/<id>.ers                  its RFC 4998 evidence record, validation data embedded
trusted-lists/<territory>-<n>.xml the signed EU Trusted Lists in force at each time-stamp
README.txt

This package carries everything needed to validate the evidence with nothing but the files: each evidence record includes the time-stamping authority's certificates and their revocation status as captured at the time, and the signed EU Trusted Lists show that the authority was qualified when it stamped. Every package we release is recorded, with its SHA-256 — the same value you get in the X-Package-SHA256 header. It covers document anchors made since 2026-09-14; for older anchors, logs and AI decisions, use the proof export above.

None of it needs TrustBeat to verify

This is the point of exporting at all. Once the files are on your side, whoever checks them later does not need an account, our API or our word:

  • A JSON proof bundle is self-contained: hash the document, recompute the Merkle path, and check the RFC 3161 token with openssl. Manual verification walks through it, and our public verification repository has a script that does it.
  • An .ers evidence record can be checked in the European Commission's DSS validation WebApp: upload the record, add the original file, and choose to send only its SHA-256. A valid record shows PASSED with a qualified time-stamp.

A routine that works

  • Send a client_ref with every hash, so each proof maps to one of your documents.
  • Export each closed period, or at high volume take the daily packages, and store them next to the documents they cover.
  • Keep the original files. A proof shows that a file existed unchanged; it cannot replace the file.
  • Once a month, check one proof at random in the DSS WebApp, so the first check is not in front of an auditor.
  • For records you must keep for years, take the preservation export package as well.

Anchoring a large volume? Ask us to switch on daily packages — we are happy to help you set up the routine. Or start free with 100 anchors a month, no card.