Audit receipts
Every chain that runs through ProofRail produces a signed receipt when it completes. The receipt is your audit trail: it records what happened, who decided what, and when. It’s cryptographically signed so tampering is detectable, and hash-chained across your organization so deletion of any receipt is detectable too.Why receipts matter
Compliance, debugging, and trust all eventually need the same thing: a record of what your AI agents did that you can present to a third party and have them believe it. ProofRail receipts give you that record in a form you can verify yourself, without trusting our backend to be honest about it.What a receipt contains
When a chain completes, the backend assembles a receipt that captures the chain in full:signature field is an HMAC-SHA256 over the entire structured data using a key held by the backend. The previous_receipt_hash links this receipt to the previous one for the same organization.
How signing works
When a receipt is generated, the backend:- Serializes the structured data to a canonical JSON form
- Computes
HMAC-SHA256(structured_data, server_secret)to produce the signature - Stores the receipt with both the structured data and the signature
How hash chaining works
Each receipt embeds the hash of the previous receipt for the same organization. This forms a chain: receipt N+1 references receipt N, which references receipt N-1, all the way back to the first receipt (the “genesis” receipt whereprevious_receipt_hash is null).
- Tampering with any single receipt breaks its signature
- Deleting a receipt entirely breaks the chain at that point (the next receipt’s
previous_receipt_hashno longer matches anything) - Reordering receipts is detectable because the hash sequence is checkable
Verification — public endpoint
The most important property of ProofRail receipts is that you can verify them without authentication. The verification endpoint is public:valid is true, the receipt’s signature checks out. If valid is false, the receipt has been tampered with or modified after signing.
This means an auditor, regulator, or counterparty can verify a receipt’s authenticity without needing access to your ProofRail account. If you give them the receipt ID, they can check it themselves — including which chain it belongs to.
Verification — from the SDK
The SDK exposes a thin wrapper around the same endpoint:ReceiptVerifyResponse (a Pydantic model with valid, receipt_number, chain_id, and generated_at fields).
Receipt numbering
Receipts get human-readable numbers in the formatPR-YYYY-NNNNN:
PR-is the ProofRail prefixYYYYis the year the receipt was createdNNNNNis a zero-padded sequence number within your organization
PR-2026-00001, PR-2026-00042, PR-2026-15847.
These numbers are useful for reference in your internal systems, support tickets, and compliance documentation. The underlying receipt is identified by its UUID; the number is the human-friendly label.
What this gives you
The combination of HMAC signing, hash chaining, and a public verification endpoint produces a property that’s unusual for SaaS audit logs: you don’t have to trust ProofRail’s backend to be honest about your own data. If you ever need to prove what your agents did — to a regulator, to a customer, to your security team, to opposing counsel — the receipt is the proof. The math works the same regardless of whether ProofRail is still in business, whether your account is still active, or whether anyone else trusts us. That’s the design goal of the receipt system. It’s not “we’ll keep good records,” it’s “you don’t need to take our word for it.”Where to go next
Chain-level governance
Why we track the whole workflow, not just individual calls.
Policies
How decisions get made before receipts get generated.
Human approval
How approvals get recorded in receipts.
SDK reference
The full API surface, including verification.