Tokens API
Are the top holders one entity, or independent?
Direct transfer links among a token's top 80 holders — evidence of a connection, never proof of one entity; no link found is not the same as independent.
/api/external/token-analysis/holder-relationships/{chain}/{mint}What it returns
Analyses the top 80 holders of a token (a fixed, published cap — never caller-chosen; see topHoldersAnalyzed) and reports every direct transfer relationship the source found among them. A relationship is EVIDENCE of a connection, never proof of one entity: a repeated direct transfer of the QUERIED token between two top holders is a strong signal, while a single shared transfer of an unrelated asset (a common exchange withdrawal, a native-coin gas top-up) is real but far weaker — sameTokenAsQueried is what lets a caller tell the two apart; this endpoint does not collapse them into one verdict. "No relationship found" is NOT "these holders are independent." relationshipCount: 0 means no direct transfer was found among the addresses actually analysed — it says nothing about a cluster starting at rank 81, and nothing about a connection through a mechanism this endpoint cannot see at all (a shared exchange account, an off-chain agreement, a funding path through an address outside the analysed set). topHoldersAnalyzed and relationshipCount are null only when the analysis could not run at all; 0 always means it ran and found nothing.
Chains
- Solana SOL
- BNB Chain BNB
- Ethereum ETH
- Base BASE
- Robinhood Chain RHC
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/token-analysis/holder-relationships/SOL/<mint>"
| Parameter | Description |
|---|---|
chainpath · string · required | SOL, ETH, BNB, BASE and RHC, all proven populated. STABLE and ARC are not indexed by the underlying source on any endpoint. CELO, ARB, OP and SCROLL return 400 here. |
mintpath · string · required | The token mint address (Solana) or contract address (EVM). |
Response fields
A JSON response. Every field is always present; null means the value could not be established, never zero.
| Field | Type | Description |
|---|---|---|
topHoldersAnalyzed | integer | null | How many of the token's top holders were actually analysed — equal to 80 for any token with at least that many indexed holders, and genuinely lower only for a token with fewer. null only when the analysis could not run at all (no eligible source, or the source failed entirely) — never a claim that the token has zero holders. |
relationshipCount | integer | null | Count of relationships. null only when the analysis could not run; 0 means it ran and found no direct relationship among the analysed holders — see this endpoint's own description for what that does and does not mean. |
relationships | object[] | Always an array — [] whether the count above is 0 or null. |
relationships[].fromAddress | string | One of the two addresses in this relationship. |
relationships[].toAddress | string | The other address. The from/to direction is the source's own reporting of a transfer direction, not a claim about who initiated the relationship in general. |
relationships[].fromHolderRank | integer | null | fromAddress's rank (1 = largest) among the topHoldersAnalyzed addresses. null only if it could not be matched back to the analysed list, which should not happen. |
relationships[].toHolderRank | integer | null | toAddress's rank, same caveat as fromHolderRank. |
relationships[].relationType | string | null | The source's own relationship label. Only "GROUPED_TRANSFER" has ever been observed; passed through raw in case the source adds a new one. null only when absent. |
relationships[].isNativeAsset | boolean | True when the moved asset is the chain's native coin rather than a token. |
relationships[].assetChain | string | null | The source's own chain identifier for the moved asset (its own spelling, not this API's chain enum). null only when the source omitted it entirely. |
relationships[].assetAddress | string | null | The moved asset's address, or the literal string "native" when isNativeAsset is true — passed through as the source reports it rather than translated. null only when the source omitted it entirely. |
relationships[].sameTokenAsQueried | boolean | True only when this relationship moved the EXACT token this request asked about. THIS IS THE FIELD THAT SEPARATES "these two holders transacted the token in question" FROM "these two holders also happen to share some unrelated transfer" (a common exchange withdrawal, a native-coin gas top-up) — read it before treating any row as evidence about this specific token. Computed from each row's own reported asset, never from the request: this source does not actually scope its answer to the token asked about. |
relationships[].totalAssetAmount | number | null | Total amount of the asset moved between these two addresses, in the asset's own human-readable units (already decimal-adjusted by the source). NEVER USD — it is a quantity of whatever assetAddress names, and different rows can be different assets with different scales; do not sum across rows with different assetAddress values. null only when the source omitted it. |
relationships[].totalTransfers | integer | null | How many individual transfers this grouped relationship represents. null only when the source omitted it. |
relationships[].firstTransferAt | integer | null | Unix seconds of the earliest transfer in this relationship. null only when the source omitted it. |
relationships[].lastTransferAt | integer | null | Unix seconds of the most recent transfer in this relationship. null only when the source omitted it. |
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