Wallets API
A wallet's outstanding token approvals
Which token approvals a wallet has granted -- token, spender, whether it is unlimited, and whether the spender is flagged. BNB and BASE only.
/api/external/wallet-analysis/wallet-approvals/{chain}/{address}What it returns
Lists the standing ERC-20 approvals a wallet has granted -- one entry per (token, spender) pair, flattened across every token the source reports. BNB and BASE ONLY (2 of the 7 chains this surface serves) -- every other chain 400s by name rather than silently returning an empty list, because an empty approvals on an unserved chain would otherwise read as "no approvals" when the honest fact is "not asked". approvals is null when the source could not be reached at all (distinct from a confirmed, genuinely empty list, published as []). isUnlimited: true is the source's own sentinel for "no ceiling" -- but it is a BUCKET, not a proof the allowance equals the maximum: measured live 2026-09-18, one approval the source classified as unlimited was large but NOT the maximum representable value, so never read true as an exact ceiling; when isUnlimited is false, amount carries the source's own raw, unparsed string, since this surface has no confirmed numeric shape for a finite approval on this path. spenderFlagged is true only when the source has a real risk signal on the SPENDER contract, and null otherwise -- it is NEVER a confident false, the same rule wallet-risk uses for its own flagged field, because the source's risk database holds a verdict only for addresses it has something on.
Chains
- BNB Chain BNB
- Ethereum ETH
- Base BASE
Request
Send your key in the x-dex-data-key header. Replace each <placeholder> with a real value.
curl -H "x-dex-data-key: $DEXDATA_API_KEY" \ "https://api.dexdata.io/api/external/wallet-analysis/wallet-approvals/BNB/<address>"
| Parameter | Description |
|---|---|
chainpath · string · required | The chain the wallet address belongs to. BNB, ETH and BASE are served; SOL, STABLE, RHC and ARC all return 400. On ETH the answer is capped per request and truncated says whether the cap was reached. CELO, ARB, OP and SCROLL return 400 here. |
addresspath · string · required | The wallet address. |
Response fields
A JSON response. Every field is always present; null means the value could not be established, never zero.
| Field | Type | Description |
|---|---|---|
truncated | boolean | Whether this wallet holds MORE outstanding approvals than one request returns. false on the chains whose source answers a wallet's full approval set in a single call, and on ETH whenever the wallet fits inside the cap. When true, approvals is a SUBSET and a caller must not read "nothing risky here" from it: the entries are real, the absence of a risky one is not evidence. THE CAP EXISTS BECAUSE THE ETH SOURCE PAGINATES WITHOUT A CEILING and its rows are NOT ordered by time in either direction, so a cheaper single page would be an unlabelled sample of a wallet rather than its most recent approvals. It is set to cover a wallet with 687 approvals whole, so true means unusually large rather than "as always". It describes the LIST only. An approval whose spender risk could not be looked up says so on that entry, with spenderFlagged: null. |
approvals | object[] | null | One entry per outstanding (token, spender) approval. null when the source could not be asked at all (never on BNB/BASE under normal operation -- only a source-side failure). A genuinely empty book is [], not null -- the two are never conflated. |
approvals[].tokenAddress | string | The token contract this approval is for. |
approvals[].tokenName | string | null | The token's own name, on-chain metadata set by its deployer. null if the source sent nothing. |
approvals[].tokenSymbol | string | null | The token's own symbol/ticker. Same provenance and nullability as tokenName. |
approvals[].spender | string | The contract this approval allows to move tokenAddress on the wallet's behalf. |
approvals[].spenderName | string | null | The source's own name for the spender contract, e.g. "AllowanceHolder". Not every spender is named. May be a fixed redaction string if the source's own answer named one of this surface's upstream data providers. |
approvals[].spenderTag | string | null | The source's own classifier tag for the spender, e.g. "UniswapV2". Same redaction behaviour as spenderName. Never observed populated in this endpoint's own measurement -- a real value here is unconfirmed on this path. |
approvals[].isUnlimited | boolean | null | Whether the source classifies this approval as having no ceiling. This is the source's own bucket, NOT a proof that the allowance equals the maximum -- one measured approval in that bucket was large but not the maximum representable value, so do not read true as an exact ceiling. null only when the source sent neither the sentinel nor any other value (never observed live; defensive). |
approvals[].amount | string | null | The exact allowance as the source's own RAW, UNPARSED string, only when isUnlimited is false. null when the approval is unlimited (no ceiling to report -- never fabricated) or the source gave nothing. This surface has never observed a finite value live on this path, so its numeric shape (decimalised vs raw base units) is unconfirmed and republished as-is rather than guessed at. |
approvals[].approvedAt | integer | null | Unix seconds -- when this approval was (most recently) granted. null if the source sent nothing. |
approvals[].txHash | string | null | The transaction hash of the (most recent) approval. null if the source sent nothing. |
approvals[].spenderFlagged | boolean | null | Whether the source has a real risk signal on record for the SPENDER contract. NEVER a confident false: the source's risk database holds a verdict only for addresses it has something on, the same rule wallet-risk's own flagged field uses. true only when a real signal fired; null otherwise. |
approvals[].spenderRiskFlags | string[] | null | The source's own risk-signal names for the spender, e.g. "phishing_activities", "stealing_attack". [] when the risk source answered and nothing fired; null when no risk source answered about this spender. |
Start building with DexData today
Sign in, create a key and make your first call in a minute. Free credits every month, and you only pay for calls that succeed.
Get a free API key