ZanoraBetaDocs

After the purchase

The problems buyers run into most, what causes each one, and the fix.

Start with GET /v1/whoami. It shows whether your key works and what it's allowed to do.

Discovery returns {"results":[]}
  • Your filters are too narrow: try without maxPriceMicros, category or protocol.
  • The seller you're looking for isn't verified yet. Unverified sellers don't appear in discovery. If you know their capability id, GET /v1/capabilities/:id still describes it, but without an address to call.
  • Check the capability exists at all: the demo seller always appears for query: "invoice".
"invalid api key" / 401 on every call
  • ZANORA_API_KEY is missing (MCP) or apiKey wasn't passed (SDK). The wallet's private key signs payments, but API calls still need the workspace key.
  • If ZANORA_WALLET_ID isn't set either, @zanora/mcp stops at startup with ZANORA_API_KEY is not set instead. A key it sent and the gateway refused reads the gateway … refused ZANORA_API_KEY.
  • The key was revoked, expired, or rotated past its grace period. Mint a new one in Settings.
INVOKE_FAILED — fetch failed (balance unchanged)

The seller's URL isn't reachable from where your agent runs, usually because it's a localhost address published from someone's laptop. Nothing was charged: the call failed before the 402. Tell the seller, or pick another capability.

POLICY_DENIED when you expected ALLOW
  • matchedRule in the error says which rule matched. workspace.dailyBudget means the daily cap was reached. allow means allow rules exist and none matched.
  • Remember price in rules is in dollars: price > 5 means more than $5.00.
  • GET /v1/policies lists what's actually active.
APPROVAL_REQUIRED again after approving

An approval covers one purchase at up to the approved amount. The retry uses it up, and the next call is held again. To stop being asked for that kind of spend, change the rule.

INSUFFICIENT_FUNDS right after funding

Funding is credited when the rail confirms, not when you submit it. GET /v1/rail/transactions shows the deposit's state. A USDC deposit made while USDC was more than 0.5% away from $1 is held and credited later.

WALLET_PROVIDER_PAUSED

That seller failed three charged calls in a row for this wallet, so calls between them are paused (and you were refunded for each failure). Only the seller's own failures count: a 5xx, a crash, an MCP isError or a timeout. A 4xx for a bad request is refunded but never pauses you. Wait for the pause to lift, or POST /v1/wallets/:id/resume-provider with {"providerId":"prv_…"}.

"ZANORA_WALLET_ID is required" / the MCP server lists several wallets

Your workspace has more than one agent wallet, and the server won't guess which one should spend. Set ZANORA_WALLET_ID.

responseHashVerified is false

The receipt is genuine, but it's for a different response than the one you received. Something between you and the seller changed the answer, or the seller returned something other than what it reported to Zanora. Keep the data if it's useful, but don't treat the receipt as proof of it.

Buying an MCP capability throws MCP_TRANSPORT_UNAVAILABLE

The SDK needs an MCP transport: new ZanoraAgent({ …, mcpCaller: new StreamableHttpMcpToolCaller() }) from @zanora/mcp.

A runsLocally capability is refused

Package capabilities (runsLocally: true, payable: false) are listed but can't be bought yet, so NOT_SUPPORTED is expected and nothing was charged. Pick a hosted result with payable: true. See Seller packages.

Still stuck?

Email support@zanora.dev with your wsp_… id and the errorId from any 500 response, or the approvalId / transactionId involved. Never send an API key or a private key.