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

> ## Agent Instructions
> To query the Token Terminal data catalog, read https://tokenterminal.com/docs/catalog/agents-manual.md first. It is the whole catalog as one page: table naming grammar, key columns, partition and cluster rules, units, additivity, and the tables that are documented but not served yet.
> Never query a catalog table on a time bound alone. Also filter its cluster key, which you read from INFORMATION_SCHEMA.COLUMNS; an empty result means the object is a view, whose pruning contract is on its page. Compute is billed to the caller's own Google Cloud project.

# Token transfers

> Every fungible token transfer, joined to the entity that issued it.

One row per fungible token movement in `facts_tokens.transfers`: a transfer, a mint or a burn, on every chain we decode. `amount_raw` is the amount in the token's smallest unit, so divide by `10^decimals` from [`dimensions.tokens`](/docs/catalog/tokens/registry) to read whole tokens.

## Coverage

Every chain we cover token transfers on.

<div class="tt-roster">
  <div class="tt-chips">
    <code>acala</code>
    <code>alephzeroevm</code>
    <code>algorand</code>
    <code>aptos</code>
    <code>arbitrum</code>
    <code>astar</code>
    <code>avalanche</code>
    <code>base</code>
    <code>berachain</code>
    <code>blast</code>
    <code>bob</code>
    <code>bobanetwork</code>
    <code>bsc</code>
    <code>cardano</code>
    <code>celestia</code>
    <code>celo</code>
    <code>centrifuge</code>
    <code>chainflip</code>
    <code>cosmoshub</code>
    <code>dydx</code>
    <code>ethereum</code>
    <code>fantom</code>
    <code>flow</code>
    <code>flowevm</code>
    <code>fraxtal</code>
    <code>gnosis</code>
    <code>gravityalpha</code>
    <code>hedera</code>
    <code>hydradx</code>
    <code>hydradxevm</code>
    <code>hyperevm</code>
    <code>immutablezkevm</code>
    <code>injective</code>
    <code>injectiveevm</code>
    <code>ink</code>
    <code>interlay</code>
    <code>iotex</code>
    <code>katananetwork</code>
    <code>linea</code>
    <code>manta</code>
    <code>mantaatlantic</code>
    <code>mantra</code>
    <code>mantrachain</code>
    <code>mantraevm</code>
    <code>megaeth</code>
    <code>monad</code>
    <code>moonbeam</code>
    <code>movement</code>
    <code>near</code>
    <code>neuroweb</code>
    <code>noble</code>
    <code>opbnb</code>
    <code>optimism</code>
    <code>osmosis</code>
    <code>peaq</code>
    <code>phala</code>
    <code>plasma</code>
    <code>polimec</code>
    <code>polkadex</code>
    <code>polkadotassethub</code>
    <code>polygon</code>
    <code>ripple</code>
    <code>robinhoodchain</code>
    <code>ronin</code>
    <code>rootstock</code>
    <code>scroll</code>
    <code>sei</code>
    <code>seievm</code>
    <code>solana</code>
    <code>sonic</code>
    <code>stacks</code>
    <code>starknet</code>
    <code>stellar</code>
    <code>sui</code>
    <code>tempo</code>
    <code>ton</code>
    <code>tron</code>
    <code>unichain</code>
    <code>viction</code>
    <code>worldchain</code>
    <code>xai</code>
    <code>xdc</code>
    <code>xlayer</code>
    <code>zksyncera</code>
  </div>
</div>

## Columns

<table>
  <thead>
    <tr>
      <th width="230">Column</th>
      <th width="120">Type</th>
      <th>Description</th>
    </tr>
  </thead>

  <tbody>
    <tr><td><code>partition\_key</code></td><td>TIMESTAMP</td><td>The month the row belongs to. The table is partitioned on it, so a date filter is cheapest when it names this alongside <code>block\_timestamp</code>.</td></tr>
    <tr><td><code>block\_timestamp</code></td><td>TIMESTAMP</td><td>When the block was produced.</td></tr>
    <tr><td><code>block\_number</code></td><td>INT64</td><td>Block height, or the slot on Solana.</td></tr>
    <tr><td><code>transaction\_hash</code></td><td>STRING</td><td>Transaction the movement belongs to. Null on <code>hydradx</code>, where a transfer can be emitted by a block hook instead of by a transaction.</td></tr>
    <tr><td><code>transaction\_index</code></td><td>INT64</td><td>Position of the transaction in its block. Solana only.</td></tr>
    <tr><td><code>outer\_event\_index</code></td><td>INT64</td><td>Enclosing instruction position on Solana. Null on the log-shaped chains, which have one nesting level, and null on Solana wherever the instruction is top level and has nothing enclosing it.</td></tr>
    <tr><td><code>event\_index</code></td><td>INT64</td><td>Position within the transaction: the log index, or the instruction index on Solana.</td></tr>
    <tr><td><code>chain\_id</code></td><td>STRING</td><td>Chain the movement happened on.</td></tr>
    <tr><td><code>token\_type</code></td><td>STRING</td><td>Token standard: <code>erc20</code>, <code>spl</code> or <code>trc20</code>.</td></tr>
    <tr><td><code>token\_id</code></td><td>STRING</td><td>Join key to <a href="/docs/catalog/tokens/registry"><code>dimensions.tokens</code></a>.</td></tr>
    <tr><td><code>token\_address</code></td><td>STRING</td><td>The token. Filter on this. Null on the Solana transfers whose token account the upstream decode could not resolve, which leaves <code>token\_id</code> null on the same rows.</td></tr>
    <tr><td><code>event\_type</code></td><td>STRING</td><td><code>transfer</code>, <code>mint</code> or <code>burn</code>.</td></tr>
    <tr><td><code>from\_address</code></td><td>STRING</td><td>Account debited. Null on a mint.</td></tr>
    <tr><td><code>to\_address</code></td><td>STRING</td><td>Account credited. Null on a burn.</td></tr>
    <tr><td><code>to\_owner</code></td><td>STRING</td><td>Holder behind <code>to\_address</code>. Solana transfers only: null on exactly the rows where <code>token\_address</code> is, and always null on mints and burns.</td></tr>
    <tr><td><code>authority\_address</code></td><td>STRING</td><td>Account that authorised the instruction. Solana only.</td></tr>
    <tr><td><code>transaction\_signer</code></td><td>STRING</td><td>Signer of the enclosing transaction. Solana only.</td></tr>
    <tr><td><code>executing\_account</code></td><td>STRING</td><td>Program that executed the instruction. Solana only.</td></tr>
    <tr><td><code>amount\_raw</code></td><td>STRING</td><td>Amount in the token's smallest unit, as a decimal string, because a uint256 exceeds every BigQuery numeric type. Divide by <code>10^decimals</code>.</td></tr>
    <tr><td><code>surrogate\_key</code></td><td>BYTES</td><td>Row identity, a 128-bit hash of the columns that define the grain. Stable across rebuilds; compare it with <code>from\_hex</code>.</td></tr>
  </tbody>
</table>

## Sample queries

<Warning>
  This table is large and split by month on `partition_key`. Bound `block_timestamp` and filter `chain_id` on every query, or you read the whole table and the whole table is billed to you.
</Warning>

<Tabs>
  <Tab title="One asset, every deployment">
    `dimensions.asset_tokens` turns one asset into its deployments, and `dimensions.tokens` has the decimals that turn `amount_raw` into whole tokens.

    ```sql theme={null}
    select
        transfers.block_timestamp,
        deployments.chain_id,
        transfers.from_address,
        transfers.to_address,
        cast(transfers.amount_raw as bignumeric) / pow(10, tokens.decimals) as amount
    from `facts_tokens.transfers` as transfers
    join `dimensions.asset_tokens` as deployments
        using (token_id)
    join `dimensions.tokens` as tokens
        on tokens.token_id = transfers.token_id
    where deployments.asset_id = 'usdc'
      and transfers.block_timestamp >= timestamp('2026-08-20')
      and transfers.block_timestamp < timestamp('2026-08-21')
    limit 100
    ```
  </Tab>

  <Tab title="Daily volume in USD">
    The fact has token amounts, so USD comes from a join to `metrics_tokens.price_daily` on `token_id` and the day the transfer falls in.

    ```sql theme={null}
    select
        timestamp_trunc(transfers.block_timestamp, day) as day,
        round(sum(cast(transfers.amount_raw as bignumeric) / pow(10, tokens.decimals) * prices.price)) as volume_usd
    from `facts_tokens.transfers` as transfers
    join `dimensions.tokens` as tokens
        using (token_id)
    join `dimensions.asset_tokens` as deployments
        on deployments.token_id = transfers.token_id
    join `metrics_tokens.price_daily` as prices
        on prices.token_id = transfers.token_id
        and prices.timestamp = timestamp_trunc(transfers.block_timestamp, day)
    where deployments.asset_id = 'usdc'
      and transfers.block_timestamp >= timestamp('2026-08-01')
      and transfers.block_timestamp < timestamp('2026-08-08')
    group by day
    order by day
    ```
  </Tab>

  <Tab title="Counterparties of an account">
    `from_address` and `chain_id` together identify the sender, because the same address on two chains is two accounts.

    ```sql theme={null}
    select
        transfers.to_address,
        tokens.symbol,
        count(*) as transfer_count
    from `facts_tokens.transfers` as transfers
    join `dimensions.tokens` as tokens
        using (token_id)
    where transfers.from_address = '0x28c6c06298d514db089934071355e5743bf21d60'
      and transfers.chain_id = 'ethereum'
      and transfers.block_timestamp >= timestamp('2026-08-01')
      and transfers.block_timestamp < timestamp('2026-08-08')
    group by transfers.to_address, tokens.symbol
    order by transfer_count desc
    limit 25
    ```
  </Tab>
</Tabs>
