Skip to content
API AccessScanner API reference

Wallet scans

Run a wallet scan on Solana or Robinhood Chain as JSON or a live stream, or read the latest cached scan for free.

A wallet scan finds where a wallet's money came from, where it went, the wallets connected to it, and bundled wallets. It is the same scan as the Deep Scan in the dashboard.

6 routes. Every path below is served under https://api.scanner.net, and every request carries the key header, so those two are not repeated per route. Shared errors, limits and streaming are in Requests and errors.

Scan depth and cost

depth sets how far the scan goes, and what it costs:

depthDashboard nameCost
0Quick1 scan
1 (default)Deep2 scans
2Max4 scans

The scan is charged before it starts and refunded if it fails. The cached routes are free.

Solana wallet scan

POST /scan

Runs a Solana wallet scan and returns the result when it finishes. A Max scan can take several minutes; use the stream to see progress.

ParameterInTypeRequiredNotes
addressbodystringyesSolana address, or a .sol domain.
depthbodynumberno0, 1 or 2. Default 1.
freshbodybooleannotrue skips any reused result and scans again. Default false.
curl -X POST "https://api.scanner.net/scan" \
  -H "Authorization: Bearer $SCANNER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"address":"WALLET_ADDRESS","depth":1}'

Response: the scan result, a WalletScanResult, with no wrapper. Key fields:

  • address: the scanned wallet.
  • originalFunder: the first wallet or entity that funded it, when found.
  • fundedBy, fundingTo, fundingReceived: wallets that sent funds to it and received funds from it.
  • connectedAddresses: other wallets linked to it.
  • bundledWallets: wallets that trade together with it.
  • walletBalances: balances and USD value, when available.
  • solDomains, ownedSolDomains: .sol domains linked to the wallet.
  • scanComplete: false when the scan stopped early and the result is partial.

The cost is charged on every call, even when part of the result is reused.

StatusCodeWhen
400MISSING_ADDRESSNo address.
400INVALID_ADDRESSNot a Solana address, or a .sol domain that doesn't resolve.
400INVALID_DEPTHdepth isn't 0, 1 or 2.
402INSUFFICIENT_CREDITSNot enough scans left.
403NON_SCANNABLE_WALLET_SCANThe address is an exchange, protocol, token, program or liquidity pool, not a wallet. The body adds entity and address.
504TIMEOUTThe scan ran out of time. The scan is refunded.

Solana wallet scan stream

GET /scan/stream

The same scan as POST /scan, sent as server-sent events while it runs. It costs the same.

ParameterInTypeRequiredNotes
addressquerystringyesSolana address, or a .sol domain.
depthquerynumberno0, 1 or 2. Default 1.
freshquerystringnotrue or 1 scans again.
curl -N "https://api.scanner.net/scan/stream?address=WALLET_ADDRESS&depth=2" \
  -H "x-api-key: $SCANNER_API_KEY"

Events: progress events such as profile, transactions_progress (fetched), processing_complete, analysis_progress (step, status), original_funder, domains, identities, balances, bundle_detection (bundledCount), holdings, depth2_progress and kol_data. Then complete, holding the full WalletScanResult described above. A failure sends error with code TIMEOUT or INTERNAL_ERROR, and the scan is refunded.

Errors before the stream opens: the same as POST /scan.

Solana cached wallet scan

GET /scan/cached

The most recent saved scan of a Solana wallet, from any Scanner user. Free. It never starts a scan.

ParameterInTypeRequiredNotes
addressquerystringyesSolana address. .sol domains are not accepted here.
depthquerynumbernoPreferred depth, 0, 1 or 2. If there is no saved scan at that depth, the deepest saved one is returned.
curl "https://api.scanner.net/scan/cached?address=WALLET_ADDRESS&depth=1" \
  -H "Authorization: Bearer $SCANNER_API_KEY"

Response:

{ "depth": 1, "scannedAt": "2026-11-12T09:30:00.000Z", "isStale": false, "scanResult": { "address": "...", "fundedBy": [] } }

isStale is true when the scan is more than an hour old. scanResult is a WalletScanResult. Check its scanComplete field: a saved scan can be partial.

This route has a per-IP limit.

StatusCodeWhen
400INVALID_ADDRESSNot a Solana address.
403NON_SCANNABLE_WALLET_SCANThe address is not a wallet.
404NOT_FOUNDNo saved scan for this wallet.
429RATE_LIMITED_SCANThe per-IP scan limit was reached.

Robinhood Chain wallet scan

POST /rh/scan

Runs a Robinhood Chain wallet scan and returns the result when it finishes. Only externally owned wallets can be scanned, not contracts.

ParameterInTypeRequiredNotes
addressbodystringyes0x address, 40 hex characters.
depthbodynumberno0, 1 or 2. Default 1.
freshbodybooleannotrue skips the cache and scans again.
curl -X POST "https://api.scanner.net/rh/scan" \
  -H "x-api-key: $SCANNER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"address":"0xWALLET_ADDRESS","depth":1}'

Response: a RobinhoodWalletScanResult, with no wrapper. Key fields: address, originalFunder, fundedBy, fundingTo, fundingReceived, connectedAddresses, bundledWallets, walletBalances (ethBalance, ethUsdValue, totalUsdValue, topTokens) and scanComplete.

Cost: a scan of the same wallet at the same depth from the last hour is returned free, unless fresh is true. Otherwise the depth cost applies.

StatusCodeWhen
400INVALID_INPUTInvalid address, or depth isn't 0, 1 or 2.
402INSUFFICIENT_CREDITSNot enough scans left.
422INVALID_INPUTThe address is a smart contract. Wallet scans only support wallets.
502UPSTREAM_ERRORThe Robinhood Chain indexer is unavailable. The scan is refunded.

Robinhood Chain wallet scan stream

GET /rh/scan/stream

The same scan as POST /rh/scan, as server-sent events. It costs the same.

ParameterInTypeRequiredNotes
addressquerystringyes0x address.
depthquerynumberno0, 1 or 2. Default 1.
freshquerystringnotrue or 1 scans again.
curl -N "https://api.scanner.net/rh/scan/stream?address=0xWALLET_ADDRESS&depth=0" \
  -H "x-api-key: $SCANNER_API_KEY"

Events: on a cache hit, cache_hit (scannedAt, isStale) and then complete. On a live scan, progress events (profile, transactions_progress, processing_complete, analysis_progress, original_funder, balances, bundle_detection, holdings), heartbeat every 15 seconds, then complete with the RobinhoodWalletScanResult. A failure sends error with code INVALID_INPUT (contract address), UPSTREAM_ERROR, TIMEOUT or INTERNAL_ERROR.

Errors before the stream opens: the same as POST /rh/scan.

Robinhood Chain cached wallet scan

GET /rh/scan/cached

The most recent saved scan of a Robinhood Chain wallet. Free.

ParameterInTypeRequiredNotes
addressquerystringyes0x address.
depthquerynumbernoPreferred depth, 0, 1 or 2.
curl "https://api.scanner.net/rh/scan/cached?address=0xWALLET_ADDRESS" \
  -H "x-api-key: $SCANNER_API_KEY"

Response: { depth, scannedAt, isStale, scanResult }, where scanResult is a RobinhoodWalletScanResult.

StatusCodeWhen
400INVALID_INPUTInvalid address.
404NOT_FOUNDNo saved scan for this wallet.

View this page as Markdown