ZZanoraDocs

Core concepts

Every paid call produces a receipt signed by Zanora and bound to the exact response. What it contains, how to check it, and how to find old ones.

What a receipt says

JSON
{
  "id": "rcp_6bd223c5…",
  "transactionId": "txn_498b5328…",
  "providerId": "prv_3652ec9e…",
  "consumerId": "wal_f33b5618…",
  "capabilityId": "cap_d2383f37…",
  "amount": { "amountMinor": "100", "currency": "USD" },
  "responseHash": "9f2c…",
  "status": "success",
  "timestamp": "2026-09-24T10:12:03.114Z",
  "signature": "…",
  "signingKeyId": "rk_…"
}
FieldMeaning
statussuccess: charged and delivered. failed: the seller's handler failed and the buyer was refunded. refunded: refunded after the fact
responseHashsha256 of the response the seller returned. For MCP, it covers the tool's structuredContent when there is one, and its content blocks otherwise
consumerIdthe agent wallet that paid
signature, signingKeyIded25519 over the canonical JSON of every other field

Receipts contain opaque ids only: no names, emails or request bodies.

Two checks, two claims

Both SDKs and both MCP packages return two booleans with every purchase. They're separate on purpose:

CheckClaim
receiptVerifiedZanora signed this receipt, and it hasn't been changed
responseHashVerifiedthis receipt is for the answer you received, not some other answer

A verified receipt with responseHashVerified: false means what arrived isn't what the seller was paid for. The answer may still be useful, but you can't cite the receipt as proof of it.

Verifying a receipt yourself

Receipts are signed over canonical JSON: keys sorted, amounts as strings, without signature and signingKeyId. Fetch the public key for the key id and verify:

Terminal
curl -s https://api.zanora.dev/v1/platform/receipt-keys/$SIGNING_KEY_ID
# → { "keyId": "rk_…", "publicKeyPem": "-----BEGIN PUBLIC KEY-----…" }

Old keys stay available after rotation, so an old receipt can always be checked. In code, agent.verifyReceipt(receipt) in @zanora/sdk, or the zanora_receipt MCP tool, does this for you.

Finding receipts

You wantCall
everything your workspace boughtGET /v1/receipts with a workspace key
everything you soldGET /v1/receipts with a provider key
one receiptGET /v1/receipts/:id
all receipts for one transactionGET /v1/transactions/:id/receipts
from an MCP clientzanora_purchases (buyer) or zanora_sales (seller)

Lists are newest first. To page through, pass ?after=<last receipt id> and follow nextCursor. The cursor is tied to a row rather than an offset, so new sales arriving between pages can't make you skip any. Details are in the API reference.