ZZanoraDocs

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 maxPriceMinor, 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.
  • 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

Running seller packages is off unless you allow the package by name in ZANORA_ALLOW_LOCAL_PACKAGES. See Running 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.