Docs — Inverba
JavaScript is off, so the interactive parts of this page (the in-browser verify demo, copy buttons) won't run. Everything that matters is still readable below — and the same applies to Inverba itself: verification is plain SHA-256 and Ed25519, checkable with about thirty lines in any language.
Documentation · v0.1.0

Five minutes to your first signed record.

Everything below runs locally. No account, no API key, no network dependency beyond the pages you fetch.

Quickstart

1 — install (generates your Ed25519 keypair on first run)
$ pip install inverba
$ inverba keys init
key inv_k1_7f3a generated · ~/.inverba/keys (never leaves this machine)
2 — scrape: content plus a signed record
$ inverba scrape https://example.com/pricing
pricing.html + record.json
3 — or from Python
from inverba import scrape

page = scrape("https://example.com/pricing")
page.record.save("record.json")
print(page.record.content_sha256)
4 — verify (yours, or anyone's)
$ inverba verify record.json --content pricing.html
✓ signature valid ✓ hash matches — verified offline

Verify without Inverba

This is the point of the whole system: a record is a standard Ed25519 signature over an RFC 8785 canonical JSON body. Any language, no Inverba dependency. Complete Python example:

import json, hashlib, base64
from jcs import canonicalize # RFC 8785
from nacl.signing import VerifyKey

rec = json.load(open("record.json"))
content = open("pricing.html", "rb").read()

# 1. content hash
assert hashlib.sha256(content).hexdigest() == rec["content_sha256"]

# 2. signature over the canonical body
body = {k: v for k, v in rec.items() if k != "signature"}
VerifyKey(bytes.fromhex(SIGNER_PUBKEY)).verify(
    canonicalize(body), base64.b64decode(rec["signature"]["sig"]))

print("valid ✓")

that's the whole check — two asserts. Registry inclusion (a standard Merkle audit path) is a planned optional third step, once the transparency log ships.

Record spec — inverba-record/1

An open specification, documented in full below — enough to write an independent implementation today, and test vectors in the repo to validate it against. A format only we can produce would defeat the point.

field
type
req
meaning
inverba_record
string
Spec version, e.g. "1"
url
string
Requested URL (redirects land in final_url)
fetched_at
string
RFC 3339 UTC timestamp of the fetch, per the fetcher's clock
content_sha256
string
Hex SHA-256 of the exact response body bytes
status_code · final_url · content_type
int/str
The fetch facts: HTTP status, URL after redirects, response content type
fetched_by
string
Public key of the worker that performed the fetch
signature
object
alg (ed25519), key_id, base64 sig over the RFC 8785 canonical body
corroborations
array
opt
Counter-signatures from other fetchers that saw the same content (empty at N=1)

Registry & watchtowers planned

A Merkle transparency log for anchoring records, plus watchtowers so anyone can independently monitor it for consistency — the same accountability construction as Certificate Transparency. The design is published; neither the hosted log nor the watchtower tooling is live yet. Records don't depend on it: everything above verifies fully offline today.