CRIUS Docs
API status Get API key
Safety & risk

Read a token's bubble map and holder clusters

Get a Robinhood Chain token's top holders as a graph, with the funding and transfer links that group them. Real examples, with and without clusters.

Updated 3 min read
Short answer

Call GET /v1/robinhood/token/{address}/bubblemap?top=100 (Starter plan, 10 credits). nodes are the top holders with their share (pct), USD value and tags; edges are funding, shared funders and token transfers between them; clusters group linked holders with their total pct, members and the links that join them. Pools, lockers, hooks and burn addresses are listed under hidden_infra, not drawn.

A bubble map shows a token’s largest holders as bubbles and draws lines between the ones that are connected, so you can see at a glance whether “the top 20 holders” are 20 people or one person with 20 wallets. Crius builds it from on-chain funding and token transfers on Robinhood Chain. It only links wallets on evidence that means something (the wallet that first funded them, transfers between them) and leaves out pools, lockers and exchanges, which touch everyone.

Get the map in one call

Two clusters among Rebot's top holders

Rebot (0x192b126efea71ca5e7767bc6fc53038d869fbbba) was an insider launch. Are any of its top 100 holders today the same person?

GET/v1/robinhood/token/0x192b126efea71ca5e7767bc6fc53038d869fbbba/bubblemap?top=100
curl "https://api.crius.sh/v1/robinhood/token/0x192b126efea71ca5e7767bc6fc53038d869fbbba/bubblemap?top=100" \
-H "x-api-key: $CRIUS_API_KEY"
Real response 200 Captured Oct 28, 2026 · 227 lines (arrays trimmed)
{
"data": {
"block": null,
"clusters": [
{
"id": "c_80b9b545",
"includes_dev": false,
"links": {
"funding_between": 0,
"shared_funders": [
{
"address": "0x795834684cdec507ea9ee240fdb7e908567dd316",
"wallets": 2
}
],
"token_transfers": 0
},
"members": [
"0xdebabd206e5a73dd81a9211533a1bd610c006d20",
"0xf0fd2e7718ea59a6ddfe884c7e4714ae2dd5610a"
],
"pct": 3.60847,
"risk": "medium",
"root_funder": "0x795834684cdec507ea9ee240fdb7e908567dd316",
"wallets": 2
},
{
"id": "c_377c5b",
"includes_dev": false,
"links": {
"funding_between": 1,
"shared_funders": [],
"token_transfers": 0
},
"members": [
"0x4eec10e9c115a7ea67b59eea59c3a3c777fab236",
"0xa0686afb77ed32fbb402a39642d05158b9fa4c96"
],
"pct": 2.56134,
"risk": "low",
"root_funder": "0xa0686afb77ed32fbb402a39642d05158b9fa4c96",
"wallets": 2
}
],
"edges": [
{
"block": 78435467,
"eth": 1.2,
"from": "0x795834684cdec507ea9ee240fdb7e908567dd316",
"hub": false,
"to": "0xdebabd206e5a73dd81a9211533a1bd610c006d20",
"type": "common_funder"
},
{
"block": 9427558,
"eth": 2,
"from": "0xa0686afb77ed32fbb402a39642d05158b9fa4c96",
"hub": false,
"to": "0x4eec10e9c115a7ea67b59eea59c3a3c777fab236",
"type": "funding"
},
{
"block": 94538219,
"eth": 2.5,
"from": "0x795834684cdec507ea9ee240fdb7e908567dd316",
"hub": false,
"to": "0xf0fd2e7718ea59a6ddfe884c7e4714ae2dd5610a",
"type": "common_funder"
}
],
"hidden_infra": [
{
"address": "0x8366a39cc670b4001a1121b8f6a443a643e40951",
"label": "uniswap_v4_pool_manager",
"pct": 70.8524,
"tags": [
"pool"
]
},
{
"address": "0x267444d099b10fb5ed7c3cc7b7c767adca574952",
"label": "pons_v2_launch_locker",
"pct": 8.16327,
"tags": [
"lp_locker"
]
},
{
"address": "0xe5e702641ea86f4ae6cc3cdaed2b886f976be044",
"label": "pons_v2_meme_hook",
"pct": 0.000056807,
"tags": [
"launchpad"
]
},
{
"address": "0xf69cd0fe7280773bb9b7c93ab68420d07290afa9",
"label": null,
"pct": 0.00000391777,
"tags": [
"contract"
]
},
{
"address": "0x8cc5b884c33a261fe6aa6499bc7315d5aed57c67",
"label": null,
"pct": 0.0000000000000000000000002,
"tags": [
"contract"
]
},
{
"address": "0x8f10b468b06c6fd214b65f87778827f7d113f996",
"label": null,
"pct": 0.0000000000000000000000001,
"tags": [
"contract"
]
},
{
"address": "0xe6eeda550918638529c6cf2ea14f9ea0572d6f88",
"label": null,
"pct": 0.0000000000000000000000001,
"tags": [
"contract"
]
}
],
"nodes": [
{
"cluster": "c_80b9b545",
"id": "0xdebabd206e5a73dd81a9211533a1bd610c006d20",
"label": null,
"pct": 2.19541,
"tags": [
"smart_account",
"fomo",
"whale"
],
"value_usd": 88.6343
},
{
"cluster": null,
"id": "0xb6815093cf0108d146aee2e98e53c17287c42393",
"label": null,
"pct": 1.86,
"tags": [
"whale"
],
"value_usd": 75.0931
},
{
"cluster": null,
"id": "0xc3403905b4e0ffaf973663ad261639087091a5da",
"label": null,
"pct": 1.68482,
"tags": [
"smart_account",
"fomo",
"whale"
],
"value_usd": 68.0207
},
{
"cluster": "c_377c5b",
"id": "0x4eec10e9c115a7ea67b59eea59c3a3c777fab236",
"label": null,
"pct": 1.46153,
"tags": [
"whale"
],
"value_usd": 59.0056
},
{
"cluster": "c_80b9b545",
"id": "0xf0fd2e7718ea59a6ddfe884c7e4714ae2dd5610a",
"label": null,
"pct": 1.41306,
"tags": [
"smart_account",
"whale"
],
"value_usd": 57.049
},
{
"cluster": "c_377c5b",
"id": "0xa0686afb77ed32fbb402a39642d05158b9fa4c96",
"label": null,
"pct": 1.09981,
"tags": [
"whale"
],
"value_usd": 44.4023
},
{
"cluster": null,
"id": "0x1795eacd1a377133002de3bca335336a19dfa2ca",
"label": null,
"pct": 1.03781,
"tags": [
"whale"
],
"value_usd": 41.8992
},
{
"cluster": null,
"id": "0xa2bfbc13abbf678ed8c743e662ba43fbe18159ea",
"label": null,
"pct": 1,
"tags": [
"whale"
],
"value_usd": 40.3726
}
],
"token": "0x192b126efea71ca5e7767bc6fc53038d869fbbba"
},
"meta": {
"block": 100415559,
"block_age_ms": 766,
"block_ts": 1793225982000,
"chain": "robinhood",
"finalized_block": 100405028,
"lag_ms": 31,
"safe_block": 100408671
}
}

What this tells you

  • clusters has two entries. The larger, c_80b9b545, joins 0xdebabd206e5a73dd81a9211533a1bd610c006d20 and 0xf0fd2e7718ea59a6ddfe884c7e4714ae2dd5610a: together pct: 3.60847 of supply, so risk: "medium" (over 3%).
  • Why they’re linked: links.shared_funders names 0x795834684cdec507ea9ee240fdb7e908567dd316, which first funded both (wallets: 2). It is also the root_funder. The two common_funder edges show it sent 1.2 ETH at block 78435467 and 2.5 ETH at block 94538219.
  • The second cluster, c_377c5b, is a direct link: links.funding_between: 1. The funding edge shows 0xa0686afb77ed32fbb402a39642d05158b9fa4c96 sent 0x4eec10e9c115a7ea67b59eea59c3a3c777fab236 its first 2 ETH at block 9427558, so the funder is a member and the root_funder. Together they hold pct: 2.56134: risk: "low".
  • All three funding edges are far older than Rebot: its launch transaction was at block 100238938. A link records how a wallet was first funded, which can tie wallets together long before they bought this token.
  • Each member node carries its cluster id (cluster: "c_80b9b545"), and includes_dev: false on both clusters: the developer isn’t among them.
  • hidden_infra shows where most of the supply is: the Uniswap v4 PoolManager 0x8366a39cc670b4001a1121b8f6a443a643e40951 holds 70.85% (the pool’s side) and the Pons launch locker 0x267444d099b10fb5ed7c3cc7b7c767adca574952 8.16%. The largest real holder has 2.20%.

No clusters at all: sockets

Are the top 50 holders of sockets (0xddccd4690cc99cf19d2e0bdbcb390d17e913958a) connected to each other?

GET/v1/robinhood/token/0xddccd4690cc99cf19d2e0bdbcb390d17e913958a/bubblemap?top=50
curl "https://api.crius.sh/v1/robinhood/token/0xddccd4690cc99cf19d2e0bdbcb390d17e913958a/bubblemap?top=50" \
-H "x-api-key: $CRIUS_API_KEY"
Real response 200 Captured Oct 28, 2026 · 138 lines (arrays trimmed)
{
"data": {
"block": null,
"clusters": [],
"edges": [],
"hidden_infra": [
{
"address": "0x8366a39cc670b4001a1121b8f6a443a643e40951",
"label": "uniswap_v4_pool_manager",
"pct": 22.2145,
"tags": [
"pool"
]
},
{
"address": "0x267444d099b10fb5ed7c3cc7b7c767adca574952",
"label": "pons_v2_launch_locker",
"pct": 8.16327,
"tags": [
"lp_locker"
]
},
{
"address": "0xe5e702641ea86f4ae6cc3cdaed2b886f976be044",
"label": "pons_v2_meme_hook",
"pct": 6.06241,
"tags": [
"launchpad"
]
},
{
"address": "0xbe0b139abc90723af76a89d3051f60ba1b64c8d9",
"label": null,
"pct": 1,
"tags": [
"contract"
]
},
{
"address": "0xdead000000000000000000000000000000000000",
"label": null,
"pct": 0.81637,
"tags": [
"burn"
]
},
{
"address": "0x0afeb98a5b40bc38e9cf5a3f202c17843a7ce553",
"label": null,
"pct": 0.168848,
"tags": [
"contract"
]
}
],
"nodes": [
{
"cluster": null,
"id": "0xe1a5961d61200006577f2e96114d212889213cd6",
"label": null,
"pct": 2.82829,
"tags": [
"smart_account",
"whale"
],
"value_usd": 1286.54
},
{
"cluster": null,
"id": "0xa4109b8d391723d8f6bcfc5d75e6996f61062f76",
"label": null,
"pct": 2.70423,
"tags": [
"smart_account",
"fomo",
"whale"
],
"value_usd": 1230.11
},
{
"cluster": null,
"id": "0xf2caeb616fb22a8acc00afbaeee83b24f18b354b",
"label": null,
"pct": 2.23269,
"tags": [
"smart_account",
"fomo",
"whale"
],
"value_usd": 1015.61
},
{
"cluster": null,
"id": "0xb9b642020e216e84887ad414e067928e380bbbd5",
"label": null,
"pct": 1.77186,
"tags": [
"whale"
],
"value_usd": 805.992
},
{
"cluster": null,
"id": "0xc9cafef2258a07f8455da92438360318b34848e2",
"label": null,
"pct": 1.73578,
"tags": [
"smart_account",
"fomo",
"whale"
],
"value_usd": 789.58
},
{
"cluster": null,
"id": "0xc51c3340b898a67fed7c9f18db75b346dd04f8a0",
"label": null,
"pct": 1.63331,
"tags": [
"smart_account",
"fomo",
"whale"
],
"value_usd": 742.968
}
],
"token": "0xddccd4690cc99cf19d2e0bdbcb390d17e913958a"
},
"meta": {
"block": 100406890,
"block_age_ms": 885,
"block_ts": 1793225087000,
"chain": "robinhood",
"finalized_block": 100397649,
"lag_ms": 30,
"safe_block": 100401329
}
}

What this tells you

  • clusters: [] and edges: []: none of the top 50 holders funded each other, shared a funder or sent each other tokens. Each bubble stands alone.
  • The largest holder, 0xe1a5961d61200006577f2e96114d212889213cd6, has pct: 2.82829 (about $1,287, value_usd). The holder base is spread out.
  • tags say who the holders are: whale (1% or more of supply), smart_account, and fomo for smart accounts created by the FOMO trading app, as with 0xa4109b8d391723d8f6bcfc5d75e6996f61062f76 (2.70%).
  • hidden_infra lists the PoolManager (22.21%), the Pons launch locker (8.16%), the PonsV2MemeHook 0xe5e702641ea86f4ae6cc3cdaed2b886f976be044 (6.06%) and the burn address 0xdead000000000000000000000000000000000000 (0.82%). Left on the map, the PoolManager would look like the largest holder by far.

How to read the map

Nodes are holders: id, pct of supply, value_usd, label, tags and cluster (null when unlinked). Size them by pct and color them by cluster.

Edges say why two bubbles are connected. Funding edges carry from, to, type, eth, block and hub:

Edge typeMeans
fundingOne holder sent the other its first ETH (at least 0.00001 ETH), like 0xa0686afb77ed32fbb402a39642d05158b9fa4c96 → 0x4eec10e9c115a7ea67b59eea59c3a3c777fab236 above.
common_funderAn outside wallet that first funded two or more of the shown holders, like 0x795834684cdec507ea9ee240fdb7e908567dd316.
transfersHolders sent this token to each other.

Clusters are groups of holders joined by those links:

FieldMeaning
idCluster id, also set on each member node's cluster.
wallets, membersHow many holders are in it, and their addresses, largest first.
pctShare of supply the cluster holds together.
riskhigh above 10% of supply, medium above 3%, else low.
linksWhy they're one cluster: shared_funders (each with the number of members it funded), and counts of funding_between members and token_transfers between them.
root_funderThe funder shared by the most members, else the member that funded the most others. Never an exchange or bridge.
includes_devThe token's developer is in the cluster.

What doesn’t link wallets matters as much: funding from exchanges, bridges, bots and app relayers (one signer paying the same 100+ wallets again and again), funders that paid more than 500 wallets, dust sends, and lookalike addresses used for address poisoning. Pass include=hubs or include=funders to see those funders, and edges=funding,transfers to choose which edge types come back.

Use it in your app

  1. Fetch the map with a Starter key. top=100 is a good default; each call costs 10 credits, so cache it per token for a few minutes.

  2. Draw it with any force-directed graph library. nodes and edges map directly to nodes and links (from → source, to → target).

  3. Lead with the clusters. Show each cluster’s pct and risk next to the map, and say when includes_dev is true.

  4. List hidden_infra separately. Users want to know where the rest of the supply is: in the pool, locked or burned.

// Turn a bubble map into nodes and links for a force-directed graph (d3-force, vis-network, …).
const token = "0x192b126efea71ca5e7767bc6fc53038d869fbbba"; // Rebot
const res = await fetch(`https://api.crius.sh/v1/robinhood/token/${token}/bubblemap?top=100`, {
headers: { "x-api-key": process.env.CRIUS_API_KEY },
});
const { data } = await res.json();
const nodes = data.nodes.map((n) => ({ id: n.id, radius: 4 + Math.sqrt(n.pct ?? 0) * 6, group: n.cluster ?? n.id }));
const ids = new Set(nodes.map((n) => n.id));
for (const e of data.edges) for (const a of [e.from, e.to]) if (!ids.has(a)) ids.add(a) && nodes.push({ id: a, radius: 3, group: "funder" });
const links = data.edges.map((e) => ({ source: e.from, target: e.to, kind: e.type }));
for (const c of data.clusters) console.log(`cluster ${c.id}: ${c.wallets} wallets, ${c.pct}% (${c.risk})`);
console.log(`not on the map: ${data.hidden_infra.map((h) => `${h.label ?? h.tags[0]} ${h.pct}%`).join(", ")}`);

Frequently asked questions

What is a bubble map?

A picture of a token's top holders where each holder is a bubble sized by how much it holds, and lines connect holders that are linked: one funded the other, they were funded by the same wallet, or they moved the token between them. A big group of connected bubbles is one owner spread over many wallets.

Why isn't the liquidity pool on the bubble map?

Because it isn't a holder. Pools, the Uniswap v4 PoolManager, LP lockers, hooks, burn addresses, routers, other contracts and exchanges are moved to hidden_infra with their share of supply. Everyone trades through them, so drawing them would link unrelated wallets. Add include=infra to draw them; they still never join a cluster.

Why are two wallets funded by the same exchange not in one cluster?

Exchanges, bridges, bots and app relayers fund thousands of unrelated people, so they never link wallets. A funder that paid more than 500 wallets is treated the same way. include=hubs shows those funding edges, marked hub: true, without using them for clusters.

Can I see a bubble map from the past?

Yes: pass block and the map uses holder balances at that block, for example to see who held a token at its peak.

How many holders can the map show?

top sets how many holders become nodes: 100 by default, up to 500. Infrastructure doesn't use up places, so you always get top real holders when the token has that many.

Get your free Crius API key

Every example on this page works with a free key: higher rate limits than the anonymous plan, holders, wallets and the WebSocket stream. No card needed.

  • Robinhood Chain (4663) only, from our own archive nodes
  • REST + WebSocket
  • Pay on-chain or by card