What Is an AI Output Receipt?
An AI output receipt is a cryptographic proof that a specific inference — prompt, response, model — existed at a moment and was not altered. EVIDIQ Notary is the open MCP server that issues them: hashing the canonical payload, signing with EIP-191, anchoring on 0G Storage, and returning a verifiable proof anyone can check offline.
Think about what happens every time an agent calls a model today. A prompt goes in, tokens come out, the response gets handed back to whatever called it. After that? Nothing. The output vanishes into logs that may or may not exist, may or may not be tampered with, and may or may not belong to the model that actually produced it. That's a problem when the output is being used as evidence — to settle a trade, to justify a payment, to defend a decision in front of a human auditor.
A receipt fixes this. It binds three things together:
- A canonical payload (prompt + response + model id + timestamp)
- A cryptographic signature from a known signer
- A publicly anchored pointer to where the evidence lives
This is what EVIDIQ Notary produces. And the receipts are designed to be checked by anyone, anywhere, without phoning home.
Why AI Outputs Need Notarization
The honest answer is that we got here by accident. Inference used to be a thing humans ran occasionally — search a thing, summarize a PDF, generate an image for a slide. Now? In 2026, agents generate millions of inferences per day. Each one is a tiny act of authorship that nobody can prove. That's terrifying if you're settling money on top of those outputs.
Here's the concrete failure mode. Agent A calls a model through an OpenAI-compatible endpoint, gets back a JSON blob saying "yes, the price of X is 412 USD." Agent A passes that to Agent B, which uses it to authorize a trade. Three days later, someone asks: did the model actually say that? When? Was the response altered in transit? Nobody knows. The endpoint has no logs, or the logs are mutable, or the logs are owned by a party with an incentive to lie.

Three questions every inference deserves a real answer to:
- Did this model say this?
- When did it say it?
- Was it altered afterward?
Notarization answers all three at once. The signature binds the model identity and the response body to a timestamp; the anchor makes it publicly retrievable; the hash makes any mutation detectable. We've talked to teams building x402-paid agent flows, and the very first thing they ask is "how do we prove the inference actually happened before we settle?" That's the exact gap EVIDIQ Notary closes.
Worth noting: a wallet balance alone tells you nothing about whether an agent's reasoning was real. A receipt tells you the reasoning existed, who signed it, and that it wasn't rewritten. That's the difference between plausible and provable.
How EVIDIQ Notary Works End to End
Let's walk a single notarize_inference call from start to finish. No hand-waving — here's the actual flow.
The caller (an agent, a script, another MCP client) prepares a canonical payload. Not just prompt and response — the full envelope:
model_id— e.g.gpt-4o-2026-08, or a local model URIprompt_hash— keccak256 of the canonicalized prompt bytesresponse_hash— keccak256 of the canonicalized response bytestimestamp— ISO-8601 UTC, rounded to the secondcaller_address— the EVM address paying for the notarization
That JSON is hashed with keccak256, exactly the way Solidity would hash it (sorted keys, no whitespace). The hash is what gets signed.
Step by step, the flow looks like this:
- Client calls
notarize_inferenceon the MCP server at evidiq.dev/mcp. - Server responds
HTTP 402 Payment Requiredwith an x402 v2 challenge —accepts[].amountdenominated in USDT0, scheme"exact", EIP-3009transferWithAuthorization, settled on X Layer. - Client signs an EIP-3009 authorization and resubmits with the
X-PAYMENTheader. - Server validates payment, canonicalizes the payload, computes the keccak256 digest.
- Server signs the digest with EIP-191 using the EVIDIQ notary key.
- Server uploads the canonical payload + signature to 0G Storage (mainnet) and gets back a
storageRootandstorageTx. - Server returns the receipt to the caller.
The receipt that comes back looks something like this — simplified for clarity:
{
"payload_hash": "0x9a3f…b21c",
"signed_digest": "0x7c4e…a08f",
"signer": "0xEv1d1Q…Notary",
"signed_at": "2026-04-14T11:22:33Z",
"storage_root": "0x4d8a…ee10",
"storage_tx": "0xabc123…",
"merkle_proof": ["0x1f…", "0x9d…"],
"model_id": "gpt-4o-2026-08",
"caller": "0xAgent…A7"
}
That storage_tx is the receipt's anchor. Anyone can pull the canonical payload back from 0G Storage by that tx hash, re-hash it, and confirm it matches payload_hash. The signature on signed_digest proves EVIDIQ Notary itself vouched for it at signed_at. The merkle_proof lets a third party prove the payload is in the storage_root tree without downloading the whole thing.
We chose EIP-191 over raw eth_sign for a reason — it's the standard personal_sign format every wallet understands, and it prepends \x19Ethereum Signed Message:\n so signatures can't be replayed as transactions. The digest the verifier recomputes is deterministic across languages and implementations, which matters more than people think.
Verifying a Receipt Offline
This is the part we care about most. A receipt you can't verify without calling the issuer is just a certificate of authority — and we don't want to be that. EVIDIQ Notary is designed so the notary can disappear tomorrow and every receipt it ever issued stays verifiable.
Here's the offline verification recipe. No API key, no contact with the notary, no SDK required:
- Fetch the canonical payload from 0G Storage using
storage_tx(any public 0G node will do). - Recompute keccak256 over the canonicalized payload. Compare to
payload_hash. If they differ, the receipt is dead. - Take the EIP-191 signed digest:
"\x19Ethereum Signed Message:\n" + len(payload_hash_bytes) + payload_hash_bytes. Feed it plus the signature toecrecover. You get back the signer address. - Confirm the recovered address equals the published EVIDIQ Notary signer (
0xEv1d1Q…Notary). - Walk the
merkle_prooffrom the payload up tostorage_root. Any node endpoint can do this.
Five steps. All local. All deterministic. The math is simple — and that's the point.

The trust model shifts in an interesting way when you verify offline. You're not trusting EVIDIQ to tell you the truth — you're trusting cryptography and a public storage layer. The notary's role narrows to "I saw this happen at this time and I'm willing to put my reputation on it." If the notary ever lies, anyone holding a forged receipt can prove the signature doesn't match the canonical payload hash. If the storage layer is ever compromised, the merkle proof against storage_root fails. Either way, the failure is detectable.
For a deeper walkthrough with worked examples in Solidity and TypeScript, the EVIDIQ Notary docs page spells out the exact byte layouts and provides reference implementations. We keep them updated whenever the canonicalization rules change, because "deterministic" only matters if everyone agrees on what "canonical" means.
What about the notary key itself? It lives in an HSM-style key custody setup — the key never appears in plaintext on a signing host. We rotate it on a published schedule and the old keys stay verifiable forever (the address is the identity, not the key material). Old receipts don't go stale.
