Token Approval Security
Synchronous, risk-scored view of a wallet’s outstanding token approvals.
summary aggregates total USD at risk so an approval-manager screen can render its banner without walking the array.
Request Notes
Supported Chains
Only Ethereum (1), BNB Smart Chain (56), and TRON. See Supported Chains. Any other chainId is rejected with 400.
Responses are cached ~60 seconds per unique query + flag combination. A revocation the user just made may take up to that long to disappear.
On TRON, responses echo case-preserved base58 — TRON encodes its checksum in letter casing, so a lowercased TRON address is not usable. Use the returned form for anything sent to a node or explorer.
Request Combinations
At least one ofowner or spender is required. token cannot be sent on its own.
Opt-In Fields
These response fields are added only when you set the matching request flag totrue. All flags default to false. Enable only the enrichments you render — each flag adds a lookup and its own latency. For a wallet-facing approval list, includeBalance + includeSpenderRisk is usually the right pairing.
false or omitted, that field is left out of the JSON — you did not ask for it.
If the flag is true, the field is always in the JSON. A value means the lookup succeeded. null means the lookup failed; the rest of the row is still valid. Prefer retrying over showing an error screen.
In JavaScript, check that the key exists ("spender_risk" in row) before reading it. Do not use row.spender_risk !== null — a missing key is undefined, and undefined !== null is true.
Always send includeBalance: true on an approval-management screen. It turns “Unlimited / Unlimited” into “$4.50 at risk now, unlimited going forward”, and it lets an unlimited approval on an emptied wallet correctly report valid_allowance: "0".
Response Notes
USD Fields
Every row always includes both fields. They are nevernull. They price different amounts and can disagree.
amount_raw, valid_allowance, and balance are uint256-scale strings — parse with BigInt. The USD fields are ordinary floats when they are numbers.
includeBalance: true, an infinite on-chain approval often returns both a number and "Unlimited":
affected_usd_amount:4.5— the wallet holds $4.50, so only that can be taken todaypotential_affected_usd_amount:"Unlimited"— the allowance is still unbounded, so later deposits can be taken too
includeBalance, both fields are often "Unlimited", even if the wallet is empty.
Risk Object
Returned on a row when you setincludeSpenderRisk, includeTokenRisk, or includeOwnerRisk.
risk_level yourself (for example risk_level >= 4). Use is_risky.
Do not write logic against risk_details values (for example "blacklist_manual"). Those strings are not a stable list and can change. The array is [] when is_risky is false.
risk_level is 0, the address is considered safe. -1 means “no data” — do not consider the address as safe.
summary Totals
summary is a page-level banner. Do not add up the rows yourself.
- The same token balance approved to several spenders is counted once, not once per spender.
- Only rows with a number USD value are included.
"Unlimited"and"Unknown"add0. - So
0can mean “nothing at risk” or “every row on this page is unlimited or unpriceable.” - If any row is
"Unlimited"or"Unknown", treat the total as a floor: at least $X, plus N unlimited approvals. includeBalance: trueturns most unlimited rows into a number and closes that gap.
valid_approved_tokens is a lookup table for tokens HashDit has indexed (name, address, price, decimals). Unindexed tokens still appear in approval_status; they are just missing from this list.
hasMore is evaluated before filter: "only-valid" runs, so a filtered page can show count well below limit while hasMore is still true. Do not stop paginating on a short count.Headers
Your HashDit API key
Body
Approval query. At least one of owner or spender is required. token cannot be sent on its own.
int or string. Only 1 (Ethereum), 56 (BSC), or 728126428 / "tron" (TRON). Any other chain is rejected with 400. See Supported Chains.
"56"
Owner / approver address. At least one of owner or spender is required.
"0x26d61f23bbc94d7b2139f9c581722bf4e8b64b87"
Spender address. At least one of owner or spender is required.
Restrict to one token contract. Cannot be sent on its own — token alone returns 400.
1-based page number. Values below 1 are treated as 1.
Rows per page. Ceiling 100 — higher values are clamped, not rejected.
Only "only-valid" is accepted; it drops rows whose valid_allowance is 0. Any other value is a validation error.
Read each token's live on-chain balance for the owner.
Add spender_risk to every row.
Add token_risk to every row.
Add owner_risk to every row.
Classify each spender and owner as "eoa" or "contract".