ZanoraBetaDocs

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": { "amountMicros": "1000000", "currency": "USD" },
  "responseHash": "9f2c…",
  "status": "success",
  "timestamp": "2026-09-24T10:12:03.114Z",
  "signature": "…",
  "signingKeyId": "key_…"
}
FieldMeaning
statussuccess: charged and delivered. failed: the seller's handler failed and the buyer was refunded. refunded: Zanora reversed a successful purchase after the fact (see below)
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.

Reversed purchases

If a call succeeded but you're unhappy with the result, contact the seller first. You can also email support@zanora.dev within 30 days of the purchase with the receipt id (Terms §5). If Zanora reverses it:

  • the buyer's wallet gets the full price back, the seller's wallet gives up what it was paid for the call, and Zanora gives up its fee. All three are new ledger entries; nothing is edited;
  • a second, signed receipt is issued for the same transactionId with status: "refunded". The original success receipt stays as it was, because it is still a true record of what was bought and delivered;
  • a purchase is reversed at most once, and not after 30 days.

A seller who has already been paid out for the call can end up with a negative balance, which is settled from future earnings.

Two checks, two claims

The SDK 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 (no API key needed) and verify:

Terminal
curl -s https://api.zanora.dev/v1/platform/receipt-keys/$SIGNING_KEY_ID
# → { "keyId": "key_…", "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.