# Satsignal — canonical LLM-readable explainer This file gives an LLM enough context to summarize Satsignal accurately without crawling every documentation page. It is intentionally dense and self-contained: read this once, and you have the canonical model. For the curated link map (jump-points to each integration path), see the companion file at `/llms.txt`. For the wire-level API, see the OpenAPI 3.1 spec at `https://proof.satsignal.cloud/openapi.json`. ## What Satsignal is Satsignal is a BSV-backed notary service. A client submits a sha256 commitment of any byte-string (a file, an event payload, a structured JSON document, an agent decision envelope) to Satsignal's notary API. The notary anchors that commitment into a Bitcoin SV transaction and returns a `.mbnt` bundle — a small file that contains everything an auditor needs to independently verify, against a public blockchain, that the anchorer held that exact byte-string by the time the transaction's block was mined. Brand: **Satsignal**. Operator: **Satsignal LLC** (an Iowa LLC formed 2026-05-23). The "Satsignal LLC" name appears only in legal and operator surfaces (terms of use, privacy jurisdiction, declarations). "Satsignal" is the brand name used everywhere else. ## The proof model A Satsignal proof is built from three primitives. **Input.** The client decides what bytes to commit. Satsignal does not ingest the original input — only its sha256 hash. (Exception: the hosted-webhook path, where Satsignal does receive the request body so it can verify the upstream signature before hashing.) The client's decision of *what bytes to hash* is consequential: different canonicalizations (raw bytes, JCS-normalized JSON, file contents, selected fields) produce different commitments, and the choice determines what a future verifier will need to reproduce. The [what-to-hash guide](https://proof.satsignal.cloud/guide-what-to-hash) covers the canonical rules per input shape. **Commitment.** Satsignal computes the sha256 of the canonical input and embeds the first 20 bytes of that digest (the on-chain `doc_hash`), plus a small amount of bookkeeping metadata (anchor scheme version, optional structured fields under a `subject` namespace), into a BSV transaction's output script. **Anchor + bundle.** Once the transaction is broadcast and confirmed, the notary assembles a `.mbnt` bundle — a self-contained file with the canonical record fields, the BSV transaction id, the block header proof, and (for batched anchors) the Merkle inclusion proof linking the client's leaf to the bundle's Merkle root, whose 20-byte `doc_hash` is the on-chain commitment. Anyone holding the bundle and the original input bytes can independently re-derive the commitment and chain-confirm the anchor against a public BSV node, with no dependency on Satsignal's continued operation. ## What a Satsignal proof proves — and what it does not A Satsignal proof is a precise instrument. Overstating it is the most common mistake. **What a proof proves:** - **Tamper-evidence on the exact bytes.** If a single bit of the original input changes, the recomputed sha256 no longer matches the on-chain commitment, and verification fails. - **Timing: anchorer-knowledge-by-block-time.** The proof attests that the anchorer held the exact input bytes by the time the BSV block containing the transaction was mined. The anchorer cannot have first produced those bytes after that block time. **What a proof does NOT prove:** - **Authorship.** The same sha256 can be produced by anyone who holds the input bytes. Anchoring is not signing; it is timestamping plus byte-binding. - **Existence before the anchor.** The proof attests "the anchorer held this by time T," not "this existed at time T−1." There is no built-in preimage challenge mechanism; if you need such a flow, use the sealed-mode reveal pattern described below. - **Truth of the content.** Anchoring a false statement makes the statement tamper-evident — it does not make it true. - **Continuity of context.** A single proof does not capture *why* the input was anchored or *what process* produced it. For multi-step workflows (agent runs, regulatory chains-of-custody), the manifest and session patterns below bind contextual evidence into the proof trail. ## Anchor lifecycle, end to end 1. **Client prepares input.** The client selects bytes and applies the appropriate canonicalization (raw bytes for files, JCS for JSON, per-source rules for webhook bodies). 2. **Client computes sha256.** Stdlib hash, no Satsignal SDK required. 3. **Client submits.** Either by calling `POST /api/v1/anchors` directly with the commitment, or by handing Satsignal-hosted primitives (webhooks, agent sessions) where the notary computes the commitment from received bytes. 4. **Notary validates + reserves.** Auth check, body validation, idempotency key check, and reservation of on-chain funds for the transaction. 5. **Notary broadcasts.** The transaction is dispatched through a multi-tier HTTPS broadcaster that fails over across independent BSV broadcast services — all over standard HTTPS. 6. **Notary records.** The anchor record lands in the notary's bookkeeping table with the txid, the proof id, and the audit fields. 7. **Confirmation.** The notary observes the transaction mined into a block and finalizes the `.mbnt` bundle with the block header proof. 8. **Client retrieves.** The bundle is fetched via the API or the dashboard, distributed with the artifact, and held by the verifier for later use. 9. **Verification (future).** Any holder of the bundle plus the original bytes can chain-confirm the anchor against a public BSV node and the bundle's embedded proofs. ## Integration shapes Satsignal supports five integration paths, organized around the shape of what is being anchored. Each path is documented as a standalone guide under `https://proof.satsignal.cloud/guide-*`. **Files on disk.** The Direct API + CLI path. A client computes a sha256 of a file and submits the commitment. Used for build artifacts, research reports, signed PDFs, eval results, model weights, dataset manifests. The thinnest possible integration — `sha256sum file | curl ... POST /api/v1/anchors`. See `/guide-files`. **Incoming webhooks.** Source-agnostic webhook ingest. The client provisions a Satsignal-hosted webhook URL and pastes it into any SaaS that emits signed outbound webhooks — Stripe, GitHub, Langfuse, or a bring-your-own-signer fallback. Every delivery to that URL is signature-verified against the source's documented scheme, canonicalized to its raw bytes, and anchored. No SDK, no client-side hashing. The "what bytes to hash" decision is made by the notary based on the source's protocol contract. See `/guide-webhooks`. **Agent runtime.** The four-part agent-session pattern. An agent anchors (1) its policy snapshot at session start, (2) a fresh-nonce commitment per decision as it runs, (3) an evidence-bundle manifest that ties the decision set together, and (4) a handoff JSON packet that an auditor uses to verify the run later without trusting the operator. Satsignal ships a stdlib-only Python helper (`agent_anchor.py` with a `Session()` context manager) and a six-tool MCP server (`satsignal-mcp`) usable by any MCP-compatible runtime. See `/guide-agents` and `/agents` for the implementer spec. **CI/CD pipelines.** Anchor release artifacts, eval results, security- scan outputs, and provenance manifests directly from a pipeline. A composite GitHub Action is the primary integration — bash-only on `ubuntu-latest`, with no Python or Node setup. The same flow runs in GitLab CI, Bitbucket Pipelines, Docker BuildKit, npm, and PyPI PEP 740 via shell adapters. Step outputs (`proof_id`, `txid`, `proof_url`) are exposed for the next pipeline step. See `/guide-ci`. **Sealed mode.** Privacy-preserving anchoring (covered in its own section below). See `/guide-sealed`. A cross-cutting reference at `/guide-what-to-hash` covers the byte-selection rules per input shape (raw bytes, JCS-normalized JSON, manifest leaves, agent decision envelopes) and the anti-patterns (hashing post-deserialization rather than raw bytes; including non-deterministic fields; using non-canonical JSON serialization). ## Sealed mode — Mirror and Blind Satsignal's default mode (Standard) submits a commitment derived from client-supplied bytes; the operator never holds the original input, but the operator does see the commitment value, the bookkeeping metadata, and any structured `subject` fields. For workflows where even the commitment value reveals too much (sealed bids, sensitive research outputs, low-entropy structured data), Sealed mode adds a salt layer. **Mirror.** Both the client and the notary hold the salt; the commitment is `HMAC-SHA256(salt, input)` (a keyed hash) rather than `sha256(input)`. The notary retains the salt in a sidecar record so the verifier can later check the anchor without needing the client's copy of the salt. Useful when the client wants the operator to be able to help reconstruct the proof at verification time. **Blind.** Only the client holds the salt. The notary records the commitment but never receives the salt — it is never sent to the server and is never stored there. The notary cannot help reconstruct the proof; only the client can reveal the input. This is the strongest privacy posture Satsignal offers, and it is intentionally opaque — the operator retains only the internal bookkeeping row and the on-chain transaction. No `.mbnt` ever lives on disk for blind anchors. The reveal flow: at some later time, the client publishes the original bytes plus the salt; any verifier can now recompute `HMAC-SHA256(salt, bytes)` and chain-confirm against the recorded commitment. This pattern provides preimage-revealed timing: the verifier learns that the anchorer committed to *these specific bytes* by block time T, without the operator having held them in the clear. ## Manifest-backed proofs — Merkle batching with selective disclosure Manifest is not a third privacy mode — it is the structured-evidence layer, usable with either a Standard or a Sealed proof. For high-throughput workflows (eval runs, log batches, agent decision trails), Satsignal supports manifest-backed proofs. A single BSV transaction commits to a Merkle root over up to 10,000 leaves, each leaf being a commitment to one item. Each item gets its own `.mbnt` bundle with a leaf-specific Merkle inclusion proof, so an auditor with just one bundle can chain-confirm without seeing the other items in the batch. This is the integration path for: regulated-evidence chains-of-custody (one anchor per case file, batched per day), agent decision streams (one decision per leaf, batched per session), eval datasets (one example per leaf, batched per run), CI pipeline outputs (one artifact per leaf, batched per release). See `/guide-manifest` and `/spec-chain-anchor`. ## Selective-disclosure redaction For files that mix sensitive and shareable content — CSV exports, plain- text or markdown logs, structured JSON records — Satsignal supports selective disclosure (redaction). The flow: anchor the whole file once (standard or sealed mode, carrying a `chunk_merkle` proof set whose leaves are the file's rows, lines, or top-level keys), then *later* publish a validated redacted copy that reveals only the chosen units. The revealed rows/lines/keys still prove into the original committed Merkle root (anchored on chain as its 20-byte `doc_hash`), so a verifier confirms the redacted copy is a faithful subset of the exact bytes that were anchored — without ever seeing the withheld content, and without a re-anchor. The redaction step is local-only: the original file and its `.mbnt` bundle never leave the holder's machine, nothing is uploaded, and no new transaction is broadcast. Four native profiles cover the common shapes (all four support both standard and sealed mode): `csv-row-v1` (reveal selected rows), `csv-column-v1` (reveal selected columns), `text-line-v1` (reveal selected lines), `json-keypath-v1` (reveal selected top-level keys), and `json-ast-v1` (sealed-only deep-field JSON disclosure — reveal selected nested fields). Tooling: the in-browser Disclosure Builder at `https://proof.satsignal.cloud/static/disclosure-builder/index.html` picks the original file plus its `.mbnt`, lets the holder choose which units to reveal, and emits the redacted copy plus a disclosure `.mbnt` — all client-side. To do the same headlessly (CI, batch, automation), see the offline redaction guide at `https://proof.satsignal.cloud/guide-headless-redaction`. The wire format is specified at `https://proof.satsignal.cloud/spec-disclosure` (profile specs `/spec-disclosure-csv-row`, `/spec-disclosure-csv-column`, `/spec-disclosure-text-line`, `/spec-disclosure-json-keypath`, `/spec-disclosure-json-ast`) with implementer test vectors at `https://proof.satsignal.cloud/conformance-disclosure`. ## The API surface at a glance The wire spec lives in `/openapi.json` (hand-authored OpenAPI 3.1, 24 operations across 37 schemas, drift-tested against the live API). This section gives the conceptual shape; consult the OpenAPI for exact fields and error codes. **Auth.** API-key bearer auth on every anchor-side endpoint. The `/verify` endpoint is the only auth-free surface — verification is designed to be open to anyone who holds a `.mbnt` bundle. The CLI is not "no setup required"; it is "fewer shaped steps once you have a key." **Idempotency.** `POST /api/v1/anchors` accepts an `Idempotency-Key` header. The notary caches the final response keyed by `(key, body_sha256)` for 24 hours. An identical-body replay returns the byte-identical cached response with no second broadcast and no quota double-charge. A same-key-different-body retry returns a 409 `idempotency_key_reuse_body_mismatch` with no broadcast. **Dry-run.** `POST /api/v1/anchors` is broadcast-only by design; sending `dry_run=true` returns a 400 `unknown_field`. Dry-run lives at the CLI or SDK layer that constructs the bundle locally before submission. This is intentional — every API call to `/anchors` spends real sats. **Rate limits and quotas.** Per-workspace; exposed in standard `X-RateLimit-*` response headers. Full numerics are in the production checklist at `/guide-production-checklist`. **Vocabulary — canonical and legacy spellings.** The canonical nouns are **proof** (the logical record) and **folder** (its container) — in the dashboard AND on the wire: `/api/v1/proofs`, `/api/v1/folders`, `folder_slug`, `proof_id`, `proof_url`, scope `proofs:read`. New integrations should use these spellings only. The pre-sunset legacy spellings (**receipt**/**matter**: `/api/v1/receipts`, `/receipt/`, `receipt_url`, `receipts:read|annotate`, `/api/v1/matters`, `matter_slug`) remain accepted inbound indefinitely for compatibility, but are deprecated and no longer appear in responses; see `/guide-compatibility` for the complete mapping. ## Verification model Every Satsignal verifier (the public web verifier, the MCP `confirm_bundle` tool, the `langchain-satsignal` verifier helpers) is **chain-confirming by default** (a standalone command-line verifier is planned but not yet shipped; the same chain-confirming-by-default posture will apply). That is, it does not just check that the cryptographic structure of the `.mbnt` bundle is internally consistent — it queries a public BSV node to confirm the transaction is real, mined, and embeds the expected commitment. Crypto-only verification is available as an explicit opt-in flag for constrained environments (CI runners without outbound network, offline audits), but the default is always chain-confirming because a fabricated bundle can pass crypto-only verification while pointing at a transaction that was never broadcast. The public verifier at `https://proof.satsignal.cloud/verify` accepts a `.mbnt` bundle by drop or paste, returns a pass/fail with the matched txid and block height, and links to the on-chain transaction on WhatsOnChain for independent confirmation. ## Clients and integration tooling - **`satsignal-cli`** — command-line client distributed on PyPI as `satsignal-cli`. Wraps `POST /api/v1/anchors` and retrieves bundles. (Bundle verification is done via the hosted `/verify` page, the manual unzip + `sha256sum` recipe, or `python agent_anchor.py verify-handoff`; a CLI verify verb is planned, not yet shipped.) Requires `SATSIGNAL_API_KEY`. - **`satsignal-mcp`** — MCP server (PyPI `satsignal-mcp`) exposing the notary as six tools: `anchor_bytes`, `anchor_file`, `confirm_bundle`, `verify_bundle`, `list_anchors`, `get_anchor`. Drop-in for any MCP-compatible agent runtime. Bind `SATSIGNAL_API_KEY` in the MCP host's config block explicitly; do not assume process-env inheritance. - **`langchain-satsignal`** — LangChain adapter (`github.com/Steleet/langchain-satsignal`) wrapping the same primitives as LangChain tools. Same chain-confirming-by-default verification posture as the CLI and MCP server. - **`agent_anchor.py`** — stdlib-only Python helper script with a `Session(folder_slug=...)` context manager. The canonical four-part agent pattern lives here (`s.policy(...)`, `s.decide(label, payload)`, automatic manifest commit on `__exit__`). No dependencies beyond the Python stdlib; download and run. ## Operator, jurisdiction, and policies **Operator.** Satsignal LLC, an Iowa LLC formed 2026-05-23. The operator legal entity is the contracting party on the terms of use and the controller of personal data under the privacy policy. The "Satsignal LLC" name and Iowa jurisdiction appear only in legal surfaces (terms section 8, privacy jurisdiction) and operator disclosure blocks. **Pricing.** Currently opening with design partners; see `https://satsignal.cloud/pricing.html` for the current plan structure. This LLM-readable explainer does not restate pricing terms to avoid drift; consult the pricing page. **Trust posture.** `https://satsignal.cloud/trust.html` documents the operational guarantees (broadcast tiering, retention, what the operator can and cannot do unilaterally). Satsignal is a notary service that produces cryptographically and chain-verifiable proofs. **Security.** `https://satsignal.cloud/security.html` covers the operator security model — key custody, what a key compromise can and cannot affect, and single-operator anchor authority. **Privacy.** `https://satsignal.cloud/privacy.html` covers data handling, retention, and the sealed-blind opacity guarantee. **Terms of use.** `https://satsignal.cloud/terms.html` is the binding agreement. ## Further reading - The curated link map: `https://satsignal.cloud/llms.txt` (or `https://proof.satsignal.cloud/llms.txt`). - The OpenAPI 3.1 spec: `https://proof.satsignal.cloud/openapi.json`. - The Postman collection: `https://proof.satsignal.cloud/postman.json`. - The vendored API reference (ReDoc): `https://proof.satsignal.cloud/api-reference`. - The sitemap: `https://satsignal.cloud/sitemap.xml`. - The integration guides index (chooser + path guides + production references): `https://satsignal.cloud/docs.html`.