Wallet Data Walkthrough
Pull native balances, ERC-20 holdings, NFT positions, transfer history, approvals, swaps, and a wallet-level PnL — all from one address path.
The wallet surface lives under GET /v1/wallets/{address}/... and is the most-used part of the API. This guide walks through the five endpoints you will hit most often, with real request and response shapes, then points at the rest.
Endpoint map
| Endpoint | Returns | Typical use |
|---|---|---|
GET /v1/wallets/{address}/native-balance | Native gas-token balance at tip | Quick "is this wallet active?" check |
GET /v1/wallets/{address}/balances | Native + ERC-20 balances, USD valuation | Portfolio dashboards |
GET /v1/wallets/{address}/native-transfers | Paginated native (ETH/BNB/MATIC/…) transfers | Cash-flow / accounting feeds |
GET /v1/wallets/{address}/erc20-transfers | Paginated ERC-20 transfers | Token activity, tax exports |
GET /v1/wallets/{address}/transfers | Combined feed (native + ERC-20 + NFTs) | One-call wallet history |
GET /v1/wallets/{address}/nft-transfers | Paginated NFT (ERC-721/1155) transfers | NFT lifecycle, mints, sales |
GET /v1/wallets/{address}/nfts | Current NFT holdings | NFT portfolio views |
GET /v1/wallets/{address}/approvals | Outstanding ERC-20 / NFT approvals | Risk dashboards ("revoke.cash" style) |
GET /v1/wallets/{address}/defi-positions | Open Lido / Aave V3 / Compound V3 / Uniswap V3 positions | DeFi exposure (see DeFi guide) |
GET /v1/wallets/{address}/swaps | Decoded DEX swaps (Uniswap, Sushi, Curve, …) | PnL attribution, slippage analysis |
GET /v1/wallets/{address}/pnl | Realised + unrealised PnL roll-up | Tax / performance reports |
GET /v1/wallets/{address}/net-worth | Total USD value across chains | Single-number portfolio summary |
GET /v1/wallets/{address}/details | Metadata: contract / EOA, first/last seen, tx count | Address fingerprinting |
GET /v1/wallets/{address}/interactions | Counterparties grouped by frequency | Graph / cluster analysis |
GET /v1/wallets/{address}/domains | ENS / Unstoppable / SNS name resolution | Display names |
All endpoints accept an optional chain query parameter (slug — see Chain IDs). Omit it to query Ethereum mainnet by default; pass ?chain=all (on supported endpoints) to fan out across every indexed chain.
Example 1 — current portfolio value
Get every token balance for an address on Ethereum, with USD valuation.
curl 'https://api.cryptachain.com/v1/wallets/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/balances?chain=ethereum' \
-H "X-API-Key: $CRYPTACHAIN_API_KEY"import os, requests
r = requests.get(
"https://api.cryptachain.com/v1/wallets/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/balances",
params={"chain": "ethereum"},
headers={"X-API-Key": os.environ["CRYPTACHAIN_API_KEY"]},
)
data = r.json()
print(f"Total: ${data['total_usd']:,.2f} across {len(data['balances'])} assets")const r = await fetch(
'https://api.cryptachain.com/v1/wallets/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/balances?chain=ethereum',
{ headers: { 'X-API-Key': process.env.CRYPTACHAIN_API_KEY! } },
);
const data = await r.json();
console.log(`Total: $${data.total_usd.toFixed(2)} across ${data.balances.length} assets`);Response (truncated):
{
"address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
"chain": "ethereum",
"balances": [
{ "asset": "ETH", "balance": "1234.567890123456789", "balance_usd": 4815162.34, "type": "native" },
{ "asset": "USDC", "contractAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"balance": "50000.000000", "balance_usd": 50000.00, "type": "erc20" }
],
"total_usd": 4865162.34,
"block_number": 21950000,
"timestamp": "2026-04-04T14:30:00Z"
}Add ?includeSpam=true to receive suspected airdrop / spam tokens (filtered out by default — see the spam detection section below).
Example 2 — full ERC-20 history for a tax export
Pull every USDC transfer for an address in a date range, with USD valuation at the time of each transfer.
curl 'https://api.cryptachain.com/v1/wallets/0xd8dA.../erc20-transfers' \
--data-urlencode 'chain=ethereum' \
--data-urlencode 'contractAddress=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' \
--data-urlencode 'fromDate=2026-01-01T00:00:00Z' \
--data-urlencode 'toDate=2026-03-31T23:59:59Z' \
--data-urlencode 'limit=1000' \
-G \
-H "X-API-Key: $CRYPTACHAIN_API_KEY"Response shape (one transfer):
{
"txHash": "0xabc...",
"blockNumber": 21950100,
"timestamp": "2026-04-04T14:35:00Z",
"from": "0xd8dA...",
"to": "0x1234...",
"contractAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"tokenSymbol": "USDC",
"tokenDecimals": 6,
"value": "50000.000000",
"direction": "out"
}The response includes a cursor token; pass it back as ?cursor=... to walk through every page. See Batch processing for the full pagination loop and rate-limit-aware retry pattern.
Date range is capped at 365 days
fromDate / toDate must span ≤ 365 days. For longer windows, walk the range in 12-month chunks. The cursor inside a single window is unbounded.
Example 3 — combined native + token feed (one call)
If you want all activity, not just one asset class, use /transfers instead of the per-type variants. It returns native, ERC-20, and NFT transfers in a single chronological stream.
curl 'https://api.cryptachain.com/v1/wallets/0xd8dA.../transfers?chain=ethereum&limit=5&includePrices=true' \
-H "X-API-Key: $CRYPTACHAIN_API_KEY"Each row carries direction ("in" / "out") relative to the queried address — there's no need to compare from / to yourself. Setting includePrices=true adds price_usd and value_usd columns, valued at the block timestamp. The default currency=USD can be swapped for any of the 36 supported currencies.
Trade-off: the combined endpoint is convenient but slightly slower (~50ms vs ~30ms for the per-asset-class variants), because three indexes are scanned. For high-throughput exports, prefer the per-type endpoints.
Spam and airdrop filtering
By default, /balances, /erc20-transfers, and /transfers filter out tokens that the spam detector flags as airdrop spam (homoglyph names, suspicious URLs in the symbol, "claim reward" patterns, contracts that have never received a non-airdrop transfer). To bypass the filter, pass ?includeSpam=true.
This is opt-in for a reason: most users do not want to see thousands of $1 worth of garbage tokens in a portfolio view. If you are building a security tool or block-explorer, set it to true.
DeFi positions
For non-trivial positions — LP shares, lending collateral, staking — use /defi-positions, which decodes the underlying protocol state (Lido stETH shares, Aave V3 supply / borrow, Compound V3 markets, Uniswap V3 NFTs). See the DeFi guide for the full response shape and supported protocols.
Multi-chain queries
Most endpoints accept chain= as a slug (ethereum, polygon, bsc, …). Some — like /balances and /net-worth — also accept chain=all to fan out across every indexed chain in parallel. This is slower (the response is gated by the slowest chain), but saves you N round-trips for portfolio dashboards.
Common pitfalls
Address case
For EVM chains, addresses are stored lowercase in the index. The API accepts mixed-case (EIP-55) input and normalises it; you can pass 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 or 0xd8da6bf26964af9d7eed9e03e53415d37aa96045 — both match. For Bitcoin / Solana / TRON, addresses are case-sensitive — passing the wrong case will return 400 INVALID_ADDRESS.
Tip-of-chain vs historical balance
/native-balance and /balances return the current balance. To get a balance at a historical block, use the transfer history and sum debits/credits yourself, or contact us about the per-block snapshot endpoint (Enterprise tier).
Try it live
The /playground lets you call any of the wallet endpoints with your own API key. Filter the operations list by tag Wallets to scope down.
Next steps
- Authentication — set up your API key
- Rate Limits — understand quotas before fanning out
- DeFi guide — drilling into open positions
- Screening guide — pair wallet data with compliance checks