After the purchase
Buyer troubleshooting
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,categoryorprotocol. - 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/:idstill 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_KEYis missing (MCP) orapiKeywasn'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
matchedRulein the error says which rule matched.workspace.dailyBudgetmeans the daily cap was reached.allowmeans allow rules exist and none matched.- Remember
pricein rules is in dollars:price > 5means more than $5.00. GET /v1/policieslists 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.