Flo

Blockchain Anchoring — prove a document existed, without being trusted

Anyone can claim a file is unchanged. An anchor lets a third party check it — against Bitcoin, years later, without asking LedgerFlow anything.

A partner, merchant or internal system submits a file through the external API. LedgerFlow takes its cryptographic fingerprint and anchors that fingerprint into the Bitcoin blockchain via OpenTimestamps, then hands back a portable .ots proof.

The file never leaves the deployment — only 32 bytes of hash do. The proof outlives the relationship: it is verified with open-source tooling against the public blockchain, so it keeps working even if this platform, this company and these servers are gone.

That independence is the entire value. Evidence you have to ask the vendor to confirm is not evidence — it is a reference. This is proof a counterparty, an auditor or a court can check without our cooperation, our uptime, or our continued existence.

See the anchor register →

How an anchor is made — submit, check, stamp, prove

The submitter hashes and encodes the file (left), LedgerFlow validates and records it (middle), and OpenTimestamps commits the fingerprint into a Bitcoin block (right) — after which the proof comes back and stands on its own.

  • Submit — one authenticated POST: file name, MIME type, the base64 payload, and the submitter's own SHA-256 of it.
  • Check — the server re-hashes what it actually received and compares. Any disagreement aborts the submission entirely.
  • Stamp — the 32-byte digest (never the file) is queued to the OpenTimestamps calendar, which aggregates thousands of digests into one Bitcoin transaction. Anchoring costs a fraction of a cent per proof because everyone shares the block space.
  • Prove — when the block confirms, the proof is upgraded, the block height is recorded, and the .ots file becomes downloadable — and emailable to its owner.

The hash custody chain

Most systems hash whatever arrives and call it proof — which silently anchors corrupted bytes if anything went wrong in transit. Anchoring a damaged file is worse than not anchoring at all: you now hold durable, verifiable proof of the wrong thing. LedgerFlow makes the submitter commit first:

  1. You state the fingerprint of the file you are sending.
  2. The server computes the fingerprint of the bytes it actually received.
  3. They must match. If they do not, the submission is rejected outright — nothing is stored, nothing is anchored, no quota is consumed — and both values are returned so the caller can tell a transport problem from a client-side bug.

On an accepted anchor both values are kept, and the platform re-asserts that agreement at rest. The result is an unbroken evidential line from the submitter's own machine to a Bitcoin block.

What a proof proves — and what it does not

Being precise here is what makes the evidence credible in a dispute.

It proves that these exact bytes existed no later than a specific Bitcoin block. One byte changes and the fingerprint changes and the proof no longer matches. No one — not the submitter, not LedgerFlow, not a regulator — can backdate a block.

It does not prove who wrote the file, that its contents are true, or that it is original. It is existence and integrity at a point in time, not authorship or authenticity.

Typical uses: settlement and reconciliation files, statements, signed agreements, KYC evidence packs, model or configuration snapshots, audit exports — anything where "this is what it said on that day" is the question that matters.

Five calls — the whole integration

External parties reach anchoring on the dedicated tenant-facing API surface — plain HTTPS and JSON, no SDK, one bearer token. Internal operators see the same anchors through the admin pages.

Call What it does
anchor_submit Anchor a payload — returns the anchor id and the server-computed hash
anchor_list The caller's own anchors, newest first, filterable by status
anchor_get Full detail: status, timestamps, Bitcoin block height, both hashes
anchor_proof The .ots proof file, base64 — for offline verification
anchor_verify Re-hash supplied bytes against the stored fingerprint

An anchor moves pending → submitted → confirmed; a submission that the calendar rejects lands on failed with a message. There is no webhook — poll anchor_get (hourly is ample; Bitcoin confirmation takes hours, not seconds).

Every 64-bit id is returned as a JSON string, so integrations in JavaScript and other float64 languages cannot silently corrupt it.

Limits and safeguards

Anchoring is an authenticated, quota'd, rate-limited endpoint that accepts large bodies — so it is fenced on every axis:

  • 10 MB per payload, enforced in the API; the edge caps the HTTP body independently.
  • 20 anchors per account per UTC day, serialised per owner so concurrent submissions cannot overshoot the quota.
  • Rate and connection limits per client IP at the proxy, on a dedicated zone rather than the general API zone.
  • Notifications only ever go to the account's own address — a submitter cannot direct platform-signed mail anywhere else, so the endpoint can never be used as an authenticated relay.
  • Rejections cost nothing — an invalid submission stores no row, consumes no quota, and creates no anchor.

Ownership and privacy

Every anchor belongs to the account that created it, enforced by record-level security and by an ownership check on each call. Asking for someone else's anchor and asking for one that does not exist return the same answer — so the API never even confirms that another party's anchor exists. Competitors sharing your platform cannot probe each other's activity.

Only the fingerprint travels. The payload is never sent to the calendar, to Bitcoin, or to any third party, and it is never attached to the confirmation email — that carries the proof and a small JSON descriptor only.

The payload is retained inside the deployment so a later anchor_verify can re-check it. A hash protects integrity, not confidentiality: short, guessable content can be brute-forced from its hash, so treat anchoring as tamper-evidence, not as a privacy control.

Verify it yourself — the part that makes it evidence

A proof that only LedgerFlow can check is not proof. Anyone holding the file and the .ots can verify it with the open-source client, against the public blockchain:

pip install opentimestamps-client

shasum -a 256 report.csv     # must equal the anchored fingerprint
ots verify report.csv.ots    # → "Bitcoin block N attests existence as of <date>"

The client hashes the file, walks the proof up to the Bitcoin merkle root, and checks that root against the chain — through public Electrum servers by default, or against your own full node. Alter the file and the first step fails; forge the proof and the second does. Neither step involves LedgerFlow, which is precisely the point: the evidence does not depend on the platform that produced it.

Two anchors, one pipeline

LedgerFlow anchors two different things through the same proven machinery:

  • The balance chain — on a schedule, the platform hashes every account's chained row hash into a single root and anchors that, making the ledger's own history tamper-evident. Nobody submits it; it is the platform proving itself.
  • Payload anchoring (this page) — an authenticated party submits arbitrary content and anchors it on demand, owning the result.

Below the point where a fingerprint is produced, everything is shared: the same anchor log, the same queue, the same calendar, the same proof upgrade and diagnostics, the same .ots export. One hardened path, two sources of truth — which is why a new anchoring use case costs a digest source rather than a new subsystem.