> ## Documentation Index
> Fetch the complete documentation index at: https://docs.codex.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Detailed Token Page

> Learn how to build a comprehensive token detail page with price, holders, safety, trades, and real-time updates

In this recipe we'll walk through building a token detail page — the kind of page your users land on after clicking a token from a discovery feed. We'll combine multiple Codex endpoints to populate every section: metadata, price, holders, top traders, safety signals, trade history, and real-time updates.

This data powers the token pages on [Defined.fi](https://www.defined.fi/tokens?utm_source=codex\&utm_medium=docs\&utm_campaign=recipes-token-dashboard):

![Token-Dashboard](https://mintcdn.com/codex-dfdf2708/yCAztF6zvVgnt5iY/images/token-dashboard.jpg?fit=max\&auto=format\&n=yCAztF6zvVgnt5iY\&q=85\&s=0b5ed134d299e77c75385ce38851d8cf)

## Step 1: Token Metadata & Safety

Start by fetching the token's core info — name, symbol, images, social links, and safety signals. This single query gives you everything for the header of your token page.

> [accordion] Token metadata with safety fields
>
> [Test this query in the Explorer →](https://docs.codex.io/explore.md)
>
> ```graphql theme={null} theme={null}
> query TokenMetadata {
>   token(
>     input: {
>       address: "TOKEN_ADDRESS"
>       networkId: 1399811149
>     }
>   ) {
>     name
>     symbol
>     decimals
>     address
>     networkId
>     isScam
>     creatorAddress
>     creator {
>       address
>       displayName
>       category
>       identityLabels
>       tokensCreatedCount
>       tokensMigratedCount
>     }
>     createdAt
>     mintable
>     freezable
>     socialLinks {
>       twitter
>       telegram
>       discord
>       website
>     }
>     top10HoldersPercent
>     info {
>       circulatingSupply
>       totalSupply
>       imageSmallUrl
>       imageLargeUrl
>       description
>     }
>     launchpad {
>       launchpadName
>       graduationPercent
>       poolAddress
>       completed
>       migrated
>       migratedAt
>       migratedPoolAddress
>     }
>   }
> }
> ```

> [!NOTE]
>
> **Token risk:** Request the `risk` field to show a verdict and warnings on your token page. See [Token Risk](https://docs.codex.io/concepts/token-risk.md). For Solana tokens, `mintable` and `freezable` return an address when the token's supply can be increased or holdings can be frozen.

> [!TIP]
>
> **Screen for suspicious-wallet concentration.** Alongside `isScam`, Codex reports how much of a token's supply sits in risky wallet cohorts. [`filterTokens`](https://docs.codex.io/api-reference/queries/filtertokens) exposes `suspiciousHeldPercentage` and `suspiciousCount` — the deduplicated union of snipers, bundlers, and insiders — plus the per-cohort `sniperHeldPercentage`, `bundlerHeldPercentage`, `insiderHeldPercentage`, and `devHeldPercentage`. These are available as result fields, filter inputs, and ranking attributes, so you can both display them and screen risky tokens out at discovery time. For launchpad tokens, the same breakdown is available inline on [`pairMetadata`](https://docs.codex.io/api-reference/queries/pairmetadata) via `walletActivity` (shown in Step 2).

> [!TIP]
>
> **Resolve the creator inline.** Alongside the raw `creatorAddress`, `EnhancedToken` exposes `creator`, a fully resolved [`Wallet`](https://docs.codex.io/api-reference/types/wallet). Select it to pull the creator's display name, identity labels, [category](https://docs.codex.io/api-reference/enums/walletcategory.md), and `tokensCreatedCount` / `tokensMigratedCount` in the same call — a useful trust signal (e.g. a serial deployer) without a follow-up query.

## Step 2: Price & Pair Data

Fetch the token's current price, volume, and liquidity from its top trading pair using `pairMetadata`. This gives you the price stats panel for your dashboard.

> [accordion] Price and volume from pairMetadata
>
> [Test this query in the Explorer →](https://docs.codex.io/explore.md)
>
> ```graphql theme={null} theme={null}
> query TokenPrice {
>   pairMetadata(
>     pairId: "PAIR_ADDRESS:1399811149"
>   ) {
>     price
>     liquidity
>     volume5m
>     volume1
>     volume4
>     volume12
>     volume24
>     priceChange5m
>     priceChange1
>     priceChange4
>     priceChange12
>     priceChange24
>     highPrice24
>     lowPrice24
>     enhancedToken0 {
>       name
>       symbol
>       isScam
>     }
>     enhancedToken1 {
>       name
>       symbol
>       isScam
>     }
>     walletActivity {
>       suspiciousCount
>       suspiciousHeldPercentage
>       sniperHeldPercentage
>       bundlerHeldPercentage
>       insiderHeldPercentage
>     }
>   }
> }
> ```

> [accordion] Finding the pair ID with listPairsWithMetadataForToken
>
> If you don't already have the pair ID, use `listPairsWithMetadataForToken` to find it. Results are not sorted by liquidity, so sort by `liquidity` yourself to find the main pair.
>
> [Test this query in the Explorer →](https://docs.codex.io/explore.md)
>
> ```graphql theme={null} theme={null}
> query FindPair {
>   listPairsWithMetadataForToken(
>     tokenAddress: "TOKEN_ADDRESS"
>     networkId: 1399811149
>     limit: 5
>   ) {
>     results {
>       pair {
>         address
>         id
>         token0
>         token1
>         fee
>         protocol
>       }
>       backingToken {
>         address
>         symbol
>       }
>       volume
>       liquidity
>     }
>   }
> }
> ```

> [!TIP]
>
> Use `enhancedToken0` and `enhancedToken1` to get enriched token metadata directly from the pair query — this saves you an extra call to `token`. The `walletActivity` block returns suspicious-wallet concentration (snipers, bundlers, insiders) and is populated for launchpad tokens — it's `null` for others. `filterTokens` returns `null` for these fields too, so for non-launchpad tokens read them from [`tokenWalletStats`](https://docs.codex.io/api-reference/queries/tokenwalletstats) instead (EVM tokens with a known creator created since October 8, 2025).

## Step 3: Holders & Top Traders

Build the holders tab. Use `holders` for the top holder list and `tokenTopTraders` for the most active traders with PnL data.

> [accordion] Top holders
>
> [Test this query in the Explorer →](https://docs.codex.io/explore.md)
>
> ```graphql theme={null} theme={null}
> query TopHolders {
>   holders(
>     input: {
>       tokenId: "TOKEN_ADDRESS:1399811149"
>     }
>   ) {
>     count
>     top10HoldersPercent
>     items {
>       address
>       balance
>       shiftedBalance
>       balanceUsd
>       tokenPriceUsd
>     }
>   }
> }
> ```

> [accordion] Top traders with PnL
>
> [Test this query in the Explorer →](https://docs.codex.io/explore.md)
>
> ```graphql theme={null} theme={null}
> query TopTraders {
>   tokenTopTraders(
>     input: {
>       tokenAddress: "TOKEN_ADDRESS"
>       networkId: 1399811149
>       tradingPeriod: WEEK
>       limit: 20
>     }
>   ) {
>     items {
>       walletAddress
>       realizedProfitUsd
>       realizedProfitPercentage
>       amountBoughtUsd
>       amountSoldUsd
>       volumeUsd
>       buys
>       sells
>       tokenBalance
>       lastTransactionAt
>     }
>   }
> }
> ```

## Step 4: Trade History

Show recent buys and sells. Use `getTokenEvents` for the initial load and paginate with `cursor` for older trades.

> [accordion] Recent trades
>
> [Test this query in the Explorer →](https://docs.codex.io/explore.md)
>
> ```graphql theme={null} theme={null}
> query RecentTrades {
>   getTokenEvents(
>     query: {
>       address: "TOKEN_ADDRESS"
>       networkId: 1399811149
>     }
>     limit: 25
>   ) {
>     cursor
>     items {
>       eventDisplayType
>       timestamp
>       maker
>       token0SwapValueUsd
>       token1SwapValueUsd
>       token0Address
>       token1Address
>       transactionHash
>       blockNumber
>       walletAge
>       walletLabels
>     }
>   }
> }
> ```

> [accordion] Filtered by buys only with minimum size
>
> [Test this query in the Explorer →](https://docs.codex.io/explore.md)
>
> ```graphql theme={null} theme={null}
> query LargeBuys {
>   getTokenEvents(
>     query: {
>       address: "TOKEN_ADDRESS"
>       networkId: 1399811149
>       eventDisplayType: [Buy]
>       priceUsdTotal: { gt: 1000 }
>     }
>     limit: 25
>   ) {
>     cursor
>     items {
>       eventDisplayType
>       timestamp
>       maker
>       token0SwapValueUsd
>       token1SwapValueUsd
>       transactionHash
>       walletLabels
>     }
>   }
> }
> ```

## Step 5: Chart Data

Fetch OHLCV bars for rendering a price chart. See the [Charts recipe](https://docs.codex.io/recipes/charts.md) for full details on rendering with TradingView.

> [accordion] OHLCV bars for chart
>
> [Test this query in the Explorer →](https://docs.codex.io/explore.md)
>
> ```graphql theme={null} theme={null}
> query TokenChart {
>   getTokenBars(
>     symbol: "TOKEN_ADDRESS:1399811149"
>     from: 1740000000
>     to: 1740604800
>     resolution: "60"
>   ) {
>     o
>     h
>     l
>     c
>     t
>     volume
>   }
> }
> ```

## Step 6: Real-Time Updates

Once the page is loaded, open subscriptions to keep it live. Here are the key subscriptions for a token dashboard:

> [accordion] Live price & volume updates
>
> Subscribe to `onPairMetadataUpdated` to keep price, volume, and liquidity current without polling.
>
> [Test this query in the Explorer →](https://docs.codex.io/explore.md)
>
> ```graphql theme={null} theme={null}
> subscription LivePrice {
>   onPairMetadataUpdated(
>     id: "PAIR_ADDRESS:1399811149"
>   ) {
>     price
>     liquidity
>     volume5m
>     volume1
>     volume24
>     priceChange5m
>     priceChange1
>     priceChange24
>   }
> }
> ```

> [accordion] Live trades
>
> Subscribe to `onTokenEventsCreated` to stream new trades as they happen.
>
> [Test this query in the Explorer →](https://docs.codex.io/explore.md)
>
> ```graphql theme={null} theme={null}
> subscription LiveTrades {
>   onTokenEventsCreated(
>     input: {
>       tokenAddress: "TOKEN_ADDRESS"
>       networkId: 1399811149
>     }
>   ) {
>     events {
>       eventDisplayType
>       timestamp
>       maker
>       token0SwapValueUsd
>       token1SwapValueUsd
>       transactionHash
>       walletLabels
>     }
>   }
> }
> ```

> [accordion] Live chart bars
>
> Subscribe to `onTokenBarsUpdated` to keep the chart updating in real time.
>
> [Test this query in the Explorer →](https://docs.codex.io/explore.md)
>
> ```graphql theme={null} theme={null}
> subscription LiveChart {
>   onTokenBarsUpdated(
>     tokenId: "TOKEN_ADDRESS:1399811149"
>   ) {
>     aggregates {
>       r1 {
>         usd {
>           o
>           h
>           l
>           c
>           t
>           volume
>         }
>       }
>     }
>   }
> }
> ```

> [accordion] Live holder updates
>
> Subscribe to `onHoldersUpdated` to keep the holders list current.
>
> [Test this query in the Explorer →](https://docs.codex.io/explore.md)
>
> ```graphql theme={null} theme={null}
> subscription LiveHolders {
>   onHoldersUpdated(
>     tokenId: "TOKEN_ADDRESS:1399811149"
>   ) {
>     holders
>     balances {
>       address
>       balance
>       shiftedBalance
>       balanceUsd
>     }
>   }
> }
> ```

> [!WARNING]
>
> Each subscription uses one connection toward your plan's limit (300 for Growth plans). A single token dashboard page with all four subscriptions above uses 4 connections. Share connections across subscriptions where possible — see [Subscriptions › Multiple Subscriptions](https://docs.codex.io/concepts/subscriptions.md#multiple-subscriptions) for guidance on how to size each connection.

## Putting It All Together

Here's the recommended data flow for a token dashboard:

**On page load (queries):**

1. `token` — metadata, safety, social links
2. `pairMetadata` — price, volume, liquidity
3. `holders` + `tokenTopTraders` — holder and trader tabs
4. `getTokenEvents` — recent trade history
5. `getTokenBars` — chart OHLCV data

**After load (subscriptions):**

1. `onPairMetadataUpdated` — live price and volume
2. `onTokenEventsCreated` — live trade feed
3. `onTokenBarsUpdated` — live chart updates
4. `onHoldersUpdated` — live holder changes

> [!TIP]
>
> **Optimizing calls:** You can reduce initial load by running queries 1-5 in parallel — they're all independent. For the subscriptions, open them on a single WebSocket connection to minimize connection usage.

### Subscriptions vs Queries Quick Reference

| Data | Query (historical) | Subscription (real-time) |
| - | - | - |
| Price & volume | `pairMetadata` | `onPairMetadataUpdated` |
| Trades | `getTokenEvents` | `onTokenEventsCreated` |
| Chart bars | `getBars` / `getTokenBars` | `onBarsUpdated` / `onTokenBarsUpdated` |
| Holders | `holders` | `onHoldersUpdated` |
| Token prices | `getTokenPrices` | `onPricesUpdated` |

Check out the related endpoints in their respective pages:

* [token](https://docs.codex.io/api-reference/queries/token.md)
* [pairMetadata](https://docs.codex.io/api-reference/queries/pairmetadata.md)
* [listPairsWithMetadataForToken](https://docs.codex.io/api-reference/queries/listpairswithmetadatafortoken.md)
* [holders](https://docs.codex.io/api-reference/queries/holders.md)
* [tokenTopTraders](https://docs.codex.io/api-reference/queries/tokentoptraders.md)
* [getTokenEvents](https://docs.codex.io/api-reference/queries/gettokenevents.md)
* [getBars](https://docs.codex.io/api-reference/queries/getbars.md) / [getTokenBars](https://docs.codex.io/api-reference/queries/gettokenbars.md)
* [onPairMetadataUpdated](https://docs.codex.io/api-reference/subscriptions/onpairmetadataupdated.md)
* [onTokenEventsCreated](https://docs.codex.io/api-reference/subscriptions/ontokeneventscreated.md)
* [onTokenBarsUpdated](https://docs.codex.io/api-reference/subscriptions/ontokenbarsupdated.md)
* [onHoldersUpdated](https://docs.codex.io/api-reference/subscriptions/onholdersupdated.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.