Proofs for Agents
How an agent consumes, stores, and verifies proofs — and what makes them safe to share with counterparties.
Proofs are what an agent hands to the outside world. Everything inside a delta stays private; the proof is the part that is safe to cite, publish, and forward. This page covers how an agent stores proof artifacts, how it verifies them, and what it can reliably claim on top of them.
Use When
Use this page when an agent is designing its proof-persistence schema, building a receipt workflow, or wiring up independent verification for a counterparty.
Inputs
- A storage layer the agent controls for its own audit trail.
- Access to the Balance API with a valid key (for receipts and comparisons).
- A counterparty or auditor who needs to verify activity without PacSpace credentials.
The Public Contract
Every verified delta produces a small set of proof fields. These are the fields an agent should persist verbatim:
| Field | Where it comes from | What it is |
|---|---|---|
receiptId | Emit response | The proof root for a submission. Safe to share. |
recordId | Emit response | The internal identifier for that submission. |
proofRoot | Checkpoint, receipt, verify responses | A single fingerprint covering a group of deltas. Safe to share. |
proofHash | Webhook payloads | The per-record proof fingerprint. Safe to share. |
contentHash | Webhook payloads | Fingerprint of the delta content itself. Safe to share. |
itemHash / itemHashes | Grouped emit and query responses | Per-item content fingerprints inside a group. Safe to share. |
previousProofHash | Webhook payloads | Links to the prior record in the verification chain. |
verificationReference | Delta status, verify responses | Reference on the verification layer, for independent verification. |
verificationExplorerUrl | Verify responses | Public URL anyone can open to confirm the proof. |
verifiedAt / blockTimestamp | Delta status, webhook payloads | When verification completed. |
None of these fields contain business data. They can safely be logged, stored, forwarded to a counterparty, or embedded in an invoice.
What an Agent Should Persist
For every verified delta, persist at minimum:
recordId— so the agent can look the submission up later.receiptIdandproofRoot— so the agent can hand a counterparty a single value to verify.proofHashandcontentHash— so the agent can confirm chain integrity on future deliveries.previousProofHash— so chain-continuity checks are possible.verificationReference— so the agent can point a counterparty or auditor straight at the verification layer.verifiedAt— so the agent has an authoritative timestamp, not its own wall clock.
All of the above are safe to write to logs, telemetry, and audit stores the agent shares with the operator.
The Four Proof Operations
Verify a Single Proof Root (Public)
GET /api/v1/verify/:proofRoot is unauthenticated. Any counterparty, auditor, or downstream agent can call it to confirm a proof without needing PacSpace credentials.
curl https://balance-api.pacspace.io/api/v1/verify/0x7f3a9b2c...
The response includes:
verified— boolean outcome.proofRoot— echoed back.recordedAt— when the proof was permanently recorded.summary— aggregate counts and net change.records— per-item amounts, reasons, and timestamps (no business identifiers).verification.verificationExplorerUrl— the public link anyone can open.
Generate a Receipt
GET /api/v1/balance/receipt/:customerId produces a receipt — a proof document covering verified deltas for a customer in a scoped window. Receipts are the format an agent hands to a counterparty. Full schema on Receipt.
Verify a Spot-Check Package
POST /api/v1/verify/package accepts an expectedProofRoot plus a list of item fingerprints and returns a binary verification outcome. Use this when an auditor wants to confirm a specific subset of items without the full receipt. Full schema on Verifying Proofs.
Compare Two Balance Views
POST /api/v1/balance/compare is not itself a proof operation, but its response includes a proof.proofRoot the agent can persist alongside the comparison verdict. See Verify.
Chain-Continuity Check
An agent that consumes delta.verified webhooks can detect inserted, dropped, or reordered deltas by tracking the chain:
- On every verified delta, look up the last stored
proofHashfor that customer. - Confirm the delivered
previousProofHashmatches. - Persist the delivered
proofHashas the new last-stored value.
const stored = await getLastProofHash(data.delta.customerId);
if (stored && data.proof.previousProofHash !== stored) {
await alert('proof chain discontinuity detected', {
expected: stored,
received: data.proof.previousProofHash,
});
}
await storeProofHash(data.delta.customerId, data.proof.proofHash);
If the chain breaks, an agent should alert — not silently mutate state. Most breaks have benign explanations, but they all deserve a human look.
Content-Fingerprint Check
Every emit response and every webhook payload exposes a content fingerprint for each item. An agent that stored its own fingerprint at emit time can confirm the returned value matches:
assert(
data.proof.contentHash === storedContentHash,
'content fingerprint mismatch — data may have been altered',
);
This is the cleanest proof that the data the agent submitted is the data PacSpace verified.
Sharing Proofs
Three shapes of proof artifact are safe to share with counterparties:
- A
proofRootorreceiptId. Anyone can open/api/v1/verify/:proofRootand confirm it exists, read the summary, and follow theverificationExplorerUrlto the verification layer. - A receipt document from
GET /api/v1/balance/receipt/:customerId. This contains the proof root, the list of items, and links to public verification. - A spot-check package generated from the receipt, for auditors who want to confirm a subset of items with binary output.
Never share the original delta payload, the customerId mapping, or any business reference the agent did not intend to expose.
Receipts for Invoicing
The canonical end-of-period workflow:
POST /api/v1/balance/checkpoint— lock the period.GET /api/v1/balance/receipt/:customerId?period=YYYY-MM— generate the receipt.- Attach the
proofRoot(and optionally theverifyUrl) to the invoice. - The counterparty verifies the
proofRootindependently atGET /api/v1/verify/:proofRoot.
This removes the agent from the position of "source of truth" for the invoice. The counterparty can confirm the proof without trusting the agent — and without needing PacSpace credentials.
Idempotency
Receipt generation and public verification are read operations; idempotency does not apply. Checkpoint creation is idempotent: the same request for the same scope returns the same checkpoint.
Retry
Retry transient failures on proof endpoints the same way the agent retries any read: bounded exponential backoff on 408, 429, 5xx. Never retry 4xx validation errors.
Failure Modes
- Persisting only
recordIdand losing theproofRoot, forcing the agent to regenerate receipts just to answer a counterparty question. - Sharing the original delta payload instead of the receipt, exposing business data.
- Skipping chain-continuity checks and missing dropped or reordered deltas.
- Treating a failed
/api/v1/verify/:proofRootresponse as a transient error instead of surfacing it to the operator. - Attaching an internal identifier to an invoice instead of the
proofRoot, making the invoice un-verifiable by the counterparty.
Related Pages
- How Verification Works — the verification lifecycle end to end.
- Proof Fingerprints — the properties every proof has.
- Verifying Proofs — step-by-step verification procedure.
- Receipt — receipt endpoint reference.
- Autonomous Agent Pattern — applying these checks in a webhook handler.