Skip to main content
Use this pattern when you render a trending / top-tokens page that previously required hundreds of REST calls (multiple leaderboards × many mints × enrichment per mint).

Problem

A typical page might:
  1. Fetch top tokens for several windows (volume + txn count at 1h, 2h, 4h, 24h).
  2. Dedupe ~300 unique mints across those lists.
  3. Call ~7 REST endpoints per mint (deploy, price changes, volume, metadata, holders, supply, stats).
That is one HTTP round trip per call — latency dominated by RTT, not query time.

Solution

One POST /api/sol/graphql request:
  • Multiple aliased topTokens roots (one per leaderboard).
  • One tokens(mints: [...]) root with only the nested fields you need.
The server runs and caches the same logic as REST; you pay one RTT from your backend or browser.

Limits

ConstraintValue
topTokens hours1–168
topTokens limit1–100
tokens mintsMax 500 unique addresses (deduped server-side)
holders per mintDefault 20, max 200

Example query

query TrendingBoard($mints: [String!]!) {
  solPrice {
    solPrice
    hasValidPrice
  }

  topVol24: topTokens(hours: 24, limit: 100, sort: VOLUME) {
    sort
    hours
    count
    data {
      mint
      symbol
      name
      totalSolVolume
      tradeCount
      uniqueTraders
    }
  }

  topTxn1h: topTokens(hours: 1, limit: 100, sort: TXNS) {
    count
    data { mint tradeCount totalSolVolume }
  }

  topTxn2h: topTokens(hours: 2, limit: 100, sort: TXNS) {
    count
    data { mint tradeCount }
  }

  topTxn4h: topTokens(hours: 4, limit: 100, sort: TXNS) {
    count
    data { mint tradeCount }
  }

  topTxn24h: topTokens(hours: 24, limit: 100, sort: TXNS) {
    count
    data { mint tradeCount }
  }

  tokens(mints: $mints) {
    mint
    deploy { name symbol platform time signer }
    priceChanges {
      currentPrice
      currentPriceUsd
      change5m { change price }
      change1h { change price }
      change24h { change price }
    }
    tradingVolume(hours: 24) {
      tradeCount
      totalSolVolume
      uniqueTraders
      buySolVolume
      sellSolVolume
    }
    metadata {
      dexPaid
      metadataSource
      onChain { name symbol uri decimals uiSupply }
      offChain { image description twitter telegram website }
    }
    holders(limit: 20) {
      count
      source
      holders { address amount isLiquidityPool }
    }
    supply { supply decimals }
    sniperBundleStats {
      sniperSignersCount
      bundleSignersCount
      sniperTotalAmount
      bundleTotalAmount
    }
    topTraders(limit: 10) {
      trader
      totalPnlUsd
      winRate
    }
  }
}

Variables

Build mints as the deduped union of every mint returned from your topTokens aliases (client-side or in your BFF):
{
  "mints": [
    "MintAddress1...",
    "MintAddress2..."
  ]
}

cURL

curl -sS -X POST "https://api.raze.bot/api/sol/graphql" \
  -H "Content-Type: application/json" \
  -H "x-api-key: sk_your_key_here" \
  -d '{
    "query": "query($mints:[String!]!){ topVol24: topTokens(hours:24,limit:5,sort:VOLUME){ count data{ mint symbol } } tokens(mints:$mints){ mint deploy{ symbol } priceChanges{ currentPrice } } }",
    "variables": { "mints": ["YOUR_MINT_HERE"] }
  }'

Field selection

tokens uses GraphQL field selection — omit expensive branches if you do not need them:
FieldTypical costREST equivalent
deploy, priceChanges, tradingVolume, sniperBundleStatsLow (analytics DB)/tokens/mint, /price-changes, /trades/volume, ?analysis=stats
metadataMedium (RPC + off-chain fetch)/tokens/metadata/{mint}
holders, supplyHigher (RPC / snapshot tiers)/tokens/holders, /tokens/supply
topTradersMedium/tokens/toptraders/{mint}

Go / other backends

Post the JSON body from your service; map the response into your structs. You do not need direct database access — the history service aggregates on the server next to the data. See also: Tokens GraphQL reference, GraphQL overview.