Written for the Nansen API team; every item was hit for real while building this. Ordered by impact on the build.
- Entity labels are in one 1-credit place only.
profiler/address/counterparties.counterparty_address_label,first-funder.first_funder_nameandrelated-wallets.address_labelreturn wealth/activity tags ("Token Billionaire", "High Activity", ENS names). Binance 14 — the most famous labelled address on Ethereum — comes back as["Token Billionaire"]. The entity name appears inprofiler/address/labels(100 credits) and, unexpectedly, intransaction-with-token-transfer-lookup.token_transfer_array[].from/to_address_label("🏦 Binance 14", "🏦 Binance: Deposit") for 1 credit. Nothing in the docs says the transaction lookup carries entity labels; it is the best-value field in the API for identity questions. Suggest: expose the same label string on the profiler endpoints, or document the difference. - The all-time date range times out on busy addresses.
profiler/address/transactionswithdate: {from: 2015-07-30, to: 2030-01-01}returns HTTP 500 after ~30 s on the Uniswap V2 router and hangs past 8 s on Binance 14 and the USDT contract; a 14-day window answers in 1–6 s.counterpartiesbehaves the same. Suggest: a documented max range, or a fast-fail 4xx instead of a 30 s 500. - Burn addresses are rejected with 422 (
"Burn address not allowed") ontransactionsandcounterparties, butfirst-funderandrelated-walletsanswer normally for the same address (with 20 "Multisig Signer of" rows for 0x…dEaD). We use the 422 as a signal; documenting it would make that intentional. transaction-with-token-transfer-lookuptop-levelto_address_labelis not the transfer's label. For an ERC-20 transfer the top-leveltois the token contract and its label shows an ENS reverse record ("pssssssshao.eth" for USDT, "usdc.eth*" for USDC). Onlytoken_transfer_array[]labels are usable.token_symbolsometimes contains U+FFF0 ("USDT") in multi-transfer lookups, and spoof tokens with homoglyph symbols ("ÚЅDТ") passhide_spam_token: true. The latter is actually useful (it is how we detect address poisoning) but "hide spam" suggests otherwise.profiler/address/first-funderreturnsdata: []for wallets that never received native gas (e.g. a fresh Binance withdrawal recipient) — documented, and correct, but areasonfield would save a lookup.search/entity-nameis a name search,search/generalis the endpoint that accepts an address. The names suggest the opposite.counterpartiesreturns one row per (address, token), so the same counterparty appears several times;group_by: "entity"collapses rows but does not expose the entity name, so it cannot be used to name the counterparty.- Address validation is strict and helpful (
422 Invalid address formatfor 39 hex chars) — good; the CLI validates client-side to avoid the round trip. - Rate limits were never an issue at ≤ 10 calls per verdict; the free-tier 15 req/s cap was not approached.
- Emoji prefixes carry meaning (🏦 exchange-like incl. DEX routers, 🤖 automated/contract) but are undocumented; we strip them before parsing and treat 🏦 as a hint only.
Positive notes: X-Nansen-Credits-Cost/Remaining headers make budgeting trivial; 4xx bodies are JSON with a message; the openapi.json is accurate for every body we send.