Skip to main content

Overview

  • Base path: /api/v1
  • Authentication: API key via x-api-key header
  • Idempotency: write operations require Idempotency-Key header (UUID format)
  • Response format: all responses include x-request-id header for tracking

Endpoints

  • GET /api/v1/wallets – List user wallets
  • GET /api/v1/wallets/balances – Get balances for caller’s wallet (by chain; defaults to default wallet)
  • GET /api/v1/wallets/:address/balances – Get balances for a specific owned wallet
  • GET /api/v1/tx/:id – Get transaction details
  • POST /api/v1/send – Send native assets and tokens (EVM + Solana)
  • POST /api/v1/token/approve – ERC20 token approval (EVM only)
  • POST /api/v1/contracts/send – Generic contract interaction (EVM only)
  • POST /api/v1/trade/quote – Get swap quotes (EVM + Solana)
  • POST /api/v1/trade/swap – Execute swaps (EVM + Solana)

Chains

See the full list in Supported chains. Use the chain slug (for example, base, solana-devnet).

Rate limiting

  • Writes (including POST /api/v1/trade/quote): 15 requests per minute per user
  • Reads: 60 requests per minute per user
  • Response: HTTP 429 when exceeded
  • Headers: Retry-After (seconds until next window)

Idempotency (writes)

  • All mutating endpoints require Idempotency-Key.
  • Reusing a key with the exact same request body returns the original 200 response.
  • Reusing a key with a different body returns HTTP 409 with code: IDEMPOTENT_BODY_MISMATCH.
  • Reusing a key with no stored success response returns HTTP 409 with code: IDEMPOTENT_REPLAY.
  • Keys are scoped to the authenticated user; the endpoint path is recorded for traceability.
  • Applies to: POST /api/v1/send, POST /api/v1/token/approve, POST /api/v1/contracts/send, POST /api/v1/trade/swap.

Error handling

Error response format

{
  "error": "Human-readable error message",
  "code": "ERROR_CODE",
  "requestId": "unique-request-id"
}

Error codes

  • UNAUTHORIZED – Missing/invalid auth or API key (HTTP 401)
  • FORBIDDEN – Authenticated but not allowed to perform the action (HTTP 403)
  • NOT_FOUND – Resource not found (HTTP 404)
  • RATE_LIMITED – Rate limit exceeded (HTTP 429)
  • INVALID_INPUT – Invalid request parameters (HTTP 400)
  • WALLET_NOT_FOUND – Specified wallet not found
  • USER_NOT_LINKED – User not linked to Privy
  • WALLET_NOT_DELEGATED – Wallet not delegated to server signer
  • WALLET_ID_REQUIRED – Missing Privy wallet ID
  • CHAIN_UNKNOWN – Unknown or unsupported chain
  • INSUFFICIENT_FUNDS – Sender lacks funds for value/fee
  • IDEMPOTENT_BODY_MISMATCH – Different request body with same idempotency key (HTTP 409)
  • IDEMPOTENT_REPLAY – Idempotency key already used (HTTP 409)
  • PRIVY_RPC_ERROR – Error from Privy RPC service
  • SEND_FAILED – Transaction submission failed
  • SERVICE_UNAVAILABLE – Required service not configured
  • QUOTE_FAILED – Quote service error (HTTP 400)
  • INTERNAL_ERROR – Server error
QUOTE_FAILED specifics:
  • Solana/Jupiter: Some Solana mints are not tradable on Jupiter (curated allowlist). In those cases, this API returns HTTP 400 with code: QUOTE_FAILED and an error message like: “Token not tradable on Jupiter”.
  • EVM/1inch: If a token is not supported by 1inch, the API returns HTTP 400 with code: QUOTE_FAILED and a message like: “Token not tradable on 1inch”.
  • This is expected when the requested output token/mint is marked non-tradable by the upstream provider, even if pools exist elsewhere.

Validation

Address formats

  • EVM: must match /^0x[a-fA-F0-9]{40}$/
  • Solana: must be a valid base58 public key

Common parameters

  • Amounts (EVM): Integer strings only (decimal or 0x-hex). Must be non-negative. For ERC20 and value, must fit uint256.
  • Amounts (Solana): Integer strings in base units. SPL amounts must fit unsigned 64-bit range.
  • Sender (from): Optional. If omitted, the user’s default wallet for the specified chain is used.
  • Idempotency: All write endpoints require Idempotency-Key header. Repeats with the same body return the original response.

Native token keyword

Trade endpoints (/api/v1/trade/quote, /api/v1/trade/swap) accept the case-insensitive keyword NATIVE for fromToken/toToken:
  • EVM: NATIVE resolves to 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
  • Solana: NATIVE resolves to wrapped SOL mint So11111111111111111111111111111111111111112
  • Responses return resolved addresses (not NATIVE)
  • Send endpoint uses asset: "native" instead of token addresses for native transfers

Conventions

  • Chain selection: use the chain slug (for example, base, base-sepolia, solana-devnet).
  • Solana Transaction.chainId sentinel mapping: 0 = mainnet, -2 = testnet, -3 = devnet.
  • Idempotency: unique per user and key; repeats return the original response; mismatched bodies → 409.