# Find holders who held through a run (holder cohorts)

> Find wallets that bought a Robinhood Chain token early and held through the run, with hold time, entry market cap, sells and PnL per wallet. Real example.

Source: https://docs.crius.sh/guides/find-diamond-hand-holders/ · Updated 2026-10-28

Short answer

Call `GET /v1/robinhood/token/{address}/holders/cohort?from=…&to=…` (Starter plan, 10 credits). Set a size threshold (`min_usd`, `min_balance` or `min_pct`), `continuous=true` to require holding for the whole window and `reset_on` to choose what breaks it. Each wallet comes back with `hold_time_s`, `entry_mcap_usd`, `sells_in_window`, `resets` and `pnl_usd`.

[GET `/token/{address}/holders/cohort`](https://docs.crius.sh/reference/holders/holder-cohort/) [GET `/token/{address}/holders/snapshot`](https://docs.crius.sh/reference/holders/holder-snapshot/) [GET `/token/{address}/traders`](https://docs.crius.sh/reference/holders/top-traders/)

A holder cohort is the set of wallets that held a token through a window, for example from the moment the market cap crossed $50k until now. Crius replays every balance change in the window and, for each wallet, tells you when it started holding, how long it held, the market cap when it got in, whether it sold, and its PnL. It’s how you find “diamond hands” (wallets that bought early and didn’t sell into the pump), and the opposite: who took profit and when.

## Get the cohort in one call

Example [Starter plan · 10 credits](https://docs.crius.sh/reference/holders/holder-cohort/)

### Who held CHARGE from $50k market cap to now

Charge AI (0x7b8892cea949bc60d494681d1bc3ea96071ab0b8) first crossed $50k market cap two hours after launch. Which wallets held from that moment until now?

GET/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/holders/cohort?from=mcap:50000&to=now&limit=5

 

**cURL**

```bash
curl "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/holders/cohort?from=mcap:50000&to=now&limit=5" \
  -H "x-api-key: $CRIUS_API_KEY"
```

**JavaScript**

```js
const res = await fetch("https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/holders/cohort?from=mcap:50000&to=now&limit=5", {
  headers: { "x-api-key": process.env.CRIUS_API_KEY },
});
const { data, meta } = await res.json();
```

**Python**

```python
import os, requests

r = requests.get(
    "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/holders/cohort?from=mcap:50000&to=now&limit=5",
    headers={"x-api-key": os.environ["CRIUS_API_KEY"]},
)
body = r.json()
print(body["data"])
```

**Real response 200 Captured Oct 28, 2026 · 125 lines (arrays trimmed)**

```json
{
  "data": {
    "criteria": {
      "continuous": false,
      "exclude": [],
      "min_balance": null,
      "min_hold_s": null,
      "min_pct": null,
      "min_usd": null,
      "reset_on": "sell"
    },
    "holders": [
      {
        "address": "0xfee5fee50000062bd986e86502c5acdf989067a0",
        "balance_at_from": 5758.56,
        "balance_now": 47534.9,
        "entry_mcap_usd": 51583.8,
        "hold_time_s": 1234652,
        "min_balance_in_window": 5758.56,
        "pnl_usd": null,
        "qualified_since_block": 88461359,
        "qualified_since_ts": 1791990426900,
        "reset_history": [],
        "resets": 0,
        "sells_in_window": 0,
        "tags": [
          "contract"
        ],
        "value_usd_now": 0.183244
      },
      {
        "address": "0xb823bd7738b61547221f54bb3410b94326aae1eb",
        "balance_at_from": 497321,
        "balance_now": 497321,
        "entry_mcap_usd": 51583.8,
        "hold_time_s": 1234652,
        "min_balance_in_window": 497321,
        "pnl_usd": -22.1233,
        "qualified_since_block": 88461359,
        "qualified_since_ts": 1791990426900,
        "reset_history": [],
        "resets": 0,
        "sells_in_window": 0,
        "tags": [],
        "value_usd_now": 1.91714
      },
      {
        "address": "0x38c16e94e79383a5906449fc84477c1a7b19b613",
        "balance_at_from": 8344519,
        "balance_now": 0.00000000214748,
        "entry_mcap_usd": 51583.8,
        "hold_time_s": 1234652,
        "min_balance_in_window": 0.00000000214748,
        "pnl_usd": -298.108,
        "qualified_since_block": 88461359,
        "qualified_since_ts": 1791990426900,
        "reset_history": [],
        "resets": 0,
        "sells_in_window": 0,
        "tags": [],
        "value_usd_now": 0.00000000000000827841
      },
      {
        "address": "0x8e56f6476d1361cdc6e75798c83354e70d033f23",
        "balance_at_from": 57.0322,
        "balance_now": 57.0322,
        "entry_mcap_usd": 51583.8,
        "hold_time_s": 1234652,
        "min_balance_in_window": 57.0322,
        "pnl_usd": -0.00219735,
        "qualified_since_block": 88461359,
        "qualified_since_ts": 1791990426900,
        "reset_history": [],
        "resets": 0,
        "sells_in_window": 0,
        "tags": [
          "smart_account"
        ],
        "value_usd_now": 0.000219856
      },
      {
        "address": "0xfd2a475d7ce02ec077867d72177063b5c2ab01b6",
        "balance_at_from": 429.912,
        "balance_now": 429.912,
        "entry_mcap_usd": 51583.8,
        "hold_time_s": 1234652,
        "min_balance_in_window": 429.912,
        "pnl_usd": -0.396922,
        "qualified_since_block": 88461359,
        "qualified_since_ts": 1791990426900,
        "reset_history": [],
        "resets": 0,
        "sells_in_window": 0,
        "tags": [],
        "value_usd_now": 0.00165728
      }
    ],
    "never_reached_threshold": 0,
    "qualified": 224,
    "reset_out": 942,
    "started_qualified": 229,
    "window": {
      "from": {
        "at": "mcap:50000",
        "block": 88461359,
        "ts": 1791990426900
      },
      "to": {
        "at": "now",
        "block": 100406815,
        "ts": 1793225079000
      }
    }
  },
  "meta": {
    "block": 100406816,
    "block_age_ms": 1088,
    "block_ts": 1793225079000,
    "chain": "robinhood",
    "finalized_block": 100397649,
    "lag_ms": 86,
    "next_cursor": "5",
    "safe_block": 100401329
  }
}
```

What this tells you

-   `window.from` resolved `mcap:50000` to block 88461359 at `ts: 1791990426900` (2026-10-14 15:07 UTC); `window.to` is `now`, block 100406815.
-   `started_qualified: 229` wallets held at the $50k crossing, `qualified: 224` qualify at the end of the window, and `reset_out: 942` held at some point in the window but no longer qualify.
-   The five listed wallets all have `qualified_since_block: 88461359`, `resets: 0` and `sells_in_window: 0`: they held from the crossing to the end, `hold_time_s: 1234652` (about 14.3 days). `entry_mcap_usd: 51583.8` is the market cap at that block’s price.
-   `0xb823bd7738b61547221f54bb3410b94326aae1eb` never touched its position (`balance_at_from` and `balance_now` both 497321) and sits at `pnl_usd: -22.1233`: holding through the run doesn’t mean profit when the token later fell.
-   `0x38c16e94e79383a5906449fc84477c1a7b19b613` went from 8,344,519 tokens to `balance_now: 0.00000000214748` with `sells_in_window: 0`. It moved its tokens out by transfer, which the default `reset_on: "sell"` doesn’t count, and with no threshold (`criteria.min_usd: null`) a dust balance still qualifies. A real query should set `min_usd`.
-   `0xfee5fee50000062bd986e86502c5acdf989067a0` is tagged `contract` and has `pnl_usd: null`: it never bought or sold the token on a DEX, so there is no cost to measure against.

[Holder cohort reference](https://docs.crius.sh/reference/holders/holder-cohort/) [Data looks wrong? Report it](mailto:support@crius.sh?subject=Wrong%20data%20in%20docs%20example%3A%20Who%20held%20CHARGE%20from%20%2450k%20market%20cap%20to%20now&body=Page%3A%20https%3A%2F%2Fdocs.crius.sh%2Fguides%2Ffind-diamond-hand-holders%2F%23charge-cohort%0ARequest%3A%20GET%20%2Fv1%2Frobinhood%2Ftoken%2F0x7b8892cea949bc60d494681d1bc3ea96071ab0b8%2Fholders%2Fcohort%3Ffrom%3Dmcap%3A50000%26to%3Dnow%26limit%3D5%0A%0AWhat's%20wrong%20or%20missing%3F%0A%0A)

## How a wallet qualifies

A wallet **qualifies** while its balance is above your threshold. Choose one:

-   `min_usd`: the balance’s value at each block’s price, for example `min_usd=50`.
-   `min_balance`: a token amount.
-   `min_pct`: a share of supply.

Without any of them, any non-zero balance qualifies, as in the example.

A **reset** breaks a wallet’s holding streak. `reset_on` decides what counts:

| `reset_on` | A wallet resets when |
| --- | --- |
| `sell` (default) | it sells on a DEX or launchpad, or drops below the threshold |
| `any_decrease` | its balance goes down for any reason (sell or transfer out), or it drops below the threshold |
| `below_threshold` | only when it drops below the threshold |
| `none` | only when its balance reaches zero |

After a reset, a wallet that still qualifies starts a new streak (its `qualified_since_block` moves to the reset, and `reset_history` records it). With `continuous=true`, any reset, or not qualifying at `from`, removes it from the result and counts it in `reset_out`.

Other filters: `min_hold_s` (a minimum hold time), `entered_before` (a point: only wallets that first qualified before it), `exclude` (`infra`, `dev`, `snipers`) and `sort` (`hold_time`, the default, longest first; `balance`; `entry_mcap`). `from` and `to` take the same points as snapshots: `block:N`, `ts:MS`, `mcap:USD`, or the labels `launch`, `graduation`, `ath`, `now` (see [historical holders](https://docs.crius.sh/guides/get-historical-holders/#choose-the-point-in-time)).

## What the fields mean

| Field | Meaning |
| --- | --- |
| `qualified` | Wallets that qualify at the end of the window (with `continuous=true`: held the whole window). |
| `started_qualified` | Wallets that qualified at `from`. |
| `reset_out` | Wallets that qualified at some point in the window but not at the end, or broke continuity. |
| `never_reached_threshold` | Wallets that held in the window but never above the threshold. |
| `holders[].qualified_since_block`, `qualified_since_ts` | Start of the wallet's current streak. |
| `holders[].hold_time_s` | Seconds from the streak's start to `to`. |
| `holders[].entry_mcap_usd` | Market cap at the streak's start. |
| `holders[].balance_at_from`, `balance_now`, `min_balance_in_window` | Balance at `from`, at `to`, and the lowest in between. |
| `holders[].sells_in_window`, `resets`, `reset_history` | Sells in the window, the number of resets and when they happened (block, time, reason, balance after). |
| `holders[].value_usd_now`, `pnl_usd` | Value at `to`, and sells plus current value minus buys. `null` when the wallet never traded the token. |
| `criteria` | The definition used, echoed back. |

## Use it in your app

1.  **Define a diamond hand for your users.** A typical one: at least $50 (`min_usd=50`), held since a point (`from=mcap:10000`), never sold (`continuous=true&reset_on=sell`), not the dev or a sniper (`exclude=infra,dev,snipers`).
    
2.  **Show the evidence.** `entry_mcap_usd` and `hold_time_s` are what readers trust: “in since a $10k market cap, held 14 days”. Add `pnl_usd` when it’s known.
    
3.  **Use the counters as a conviction score.** `qualified` against `started_qualified` says how many early holders stayed. In the example, more wallets lost qualification during the window (942) than held at its start (229).
    
4.  **Get a Starter key.** The cohort endpoint needs the Starter plan and costs 10 credits per call; cache results per window, since a closed window never changes.
    

```js
// Wallets that held at least $50 of CHARGE from a $10k market cap to now, without selling.
const token = "0x7b8892cea949bc60d494681d1bc3ea96071ab0b8";
const q = new URLSearchParams({
  from: "mcap:10000", to: "now", min_usd: "50",
  continuous: "true", reset_on: "sell", exclude: "infra,dev,snipers", limit: "50",
});
const res = await fetch(`https://api.crius.sh/v1/robinhood/token/${token}/holders/cohort?${q}`, {
  headers: { "x-api-key": process.env.CRIUS_API_KEY },
});
const { data } = await res.json();

console.log(`${data.qualified} of ${data.started_qualified} early holders never sold`);
for (const h of data.holders) {
  const days = (h.hold_time_s / 86400).toFixed(1);
  console.log(h.address, `in at $${h.entry_mcap_usd} mcap`, `${days} d`, `PnL $${h.pnl_usd ?? "?"}`);
}
```

Big tokens and long windows

The cohort replays every transfer up to `to`. Tokens with more than 2M transfers, or a window with more than 2M balance changes, return `400 window_too_large`: narrow the window.

## Frequently asked questions

**How do I find diamond-hand holders of a token?**

Ask for the cohort over the run with a strict definition: `/holders/cohort?from=mcap:10000&to=now&min_usd=50&continuous=true&reset_on=sell&exclude=infra`. Only wallets that held at least $50 at the start and never sold or dropped below $50 until now come back, sorted by how long they held.

**What is the difference between \`continuous=true\` and the default?**

By default a wallet qualifies if it meets the threshold at the end of the window, even if it joined late or sold and bought back (its hold time then starts at its last reset). With `continuous=true` it must already qualify at `from` and never reset until `to`; everyone else is counted in `reset_out`.

**Does a transfer to another wallet count as selling?**

Not with the default `reset_on=sell`: only sells on a DEX or launchpad reset a holder. Use `reset_on=any_decrease` to also break on transfers out, or a `min_usd` threshold so a wallet that moved its tokens away drops out (`below_threshold`).

**How do I find early buyers who are still holding?**

Use `entered_before`: `from=launch&to=now&entered_before=mcap:20000` keeps only wallets that first qualified before the market cap crossed $20k. Add `exclude=snipers,dev` to leave out the launch snipers and the creator.

**Which plan does the cohort endpoint need?**

The Starter plan or higher, 10 credits per call. See [Plans & limits](https://docs.crius.sh/plans-and-limits/).

## Related

[Guide **Historical holders** Get a Robinhood Chain token's holders at any past block, time, market cap or launch stage, valued at that moment's price, with cost basis per holder. Read](https://docs.crius.sh/guides/get-historical-holders/) [Guide **Top traders & PnL** Rank the traders of any Robinhood Chain token by PnL, volume, buys or ROI, with wallet tags, gas and hold time. A real example with the PnL math explained. Read](https://docs.crius.sh/guides/get-top-traders-pnl/) [Guide **Token holders** Robinhood Chain token holders API: get any token's top holders in one call, with balance, share of supply, USD value, labels, holder count and top-10 share. Read](https://docs.crius.sh/guides/get-token-holders/) [Concept **Holder classes** How the Crius API tells real holders from pools, the PoolManager, lockers and contracts, and how it tags devs, snipers, whales and smart accounts. Read](https://docs.crius.sh/concepts/holder-classes/) [API reference **Holder cohort API** Wallets that held through a window. A holder qualifies when it stayed above a size threshold (min\_usd, min\_balance or min\_pct); with continuous=true it must hold for the whole window, and reset\_on dec Read](https://docs.crius.sh/reference/holders/holder-cohort/)
