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

# spot.tokens

> The full token object, every time it changes.

Subscribe on an open stream connection. See [Connecting to streams](/streams/overview) for the connection, frames and reconnecting.

## Filters

<ParamField body="chain" type="string" required>
  The [chain slug](/concepts/chains) the tokens trade on.
</ParamField>

<ParamField body="tokens" type="string[]" required>
  1 to 100 token addresses on `chain`. For one token, you can send `token` with a single address instead.
</ParamField>

To follow tokens on several chains, open one subscription per chain.

## Update

Each update's `data` is the whole token object, sent whenever the token changes. It has the same shape as `GET /v1/tokens/{chain}/{address}`. Replace your stored copy with it.

<ResponseField name="chain" type="string" required>
  The [chain slug](/concepts/chains) the token trades on.
</ResponseField>

<ResponseField name="address" type="string" required>
  The token's address.
</ResponseField>

<ResponseField name="name" type="string" required>
  The token's name.
</ResponseField>

<ResponseField name="symbol" type="string" required>
  The token's symbol.
</ResponseField>

<ResponseField name="decimals" type="integer" required>
  The token's decimals.
</ResponseField>

<ResponseField name="supply" type="decimal string" required>
  Total supply.
</ResponseField>

<ResponseField name="creator" type="string" required>
  The creator's address.
</ResponseField>

<ResponseField name="devFunding" type="object" required>
  The creator wallet's first inbound funding.

  <Expandable title="devFunding">
    <ResponseField name="status" type="string" required>
      `unresolved` while the lookup can still resolve, or `resolved` once it has settled. The other fields are `null` in both states when no funder is known.
    </ResponseField>

    <ResponseField name="address" type="string | null">
      The funder's address.
    </ResponseField>

    <ResponseField name="sourceKind" type="string | null">
      `cex` for a known exchange, or `wallet` for another wallet.
    </ResponseField>

    <ResponseField name="sourceLabel" type="string | null">
      A display label for the funder, such as an exchange name.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="createdAt" type="integer" required>
  When the token was created, in milliseconds.
</ResponseField>

<ResponseField name="launchpad" type="string | null" required>
  The launchpad the token launched on. `null` for tokens that did not launch on one.
</ResponseField>

<ResponseField name="bondingCurvePct" type="decimal string | null" required>
  Bonding-curve completion, 0–100. `null` for tokens not on a bonding curve.
</ResponseField>

<ResponseField name="graduatedAt" type="integer | null" required>
  When the token left its launchpad, in milliseconds. `null` until then.
</ResponseField>

<ResponseField name="graduatedToPool" type="string | null" required>
  The pool the token moved to on graduation.
</ResponseField>

<ResponseField name="graduatedToDex" type="string | null" required>
  The venue that pool trades on.
</ResponseField>

<ResponseField name="dexes" type="string[]" required>
  The venues the token's top pools trade on, deepest pool first.
</ResponseField>

<ResponseField name="anchorAddress" type="string | null" required>
  The address of the quote asset in the token's deepest pool.
</ResponseField>

<ResponseField name="anchorSymbol" type="string | null" required>
  The symbol of that quote asset.
</ResponseField>

<ResponseField name="price" type="money object" required>
  The current price.
</ResponseField>

<ResponseField name="marketCap" type="money object" required>
  The current market cap.
</ResponseField>

<ResponseField name="liquidity" type="money object" required>
  The current liquidity.
</ResponseField>

<ResponseField name="ath" type="object" required>
  All-time highs.

  <Expandable title="ath">
    <ResponseField name="price" type="money object" required>
      The all-time-high price.
    </ResponseField>

    <ResponseField name="priceAt" type="integer" required>
      When that price was set, in milliseconds.
    </ResponseField>

    <ResponseField name="marketCap" type="money object" required>
      The all-time-high market cap.
    </ResponseField>

    <ResponseField name="marketCapAt" type="integer" required>
      When that market cap was set, in milliseconds.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="stats" type="object" required>
  Trade activity over trailing windows that end now, keyed `5m`, `30m`, `1h`, `6h` and `24h`.

  <Expandable title="stats window">
    <ResponseField name="priceChangePct" type="decimal string" required>
      Price change over the window, as a signed percentage.
    </ResponseField>

    <ResponseField name="volume" type="money object" required>
      Trade volume over the window.
    </ResponseField>

    <ResponseField name="buyCount" type="integer" required>
      Buy trades over the window.
    </ResponseField>

    <ResponseField name="sellCount" type="integer" required>
      Sell trades over the window.
    </ResponseField>

    <ResponseField name="buyVolume" type="money object" required>
      Buy-side volume over the window.
    </ResponseField>

    <ResponseField name="sellVolume" type="money object" required>
      Sell-side volume over the window.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="totals" type="object" required>
  All-time totals.

  <Expandable title="totals">
    <ResponseField name="volume" type="money object" required>
      All-time trade volume.
    </ResponseField>

    <ResponseField name="fees" type="object" required>
      Fee totals by kind: `transaction`, `validator`, `platform` and `dex`, each a money object. The kinds are measured on different bases, so do not add them together.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="holders" type="object" required>
  Holder concentration and wallet risk groups. Each `Pct` field is the share of supply a group holds now, 0–100. Each `Count` field is the number of wallets that ever carried the group's flag on this token, so it never decreases.

  <Expandable title="holders">
    <ResponseField name="count" type="integer" required>
      Current holders.
    </ResponseField>

    <ResponseField name="top10Pct" type="decimal string" required>
      Share held by the 10 largest holders. It can read above 100 when supply data drifts.
    </ResponseField>

    <ResponseField name="devPct" type="decimal string" required>
      Share held by the creator.
    </ResponseField>

    <ResponseField name="sniperPct, sniperCount" type="decimal string, integer" required>
      Share held by, and count of, wallets that bought within two blocks of the token's first pool (snipers).
    </ResponseField>

    <ResponseField name="bundlerPct, bundlerCount" type="decimal string, integer" required>
      Share held by, and count of, wallets that made the fourth or later buy in a single block (bundlers).
    </ResponseField>

    <ResponseField name="insiderPct, insiderCount" type="decimal string, integer" required>
      Share held by, and count of, wallets that bought within three blocks of the token's first pool (insiders). These overlap with snipers.
    </ResponseField>

    <ResponseField name="freshWalletPct, freshWalletCount" type="decimal string, integer" required>
      Share held by, and count of, wallets funded less than seven days before they traded.
    </ResponseField>

    <ResponseField name="proTraderPct, proTraderCount" type="decimal string, integer" required>
      Share held by, and count of, wallets that have traded through a known trading terminal.
    </ResponseField>

    <ResponseField name="fomoPct, fomoCount" type="decimal string, integer" required>
      Share held by, and count of, wallets that have traded through the fomo.family terminal.
    </ResponseField>

    <ResponseField name="phishingPct" type="decimal string" required>
      Share held by wallets a security source labels malicious.
    </ResponseField>

    <ResponseField name="phishingCount" type="integer" required>
      Wallets that ever traded the token while labelled malicious.
    </ResponseField>

    <ResponseField name="fundedByCexPct" type="decimal string" required>
      Share of current holders that a known exchange funded, 0–100.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="security" type="object" required>
  Contract security signals.

  <Expandable title="security">
    <ResponseField name="mintDisabled" type="boolean" required>
      `true` when no more of the token can be minted: the mint authority is revoked on Solana, or the contract holds no mint power on EVM chains.
    </ResponseField>

    <ResponseField name="transferBlockable" type="boolean" required>
      `true` when transfers can be blocked: by a freeze authority on Solana, or by a blacklist or pause on EVM chains.
    </ResponseField>

    <ResponseField name="lpBurntPct" type="decimal string | null" required>
      Share of liquidity burnt or locked, 0–100. `null` until observed.
    </ResponseField>

    <ResponseField name="transferFeeBps" type="integer | null" required>
      The contract's transfer fee in basis points; `250` is 2.50%. `null` when the contract has not been scored.
    </ResponseField>

    <ResponseField name="rugPct" type="decimal string" required>
      Not yet populated; always `"0"`.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="metadata" type="object" required>
  Project links and description. Every field except `twitterReuseCount` can be `null`.

  <Expandable title="metadata">
    <ResponseField name="description" type="string | null" required />

    <ResponseField name="website" type="string | null" required />

    <ResponseField name="twitter" type="string | null" required />

    <ResponseField name="telegram" type="string | null" required />

    <ResponseField name="discord" type="string | null" required />

    <ResponseField name="twitterReuseCount" type="integer" required>
      Not yet populated; always `0`.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="platforms" type="object[]">
  External listings. Left out when empty. Today the only listing is a paid DexScreener profile: `{"platform": "dexScreener", "isPaid": true, "paidAt": 1789000000000}`. `paidAt` can be `null`.
</ResponseField>

<ResponseField name="annotations" type="object[]">
  Flags the launch carried, each tagged by `kind`, such as `{"kind": "mayhem_mode"}`. Left out when empty. New kinds can appear.
</ResponseField>

<ResponseField name="updatedAt" type="integer" required>
  When the token object last changed, in milliseconds.
</ResponseField>

## Errors

| Code | When |
| - | - |
| `VALIDATION_ERROR` | `chain` missing; no address, or more than 100; an address in the wrong format for the chain; an unknown filter field |
| `UNSUPPORTED_CHAIN` | `chain` is not a supported slug |

<RequestExample>
  ```json Subscribe theme={null}
  {
    "action": "subscribe",
    "channel": "spot.tokens",
    "filters": {
      "chain": "solana",
      "tokens": ["DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"]
    }
  }
  ```
</RequestExample>

<ResponseExample>
  ```json Update (shortened) theme={null}
  {
    "type": "update",
    "channel": "spot.tokens",
    "subscriptionId": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
    "data": {
      "chain": "solana",
      "address": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
      "name": "Bonk",
      "symbol": "Bonk",
      "decimals": 5,
      "price": { "native": "0.000000121", "usd": "0.0000216" },
      "marketCap": { "native": "10741962.1", "usd": "1917440000" },
      "liquidity": { "native": "61230.4", "usd": "10929626" },
      "updatedAt": 1789632012345
    }
  }
  ```
</ResponseExample>


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