Quickstart
Synpareia is for the moments when something is at stake between two agents. So this quickstart has two agents in it. A walkthrough where you sign your own blocks and verify your own chain proves nothing you couldn’t prove with a text file — the value only shows up when there is a counterparty who might remember things differently.
The fastest route: don’t write any code
Section titled “The fastest route: don’t write any code”If you have an MCP-capable agent (Claude Code, Claude Desktop, Cursor, or anything else that speaks MCP), the Trust Toolkit gives it an identity and the trust tools with no configuration:
{ "mcpServers": { "synpareia": { "command": "uvx", "args": ["synpareia-trust-mcp"] } }}Then tell your agent: “call orient”. It will work out what applies to its situation. Most
people should stop here — see the Trust Toolkit page.
The rest of this page is the SDK, which is what you want if you are building something on synpareia rather than using it.
Install the SDK
Section titled “Install the SDK”pip install synpareiauv add synpareiapoetry add synpareiaRequires Python 3.11+. Dependencies are few and boring — cryptography for signing, plus
small libraries for canonicalisation and signed HTTP requests.
A commitment two agents can both point at
Section titled “A commitment two agents can both point at”Alice promises Bob a dataset by a date. Later, one of them will want to establish what was actually agreed. Here is the whole shape.
-
Two identities
A profile is an Ed25519 keypair. No server, no registration, no account.
import synpareiafrom synpareia import templatesalice = synpareia.generate()bob = synpareia.generate()print(alice.id) # did:synpareia:32816841bb5f7ff9...The DID is derived from the public key:
did:synpareia:<SHA-256(public_key)>. Anyone can mint one locally, which is the point — there is no gatekeeper to ask. -
Open a chain both of them can write to
A chain carries a policy as its genesis block: who may append, what block types are allowed, who must sign what.
templates.sphereis the two-party template — a shared space where both signatories can contribute.policy = templates.sphere(alice, bob)chain = synpareia.create_chain(alice, policy=policy)The policy is not decoration. Because it sits at position 1 and every later block hashes back to it, the rules of the space are fixed at the moment the space is created — neither party can quietly widen them later.
-
Alice states the commitment
promise = synpareia.create_block(alice,"message","I will deliver the dataset by 2026-08-06, in JSONL, or refund the fee.",)pos = chain.append(promise)print(pos.sequence) # 2 — position 1 is the policyNote what makes this different from saying it in a chat window: it is signed by Alice’s key, it is hash-linked to a policy that predates it, and it says what “kept” would look like.
-
Bob acknowledges
ack = synpareia.create_block(bob, "message", "Acknowledged. Holding you to that.")chain.append(ack)Now it is a two-sided record. Bob cannot later claim he never saw the terms, and Alice cannot claim she promised something narrower.
-
Export a proof a stranger can check
export = synpareia.export_chain(chain)public_keys = {alice.id: alice.public_key, bob.id: bob.public_key}valid, errors = synpareia.verify_export(export, public_keys=public_keys)print(valid, errors) # True []Hand
exportto anyone — an arbiter, an auditor, the other party’s operator. Verification is pure cryptography: it does not call synpareia, does not need an account, and keeps working if we disappear. -
Confirm it actually catches a lie
Worth doing once yourself rather than taking our word for it. Change the date in the exported record and re-verify:
import copytampered = copy.deepcopy(export)for position in tampered["positions"]:block = position["block"]if "content" not in block:continuetext = bytes.fromhex(block["content"]).decode()if "2026-08-06" in text:block["content"] = text.replace("2026-08-06", "2026-09-30").encode().hex()breakvalid, errors = synpareia.verify_export(tampered, public_keys=public_keys)print(valid) # Falseprint(errors) # ['Position 2: content_hash mismatch',# 'position 2: block signature verification failed']Two independent checks fail, not one: the content no longer matches its hash, and the signature no longer matches the block. Note that
contentis hex-encoded in the export — editing the visible string without re-encoding changes nothing, which is a mistake worth making once in a test rather than in an argument.
What you just built
Section titled “What you just built”A sphere — a shared, tamper-evident space between two parties, with its rules fixed at creation and every entry signed by whoever wrote it. The commitment inside it is not stronger because we vouch for it. It is stronger because any third party can check it, and because neither Alice nor Bob can alter it without the alteration being obvious.
That is the whole idea. Everything else — witness seals for independent timestamps, anchors for cross-chain attestation, commit-reveal for provably independent judgement — is more of the same move applied to different situations.
Next steps
Section titled “Next steps”- Concepts overview — commit, record, check, and Forms; what the product is for
- Two operators, end to end — the same story at full length, across two machines
- Commit-reveal — proving two assessments were made independently
- API reference — the full SDK surface
Built by Sam Hyland · Canberra, Australia