ยทUses

What you can prove with Satsignal.

Three verifiable outcomes, three live primitives, one bearer-auth API. Each outcome is an audit-trail artifact an outside auditor or regulator can verify without trusting Satsignal — anchored on the public Bitcoin SV chain, verified in any browser. Works for any file, too.

All API examples below are against https://app.satsignal.cloud; we elide the host in body copy.

01Three outcomes

Three things a proof establishes.

Each maps to a live API primitive. Two of them — what an agent was allowed to do, and what evidence it used or produced — build in selective disclosure: reveal one component or one row to an auditor while the rest stay sealed.

1

What an agent committed to

Anchor a hashed decision before anyone reveals theirs. Sealed bids, model evaluations, prediction markets, multi-agent voting — nobody, including the operator, can rewrite when the commitment was made.

How: commit-reveal →
Worked demo: Sealed Bid →

2

What an agent was allowed to do

Anchor a snapshot of the system policy, user instruction, tool permissions, budget, and model config the agent was running under. Auditors verify any single component without seeing the others.

How: policy snapshots →

3

What evidence it used or produced

Anchor a batch of up to 10,000 items in one on-chain proof. Selective disclosure: any holder later proves a single item was in the batch — without revealing the others. Right pattern for high-volume agent runs; same shape via merkle-row-sealed-v1 for tabular data.

How: manifest proofs →

Two worked demos with real on-chain proofs: the Agent Evaluation demo anchors a policy snapshot before a real eval, then anchors a result manifest after; the Sealed Bid demo anchors five sealed bids as one Merkle root, then discloses a single bidder’s row to an auditor while the other four stay HMAC-sealed.

02Commit-reveal

Commit now, reveal later — without trusting a clock.

Sealed bids, evaluation scores, model benchmarks, prediction markets, multi-agent voting: anywhere two parties need to commit BEFORE either reveals, the public chain gives a stronger external timestamp property than an operator-controlled log. Anchor a hash now; publish the payload later. Anyone can prove the commitment predates the reveal — without a trusted timestamp service, without either party being online, without anyone able to edit history later.

Step 1 — Commit

Wrap, hash, anchor.

Wrap your payload (a bid, a score, a vote — anything JSON-shaped) with a fresh 32-byte random nonce. Canonicalize. Hash with SHA-256. Anchor the hash via POST /api/v1/anchors with category: "commitment". Keep the wrapped form private.

Step 2 — Reveal

Publish the wrapped form.

After the deadline (the auction closes, the evaluation ends, the prediction window expires), share the wrapped form. The nonce is what makes this safe: without it, an attacker could enumerate likely values; with it, the hash binds you to one specific committed thing.

Step 3 — Verify

Anyone re-hashes and checks.

A verifier canonicalizes the revealed wrapped form, SHA-256s it, and confirms the hash matches the on-chain commitment. The block timestamp proves the commit predates the reveal. No trust in either party, no trust in Satsignal.

Why this only works on a public chain. Operator-controlled infrastructure (signed logs, append-only DBs, transparency logs) can almost match what Satsignal does — for most use cases. But commit-reveal is the place where a public chain is uniquely valuable: the threat model includes the operator, the agent platform, and any single service. With a chain anchor, even the issuer can’t rewrite when you committed.
Helpers. Drop-in libraries that produce the same canonical bytes byte-for-byte across runtimes:
  • /commit_reveal.py — Python 3 stdlib only. CLI with commit / reveal / verify subcommands.
  • /commit-reveal.js — ES module for browser + Node 18+. Exports makeCommit and verifyReveal.
The two implementations cross-verify: a Python commit reveals cleanly to a JS verifier and vice versa.
03Policy snapshots

Prove what an agent was allowed to do at the time it acted.

An incident review — a regulator, a customer, a court — will ask: what system policy was in force, what instruction was the agent responding to, which tools could it call, what was its budget, and which model and config was it running? A policy snapshot answers all five at once with a single on-chain commitment.

The snapshot is a JSON object with a SHA-256 fingerprint of each component. Anchor the snapshot via POST /api/v1/anchors with category: "policy_snapshot"; the proof binds to all five hashes simultaneously, so an auditor with just the system prompt can verify the system_policy_hash matches the proof without ever seeing the budget config — selective disclosure of the agent’s configuration.

The five canonical fields (any subset is fine).
  • system_policy_hash — sha256 of the system prompt or policy document.
  • user_instruction_hash — sha256 of the user-supplied task or query.
  • tool_permissions_hash — sha256 over the canonicalized tool list / call permissions.
  • budget_limits_hash — sha256 over the canonicalized budget caps (USD, tokens, time, etc.).
  • model_config_hash — sha256 over the canonicalized model + sampling parameters.
Step 1 — Snapshot

Hash each component, build the snapshot.

Before the agent acts, the runtime hashes the five components and assembles a snapshot JSON. The whole snapshot is canonicalized + sha256’d — that hash is what gets anchored.

Step 2 — Anchor

POST with category=policy_snapshot.

Hand the snapshot’s sha256 to the existing /api/v1/anchors endpoint. The proof binds the on-chain timestamp to the entire five-field configuration. Save the proof’s proof_id alongside every action the agent takes from this point on.

Step 3 — Audit

Anyone with one component can verify.

An auditor receives the snapshot JSON and any of the original components. They re-hash and check — without ever needing to see the others. The chain timestamp proves the configuration predates the action.

Helpers + worked example.
  • /policy_snapshot.py — Python 3 stdlib-only CLI. Subcommands: hash-component, build, verify. Selective-disclosure verify (one field at a time) just works.
  • /example_agent_snapshot.py — runnable agent example. Hashes its own five components, optionally POSTs the snapshot to /api/v1/anchors when SATSIGNAL_API_KEY is set, then takes a (deterministic) action. Replace the decide() stub with a real agent loop and you have an audit-trail-clean configuration anchor in ~30 lines of glue.
Same shape as research pre-registration. Anchor the eval set, system prompt, scoring rubric, and decoding params before a run; anchor the result manifest after. Anyone reading the published outputs later can confirm the design was committed before the data — the structural property pre-registration gives in clinical trials and replication studies, applied to model evaluations. Worked framing for AI evaluation research: Pre-registration and selective disclosure for AI evaluations →.
04Manifest proofs

Anchor a batch — reveal one item at a time.

Per-action anchoring doesn’t scale. Manifest-backed proofs are the structural answer. Up to ten thousand items (decisions, tool calls, outputs, evidence files) collapse into one proof — and any holder can later prove a single item was in the batch without revealing the others.

Each item is just a {label, sha256_hex} pair. The server combines the leaves into a Merkle tree and anchors the root. The bundle ships every leaf with its inclusion path, so a recipient who only sees one item can still verify it belongs to the proof — no need to see the other 9,999.

Step 1 — Batch

Hash each item, collect the leaves.

Your client hashes each artifact (a tool-call log, a page of output, an evidence file) into a leaf with a readable label. Only the leaf fingerprints reach our server — the underlying bytes stay with you.

Step 2 — Anchor

POST the leaves; one chain anchor.

Send the leaves to /api/v1/anchors as {items: [...]}. The server combines them into a Merkle tree and anchors the root. One on-chain anchor covers up to 10,000 items.

Step 3 — Disclose one item

Recipient verifies that one item.

Hand a single item plus its inclusion path to whoever needs to verify it. They reproduce the leaf hash, walk the path to the root, and confirm the root matches what was anchored on chain. The other 9,999 stay private.

When this is the right shape. Long-running agents. Hourly tool-call logs. Evaluation runs that produce hundreds of judged outputs. Evidence packages where each file is sensitive but the overall manifest is the deliverable. The common thread: many private items, one public commitment, selective disclosure later.
Tabular data — named schemes. For tables (CSV rows, JSON records, eval results, vote ledgers) where the disclosure unit is a single row, two documented schemes ride on top of the API: merkle-row-v1 for high-entropy rows, and merkle-row-sealed-v1 (HMAC-per-leaf with HKDF salts) for low-entropy ones where a plain SHA-256 leaf would be brute-forceable. Both verify selectively — revealing one row never requires revealing any other.
Scheme reference, helpers, samples. Full byte-level spec, when-to-use guidance, and Python + JS helpers: docs §sealed-rows. Live row-scheme samples anchored on chain: /samples/merkle-row/RECEIPTS.md. For embedding a BSV anchor inside an AAR, C2PA, RFC 3161, or Visa TAP proof: /samples/chain-anchor/RECEIPTS.md — 5 live samples; spec at chain-anchor/v1.
05What to look for

Four properties worth checking when you evaluate a proof format.

Plenty of products in this space stop at “a hash existed at a moment.” That’s table stakes; what comes after is where formats diverge. Four properties that matter operationally:

1

Selective disclosure of low-entropy rows

A timestamp on a 50KB document is fine; a timestamp on a single bid amount, yes/no vote, or one row of a small enum leaks the answer to anyone who can enumerate the candidate set. Look for a scheme that HMACs each leaf under a per-leaf salt so the holder can reveal one row of a sealed table without unsealing the others.

Worked demo: five sealed bids, one row revealed →
Scheme reference →

2

Verification that doesn’t depend on us

If a proof only verifies through the issuer’s servers, the issuer staying online is part of your trust story. Anchoring on a public chain pushes that dependency onto the chain itself. The shape to look for: stdlib-only verifier, public-explorer lookup, no SDK requirement, no account.

In-browser verifier →

3

Byte-identical helpers across runtimes

If the proof format quietly canonicalizes differently in Python and JavaScript, a Python-anchored commitment won’t verify in JS and the spec is the issuer’s SDK rather than its docs. Look for a published byte-level spec and matching helpers in at least two runtimes that produce the same canonical bytes from the same inputs.

Helpers reference →

4

Proofs small enough to print, scan, or text

Most chain-anchored proof formats ship a multi-megabyte signed PDF or a JSON-LD certificate envelope. That fits in an inbox; it doesn’t fit on a paper invoice, a printed lab result, or in a QR code on a field inspector’s clipboard. Look for a format whose entire bundle is small enough to print on the artifact it’s proving — under a kilobyte for typical commitments. The mobile-first behaviors (scan-to-verify, deep links, offline distribution) fall out of the size for free.

Mobile + edge integration guide →

06For any file

The same proof works for ordinary files.

The three outcomes above are the agent-shaped wedge. Satsignal still does what it always did: tamper-evident proofs for any file, with format-aware fingerprints so a re-saved PDF or re-exported CSV still verifies against the content hash even when the byte-exact hash changes.

FileContent fingerprintSection breakdown
PDFextracted text, normalizedper page
JSONRFC 8785 canonicalper top-level key
CSVRFC 4180 normalizedper data row
Source / textNFC-normalized, line-ending stableper line
ZIP / DOCX / XLSXentry manifestper contained file
Image (JPG/PNG/WebP)raw pixel data, metadata strippedper tile
Anything elsebyte-exact hash onlyn/a

See the proof gallery → for one anchored sample per format, each linking to a live on-chain proof.

07Live demos

Try the primitives in your browser.

Each demo walks through a real on-chain commitment we anchored on BSV mainnet — the bundle and payload are downloadable on the page and verifiable client-side, without an account or uploading your data.

Sealed bid

Commit a hidden bid, reveal it later, prove you didn’t change your mind in between. The commit-and-reveal primitive from § 02, end to end.

Eval pre-registration

Anchor an evaluation manifest before the run; reveal the single scored row when results land. The selective-disclosure primitive from § 04, end to end.

All demos

The full live-demo index, including future additions.