Agent run receipts

Prove what your agent did. Without storing what it saw.

A receipt is a chained list of the steps in one agent run: the prompt, each tool call and result, the output. Every step is kept only as a fingerprint. The chain's last link is anchored on Polygon as one ordinary proof, and anyone holding the receipt can check the whole sequence later, offline, without reading a word of it.

Prompts, tool calls and outputs never leave your machine
One API proof per run, on every plan
Checked offline with the open-source verify-proof package
Python, Node, command line, MCP tools
Who this is for

Agents that act for someone else

When software decides and acts on a person's behalf, somebody will one day ask what it did and when. A receipt answers with a record that cannot be edited afterwards, and that shows nobody the conversation.

Support and service agents

A customer says the bot promised a refund. The receipt shows the exact sequence: their message, the order lookup, the reply, each one fingerprinted and dated, with the reply's text checkable against the record you kept.

Coding agents

An agent in Claude Code, Claude Desktop or Cursor can receipt its own session through the MCP tools: what it was asked, what it ran, what it changed. The receipt goes in the repo next to the release it produced.

Agent workflows and automations

LangChain runs, n8n and Make scenarios, scheduled jobs that call a model. One receipt per run, anchored at the end, kept with the run's log. The callback handler for LangChain is in the package's examples.

Anything that has to be audited later

Regulated workflows, agents that move money or file documents, research pipelines. The receipt is a small JSON file; the record is a public transaction. Neither depends on ProofLedger staying in business.

How it works

Fingerprints in, one hash out

The receipt format is open and documented; the chain can be recomputed in any language.

1

Record each step as a fingerprint

For every prompt, tool call, tool result and output, the receipt stores a SHA-256 of the content mixed with a random per-run secret, plus the step type, the time and an optional short label. The content itself is never written down.

2

Chain the steps and anchor the head

Each step's link is a hash of the previous link and the step. Change, drop or reorder a step and the chain breaks. The last link goes to POST /api/v1/proof like any hash: one proof per run, the proof bundle saved back into the receipt.

3

Anyone checks it, offline

verify-proof receipt verify run.receipt.json recomputes the chain, matches the head to the bundle and names the Polygon transaction to look up on a block explorer. Given a step's content and the secret, it can also confirm that one step.

Quickstart

A receipt for one run, in Python

Needs pip install verify-proof and a key from your account page in PROOFLEDGER_API_KEY. The free plan includes 100 API proofs a month; one run is one proof.

1 Record the run
from agent_receipt import RunReceipt

r = RunReceipt("support-ticket-48213", agent={"name": "support-bot"})
r.prompt(customer_message, label="customer message")
r.tool_call(json.dumps(call), label="lookup_order")
r.tool_result(result_text)
r.output(reply, label="reply sent")

Pass the exact text of each step. Labels are optional, up to 120 characters, and stay in the receipt in clear, so keep them to things like the tool name. The Node package has the same class; the MCP tools start_run_receipt and add_receipt_step do the same from inside an assistant.

2 Anchor and save
r.anchor()                            # one API proof; waits for the Polygon anchor
r.save("ticket-48213.receipt.json")

Only the chain head leaves your machine, with the label "agent run support-ticket-48213" and the run id as external_id, so anchoring the same run twice returns the same proof. The anchor usually lands within a minute; the bundle is written into the receipt.

3 Check it, anywhere
verify-proof receipt verify ticket-48213.receipt.json
verify-proof receipt verify ticket-48213.receipt.json --step 0 --content customer-message.txt
verify-proof receipt show ticket-48213.receipt.json

No account, no network call. The first line checks the chain and the bundle; the second confirms step 0 was made from that file; the third lists the steps' types, times and labels, never their content.

4 Hand it over without the secret
r.save("ticket-48213.shared.json", include_secret=False)

Without the secret the chain still verifies, and nothing in the file can be guessed, not even a one-word step. To let a third party confirm one step's content, give them that step's content and the secret.

Straight answers

What a receipt shows, and what it does not

Read this before you promise anything to your own users.

What it shows
  • This exact sequence of steps, in this order, with these fingerprints and times, existed by the anchor time
  • Nothing in it has been changed, dropped or reordered since
  • Given a step's content and the secret, that the step was made from that exact content
  • All of it checkable by anyone with the file, with no help from us
What it does not show
  • That the agent was right, safe or allowed to do what it did. A receipt records; it does not judge.
  • Who ran the agent, or that the steps recorded were all the steps taken. The receipt is as complete as the code that wrote it.
  • The content of any step the owner does not disclose. That is the point.
  • Price: one API proof per run on your plan (100 a month free; Developer 1,000 for $19; Platform 10,000 for $79; then $0.01 a proof). No new endpoint, nothing extra to buy.
Data

We see one hash per run

The receipt is built on your machine. What reaches ProofLedger is the chain head, the label "agent run <your run id>" and the run id. We keep which account made the proof, when, and its anchoring details. The prompts, the tool calls, the results and the output are never sent, and the receipt file holds only their fingerprints.

stays with you  → the customer's message, the order lookup, the reply, the receipt file and its secret
sent to ProofLedger → d9f0a37c21e8b56f4c90de2a7b18f3e5c6a4d2b1e0f9c8a7b6d5e4f3a2b1c0d9

Start with a free key

Receipt a run on the free plan today. The package, the format and the examples are open source; the reference is in the API docs. Using the API accepts the API Terms.

Create a free account Package and examples See plans