How to verify an AER-1 receipt.

Someone hands you a receipt for AI agent work and says: check it yourself. Here is exactly how. An AER-1 verifiable receipt is verified with three recomputations: the canonical bytes hash, the evidence hash, and the workflow root. No account, no permission, and no trust in whoever issued the receipt. Below is each check in plain language, then a real receipt and workflow checked end to end with the actual numbers.

Run the checks in your browser: the free AER-1 receipt verifier, no signup.

Published October 12, 2026. Updated October 15, 2026. Written against draft-zambo-aer1-23.

The three checks

Check 1

The canonical bytes hash

Every receipt commits to the exact bytes of the recorded call: the tool, the inputs, and the observed output, encoded one canonical way so the bytes are deterministic. In the API form those bytes travel base64-encoded in the canonical_bytes field. Decode them, compute SHA-256, and compare to the receipt's output_hash. A match means the recorded call is exactly what was committed at execution. A mismatch means the record changed after the fact.

Check 2

The evidence hash

When a receipt captures external evidence (a fetched page, a file, an API response), the evidence body is stored and the receipt commits to its SHA-256 in evidence_sha256. Fetch the evidence from the receipt's evidence URL, hash the body, and compare. A match means the evidence you are reading is the evidence the receipt committed to, byte for byte.

Check 3

The workflow root

Receipts from one run are grouped into a workflow with a single Merkle root. Section 8.1 of the draft fixes the construction: each step's leaf is the SHA-256 of the UTF-8 bytes of its receipt ID, leaves are paired left to right over the raw digests, an odd level duplicates its last digest, and a single-step workflow's root is that step's leaf. Recompute the root from the step receipt IDs and compare it to the workflow's published merkle_root. A match means the workflow contains exactly those steps, in that order.

All three checks are recomputations over published bytes. That is what makes the receipt verifiable by a stranger: there is nothing to take on faith, and nothing that requires the issuer's cooperation.

Worked example: a real receipt, checked end to end

This example uses live public records, so you can reproduce every number yourself. The receipt is 4028dabb-3d12-4960-855c-639ce37f14cc, a live_price call recorded on October 12, 2026. It is the single step of workflow 6b6952a5-ab1f-4596-a0b3-a352c137cb41.

Check 1: canonical bytes

Decode the receipt's canonical_bytes (575 bytes once decoded) and hash them:

SHA-256(decoded canonical bytes)
  = 62780c8f89d25c2c4b336b3590fee9d6cec98e4e19eb3c15252c428845c0a0dc
receipt output_hash
  = 62780c8f89d25c2c4b336b3590fee9d6cec98e4e19eb3c15252c428845c0a0dc
MATCH

Check 2: evidence

Fetch the evidence body from the receipt's evidence URL (97 bytes) and hash it:

SHA-256(evidence body)
  = 12898298eb1412331dd1bda16d4d700c2094ad440eef0a237bd1cc656125adcd
receipt evidence_sha256
  = 12898298eb1412331dd1bda16d4d700c2094ad440eef0a237bd1cc656125adcd
MATCH

Check 3: workflow root

The workflow has one step, so under Section 8.1 its root is the leaf: SHA-256 over the UTF-8 bytes of the step's receipt ID, hyphens included:

SHA-256("4028dabb-3d12-4960-855c-639ce37f14cc" as UTF-8)
  = 7c90f65aeccd214f8bb583bec76878d5f463d65b9b26c11e07c51dd59be814d5
workflow merkle_root
  = 7c90f65aeccd214f8bb583bec76878d5f463d65b9b26c11e07c51dd59be814d5
MATCH

Three checks, three matches. The recorded call, the evidence, and the workflow membership are all exactly what was committed. Note what the third check also gives you: this workflow's root is now a public test vector in the conformance corpus, so any independent implementation can check its own Merkle code against the same numbers.

Prefer to run it as code? The same three recomputations in a few lines:

import hashlib, base64, json, urllib.request

receipt = json.load(urllib.request.urlopen(
    "https://zambo.dev/api/receipt/4028dabb-3d12-4960-855c-639ce37f14cc"))

raw = base64.b64decode(receipt["canonical_bytes"])
assert hashlib.sha256(raw).hexdigest() == receipt["output_hash"].removeprefix("sha256:")

body = urllib.request.urlopen("https://zambo.dev" + receipt["evidence_url"]).read()
assert hashlib.sha256(body).hexdigest() == receipt["evidence_sha256"].removeprefix("sha256:")

leaf = hashlib.sha256(b"4028dabb-3d12-4960-855c-639ce37f14cc").hexdigest()
assert leaf == "7c90f65aeccd214f8bb583bec76878d5f463d65b9b26c11e07c51dd59be814d5"
print("receipt verified")

What a pass proves, and what it does not

A passing check proves a narrow, valuable thing: the saved record was not changed since it was saved. The inputs, the output, and the evidence you are reading are the ones committed when the work ran. It does not prove the agent's answer was right, the tool told the truth, or the work was worth paying for. Anyone selling verification as proof of correctness is overselling it. What verification removes is the argument about what the record says, so the argument about whether the work was good can happen on solid ground.

If a check fails, that is also information: the bytes and the commitment disagree, so the record cannot be trusted as presented. A failed check is the system working, not an edge case to explain away.

Verify your own, and get receipts of your own

  • Check a receipt now: paste any receipt into the live verifier and get the verdict in seconds.
  • Run the checks offline: the open conformance kit, with the full test corpus including the workflow vector above, is at gitlab.com/rambozambodotdev/zambo.
  • See a receipt minted live: the one-click demo runs a real call and hands you the receipt, no signup.
  • Read the format: AER-1 is an IETF Internet-Draft, draft-zambo-aer1-23. It is a draft, not a finished standard, and the verification rules above are exactly what it specifies.
  • Keep your runs permanently: a Day Pass seals a workflow so its page, badge, and PDF pack stay put after the free viewing window.

Tool call transcript verification

People ask how to verify an AI agent's tool call transcript. The honest starting point: a transcript is the agent's own narration. It is written by the same process whose work you are checking, so reading it carefully, or having another model grade it, verifies nothing by itself. It produces a second opinion about a story.

Verification means checking things the narrator does not control. For each tool call that matters: pull the receipt captured at execution, recompute the canonical bytes hash against the output hash, and check the evidence hash. For a multi-step run, recompute the workflow root from the step receipt IDs. Then do the one check no record can fake: read the system of record back and confirm the claimed effect is actually there. That combination, a committed record plus a fresh readback, is what verified means for a transcript.

The worked example above is exactly this procedure run against a real receipt. The pattern is written up with a live case in Your AI Agent Said Done. The Database Disagrees, and the open conformance kit at gitlab.com/rambozambodotdev/zambo runs the same checks offline. Or start with the live demo: one click mints a real receipt you can check yourself.

How do I audit my AI agent's tool calls?

Auditing is not reading the agent's story more carefully. The summary, the transcript, and the exported log were all produced by the system you are auditing, so none of them can testify against it. A real audit works from a record the narrator never controlled: one receipt per tool call, captured at execution, each bound to that call's exact inputs and its observed output.

Per call, the check is mechanical. Pull the receipt, recompute the SHA-256 over its canonical bytes, and compare it to the receipt's output hash. Confirm the recorded inputs are the inputs that call should have received, and the tool named in the receipt is the tool that ran. For a multi-step run, recompute the workflow root from the step receipt IDs and confirm every step is accounted for, including the ones the summary skipped. The complete procedure is written up in How to Verify Your AI Agent Actually Completed the Task.

Then compare the record to the world. Take the effects the run claims (a written file, an updated row, a sent request) and read them back from the live system. That readback step catches what hashes cannot, and it is the whole subject of Your AI Agent Said Done. The Database Disagrees. Keep the conclusion narrow: a receipt that verifies proves the saved result was not changed since it was saved, nothing more. Run the checks offline with the open conformance kit, mint a receipt to audit with the live demo, or seal the full trail with a Day Pass. The method is written up as a standalone guide: How to Audit AI Agent Tool Calls: A Practical Method.

Verifying an AER-1 receipt: FAQ

How do I verify an AER-1 receipt?

Run three checks. Decode the canonical bytes, compute SHA-256, and compare to the output hash. Fetch the evidence body and compare its SHA-256 to the evidence hash. If the receipt is part of a workflow, recompute the workflow root from the step receipt IDs the way Section 8.1 specifies and compare it to the published root. All three matching means the record was not changed after it was saved.

What do I need to verify an AER-1 receipt?

Only the receipt itself and any SHA-256 tool. No account and no permission, because every value is recomputed from bytes the receipt publishes. The free verifier at zambo.dev/verify runs the receipt checks for you, and the open kit on GitLab runs them offline.

What does a passing check prove?

It proves the saved record was not changed since it was saved: the committed inputs, outputs, and evidence are intact. It does not prove the agent's answer was correct. Verification settles the integrity of the record; judging the work is separate.

How is the AER-1 workflow root computed?

Per Section 8.1 of draft-zambo-aer1-23, each step's leaf is the SHA-256 of the UTF-8 bytes of its receipt ID. Pairs are hashed over the concatenated raw digests, an odd level duplicates its last digest, and a single-step workflow's root is that step's leaf digest.

Can I verify an AER-1 receipt without trusting Zambo?

Yes. The receipt publishes its canonical bytes and evidence, the draft publishes the construction, and the kit is open source. Anyone can recompute every commitment and get the same result, which is how independent implementers check each other.

How do I know if my AI agent finished the task?

Pull the receipt for the run and recompute its checks, then read back one claim in the real system (the database row, the file, the API state) and confirm the change is actually there. A finished task has a receipt that verifies and state that matches. The full procedure is in How to Verify Your AI Agent Actually Completed the Task, and the live verifier runs the receipt checks in seconds.

What does AI agent tool call transcript verification actually check?

A transcript is the agent's own narration, so reading it verifies nothing by itself. Real verification checks the committed record: recompute the canonical bytes hash, the evidence hash, and the workflow root, then read back the claimed effect in the system of record. If the commitments recompute and the state matches, the story is backed by evidence. Try it on a real receipt with the free verifier.

How do I audit my AI agent's tool calls?

Work from receipts, not narration. For each call, pull the receipt captured at execution, recompute the SHA-256 over its canonical bytes against the output hash, and confirm the recorded inputs are the inputs that call should have received. For a multi-step run, recompute the workflow root from the step receipt IDs. Then read the claimed effects back from the live system. A verified receipt proves the saved result was not changed since it was saved. The full procedure is in How to Verify Your AI Agent Actually Completed the Task.

AI agent receipt checker

The checker is the free half of the system. An AI agent receipt checker takes a receipt link or id and runs the verification checks in the open: recompute the digest over the saved result, confirm it matches the commitment recorded at execution time, and surface the saved result for reading. The public checker is at zambo.dev/verify, free, no account, and it is deliberately the same check anyone could run by hand from the receipt's published fields, so using it requires no trust in the checker itself.

Zambo is the verifiable work layer for AI. Use the checker on receipts you receive from anyone: a receipt that passes was not changed since it was saved, and a receipt that cannot be produced or does not pass tells you exactly where the work stands.