Tokens API
Trading flow by labelled wallet group, over time
Buy/sell USD volume and wallet/transaction counts per labelled wallet cohort (developers, snipers, smart money, KOLs), bucketed over time; Solana only.
GET
/api/external/token-analysis/cohort-flow/{chain}/{mint}Chains
- Solana SOL
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/cohort-flow/SOL/<mint>?interval=1m&from=<from>&to=<to>"
| Parameter | Description |
|---|---|
intervalquery · string · required | Bucket width. A curated subset of the underlying time_frame enum — one representative width per its own max-range class (minutes/hours/day-and-up) — 1m for intraday/launch-forensics reads, 1h for a medium trend, 1D for a long one.1m1h1D |
fromquery · integer · required | Window start, Unix SECONDS. Inclusive. |
namedWalletsquery · boolean · optional | Opt in to naming some of the wallets behind each bucket, instead of only counting them. COSTS AN EXTRA UPSTREAM CALL, which is why it is off by default — leave it off if you only need the aggregates. READ THIS BEFORE USING IT: at most 10 wallets are named per bucket, across all cohorts together, so a cohort reporting 270 buying wallets in a bucket can come back with three names. This answers "name me some of them", never "name the cohort". Each point carries namedWalletsComplete saying whether the shortfall is proven, and the selection rule behind the ten is not documented — do not read the list as a ranking. |
toquery · integer · required | Window end, Unix SECONDS. Inclusive. The declared ceiling per interval is 60 days at 1m, 90 at 1h, 365 at 1D — a wider window returns 400 naming the real ceiling rather than a silently truncated series. Even within that ceiling the response can still come back truncated: true (a real, regularly observed page limit, independent of the day-range check) — split a longer read into multiple calls. |
chainpath · string · required | Solana only; every other chain returns 400. No other wired source reports trading flow bucketed by a labelled wallet cohort for a token on any chain. |
mintpath · string · required | The token mint address. |
Response fields
A JSON response. Every field is always present; null means the value could not be established, never zero.
| Field | Type | Description |
|---|---|---|
interval | string | |
cohorts | object[] | One entry per labelled wallet cohort with any trading activity in the window. OVERLAPPING BY DESIGN — a wallet tagged both dev and sniper is counted in BOTH cohorts' numbers, so never sum across entries. A cohort with zero activity across the whole window is omitted entirely, never published with an empty series. |
cohorts[].label | string | This wallet cohort's own tag name. Today exactly four are possible — dev, sniper, smart_trader, kol — a closed vocabulary confirmed against the underlying schema, not discovered by sampling. bundler and insider are real concepts elsewhere on this surface but this endpoint can never return either. |
cohorts[].points | object[] | Ascending by at. |
cohorts[].points[].at | number | |
cohorts[].points[].volumeBuyUsd | number | null | |
cohorts[].points[].volumeSellUsd | number | null | |
cohorts[].points[].walletBuyCount | integer | null | |
cohorts[].points[].walletSellCount | integer | null | |
cohorts[].points[].txBuyCount | integer | null | |
cohorts[].points[].txSellCount | integer | null | |
cohorts[].points[].namedWallets | object[] | null | Present only when namedWallets=true was requested. Wallets named in this bucket that carry this cohort's tag. AT MOST 10 PER BUCKET, counted across ALL cohorts together — and the same bucket routinely holds hundreds. Compare this list against this point's own walletBuyCount/walletSellCount: ten names beside a count of 270 is the normal case, not an error. namedWalletsComplete says whether the gap is proven. THE SELECTION RULE IS NOT DOCUMENTED and has not been measured — these are not "the largest", not "the first", and not a ranking. Treat the order as arbitrary. null means the per-wallet detail could not be read for this bucket; an empty array means nobody in this cohort was named. Different answers. |
cohorts[].points[].namedWallets[].address | string | |
cohorts[].points[].namedWallets[].volumeBuyUsd | number | null | |
cohorts[].points[].namedWallets[].volumeSellUsd | number | null | |
cohorts[].points[].namedWallets[].txBuyCount | integer | null | |
cohorts[].points[].namedWallets[].txSellCount | integer | null | |
cohorts[].points[].namedWalletsComplete | boolean | null | Present only when namedWallets=true was requested. true — the bucket came back under the upstream per-bucket ceiling, so nothing was withheld. false — PROVEN incomplete: this cohort's own walletBuyCount/walletSellCount exceeds the names given. null — the bucket sits exactly on the ceiling and the counts do not prove a shortfall, so it is undetermined. This is derived from the counts in this same response, not from any upstream "more data" flag — that flag reads false on a capped bucket and must not be trusted here. |
truncated | boolean | true when more buckets exist past what this response covers. A real, regularly observed truncation, independent of the day-range ceiling above — narrow the window or coarsen the interval and re-request. |
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