Errors

Every response uses the same shape, so you handle errors the same way across the API.

Response envelope

// success
{ "success": true, "data": { … }, "pagination": { "limit": 50, "offset": 0, "has_more": false } }

// error
{ "success": false, "message": "human readable", "error": "machine_code", "details": { … } }

Branch on the HTTP status and the machine-readable error code. message is for humans and may change. details appears on some 4xx errors and carries machine-readable context your code can act on — e.g. nft_approval_missing includes the exact transaction to send in details.nft_approval.call. pagination is only on list endpoints. 5xx responses never leak internal detail — server-side failures all surface as error: "internal_error".

Error codes

Statuserror codesMeaning
400invalid_tier·missing_idempotency_key·invalid_amount·identifier_too_longMalformed request — unknown tier, missing Idempotency-Key header, bad amount, identifier over 255 chars
400missing_shipping_address·invalid_address·token_required·invalid_tx_hash·invalid_status·unsupported_itemBad redemption request (invalid_address also covers a bad PUT /pool-wallet body; invalid_status also a bad ?status= filter)
400invalid_price_queryGET /mystery/price needs exactly one of card_id / token_id
402insufficient_fundsCustodial purchase: end-user available balance is below the tier price
403Insufficient permissionsKey lacks the required scope (or is not a partner-scoped key)
404not_found·token_not_found·pool_wallet_not_setPurchase / webhook / redemption / card / token / pool wallet does not exist (or is not yours)
404value_unknownGET /mystery/price: card exists but no market price is available
409idempotency_mismatch·not_fulfilled·webhook_limitIdempotency-Key reused with a different tier_id / purchase not revealed yet / more than 20 webhooks
409redemption_exists·not_burnable·not_owner·no_holder·no_items·invalid_status·invalid_token_idRedemption conflict — token already redeeming, not redeemable, moved wallets, or wrong lifecycle state
409value_unknownBuyback: no market price available for the card
409nft_approval_missing·card_frozen·no_holder·receiver_signature_mismatch·accept_simulation_failedBuyback accept pre-flight — the live holder hasn’t approved the marketplace (the fix rides in details.nft_approval.call), a pending redemption/grading burn freezes the token, the token was burned, bad signature, or another on-chain rejection (a token that merely moved is followed, not failed)
503relayer_disabled·insufficient_relayer_fundsCustodial purchasing temporarily unavailable — retry later

Each endpoint page in the API Reference lists the exact codes it returns and when — see Purchase (custodial) or Prepare redemption.