Re-hash an eligible snapshot. Check the bytes yourself.
A snapshot can be re-hashed only when that record exposes both a source archive URL and a SHA-256 digest. This runbook shows how to compare those values with a standard hashing tool. Availability is record-specific; a digest match checks archive bytes, not parsed rows or row-level signature linkage.
Bytes, not promises.
Some records in the public snapshot endpoint expose a content_hash, hash_algorithm, and source_archive_url. For one of those records, a 64-character match supports two limited conclusions:
- Digest equality — the archive you fetched produces the digest recorded on that snapshot record.
- Recorded source context — the endpoint names the source identifier, observation date, and archive URL associated with that digest.
It does not validate parsed rows, transformations, current upstream availability, or a signature. The separate snapshot-chain reference at /docs/chain reports chain artifacts independently. Chain-artifact presence and row provenance are reported as separate fields.
Five steps, one command that matters.
On macOS and Linux, shasum -a 256 (or sha256sum) is all you need. On Windows, use certutil -hashfile snapshot.bin SHA256.
# 1. Open the snapshot record you care about.
# Browse https://fonteum.com/trust/integrity or request the record directly:
# https://fonteum.com/verify/<snapshot_id>
# Continue only when content_hash and source_archive_url are populated.
# 2. Fetch the source archive named by that record.
curl -L -o snapshot.bin "<source_archive_url from the record>"
# 3. Confirm the byte count matches content_size_bytes (cheap pre-check).
wc -c snapshot.bin
# 4. Re-hash the bytes with the same algorithm.
shasum -a 256 snapshot.bin
# → 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08 snapshot.bin
# 5. Compare the 64-character hex with the record's content_hash.
# A match means the fetched bytes produce that digest. It does not validate
# parsed rows, transformations, or a row-level signature.Same check, in code.
Any language with a SHA-256 implementation can compare the downloaded bytes with a populated digest. Node, stdlib only:
// Node 20+ (stdlib only) — re-hash a downloaded archive and compare.
import { createHash } from 'node:crypto';
import { readFile } from 'node:fs/promises';
// A populated content_hash from https://fonteum.com/verify/<snapshot_id>
const PUBLISHED = '<paste the 64-char content_hash here>';
const bytes = await readFile('snapshot.bin');
const recomputed = createHash('sha256').update(bytes).digest('hex');
console.log('recomputed:', recomputed);
console.log('matches: ', recomputed === PUBLISHED.toLowerCase());
A mismatch is a signal, not a dead end.
A non-matching hash usually means one of the following — work down the list before concluding the data drifted:
- Partial download — the byte count from
wc -cdoes not equalcontent_size_bytes. Re-fetch. - Upstream republished the file — federal portals sometimes re-issue an archive in place. A current download may then differ from the digest recorded for an earlier snapshot.
- Wrong archive — confirm you fetched the exact
source_archive_urlrecorded on the snapshot response, not a sibling or index page. - Transform vs. raw — the hash covers the upstream source archive, not the post-ingest parsed table. Hash the archive, not the rendered dataset.
If the archive is byte-complete, fetched from the recorded URL, and still doesn’t match, that is exactly the kind of discrepancy this system exists to surface — email security@fonteum.com with the snapshot id.