Skip to main content
The Wallet API manages the business HD wallet tree: deriving addresses, reading them, signing and submitting transactions, and tracking the USD balance used to pay gas on mainnet transfers. Wallets are scoped to the business in your token: accessing another business’s wallet returns 403.
Each operation is gated on a capability granted by your plan; a missing one returns 403: Missing required capability: <capability>. See the capability table on each endpoint.

The wallet object

The transaction object

Transfer lifecycle and outcome delivery

Initiate transfer and sponsored Sign transaction requests are asynchronous by default: the request is validated and recorded, and the API answers 202 with the PENDING transaction while the on-chain execution continues. status moves through:
You get the outcome three ways; use them together:
  1. Poll Get transaction by id with the data.id from the 202 (e.g. every 2–3 seconds) until status is COMPLETED or FAILED. This endpoint is always authoritative.
  2. Outcome webhook: pass webhookUrl in the initiate body and the final transaction is POSTed to you (see below).
  3. Reconcile anything unresolved on your side with Get transaction history filtered by status=PENDING or status=PROCESSING.
Prefer holding the request open instead? Pass waitForCompletion: true to get the legacy synchronous behavior: for transfers, 201 (completed) or 422 (failed) with the settled result; for signs, 200 with the relay result (txHash, gasUsed, feeWei). Expect 3–30s latency depending on the chain.
Signing on a non-EVM chain with an addressIndex is local-only: nothing is broadcast, so there is no transaction to poll. Those requests always answer 200 with the signed transaction, regardless of waitForCompletion.
Lost the transaction id? Re-send the initiate request with the same Idempotency-Key: the original 202 response, including the same data.id, is replayed without creating a second transfer.

Outcome webhook

When you pass webhookUrl, the service POSTs the final transaction there once execution settles, in both async and sync modes:
event is wallet.transfer.completed or wallet.transfer.failed for transfers, and wallet.sign.completed or wallet.sign.failed for sponsored signs; data is the full transaction object, including explorerTxUrl and (on failure) error.
  • Signature: each delivery carries x-wallet-timestamp and x-wallet-signature, where the signature is HMAC-SHA256("<timestamp>.<rawBody>") in hex. Pass your own webhookSecret (16–256 chars) alongside webhookUrl in the initiate request and verify with the value you sent; no out-of-band secret exchange needed. The secret is held in memory only, never persisted or logged. Reject timestamps older than 5 minutes to block replays.
  • Retries: 4 attempts (1s / 5s / 15s backoff, 10s timeout each). Respond 2xx quickly, before running your own processing.
  • Duplicates are possible: key your handling on data.id.
  • Best-effort: treat the webhook as a notification and confirm via Get transaction by id. If no webhook arrives within ~30 seconds, fall back to polling.
  • URL rules: https only in production; localhost, private, and link-local addresses are rejected with 400 INVALID_WEBHOOK_URL.

The balance object