> ## 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.

# Balance changes

> Who holds a tokenized asset, day by day, and whether the numbers add up.

Two tables sit behind every tokenized-asset cap table, and they are read together.

`facts_asset_tokens.balance_changes_daily` records one row for each day, each deployment and each holding account whose balance moved, with that day's net change, in whole token units.

Balances themselves are not stored. The [balance functions](/docs/catalog/tokens/balances) add these rows up at query time.

## Sparse, so a balance is an accumulation

A day with no row means the balance did not move that day, not that it was zero. So a holder's balance on a date is the sum of every row at or before that date, never a lookup of that date. Ask for one day in isolation and you get that day's movement, which is rarely the question.

The [functions](/docs/catalog/tokens/balances) exist so this is not something every reader has to get right.

## Read the coverage and attribution before the numbers

One thing gates a cap table: whether a ledger summed from transfer legs can describe the deployment at all. Coverage answers that per deployment, and it answers about the mechanism rather than about activity.

So a deployment with no rows here is one of two things, and they are not the same. Either coverage refuses it, in which case it names the reason, or coverage serves it and the deployment has simply never been transferred. An asset issued but never moved has an empty cap table, which is the correct answer rather than a missing one.

The curated [functions](/docs/catalog/tokens/balances) read coverage and refuse with that reason instead of returning a figure they cannot stand behind.

## Tables

<Tabs>
  <Tab title="Balance changes">
    `facts_asset_tokens.balance_changes_daily` records one row per `(timestamp, chain_id, token_address, account_address)`.

    <table>
      <thead>
        <tr>
          <th width="200">Column</th>
          <th width="130">Type</th>
          <th>Description</th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td><code>timestamp</code></td>
          <td><code>TIMESTAMP</code></td>
          <td>Day the balance moved. The partition column.</td>
        </tr>

        <tr>
          <td><code>chain\_id</code></td>
          <td><code>STRING</code></td>
          <td>Chain the deployment sits on.</td>
        </tr>

        <tr>
          <td><code>asset\_id</code></td>
          <td><code>STRING</code></td>
          <td>Asset the deployment belongs to.</td>
        </tr>

        <tr>
          <td><code>token\_id</code></td>
          <td><code>STRING</code></td>
          <td>Key of the deployment, formatted <code>\{token\_address}-\{chain\_id}</code>.</td>
        </tr>

        <tr>
          <td><code>token\_address</code></td>
          <td><code>STRING</code></td>
          <td>Contract address of the deployment. Filter this and <code>chain\_id</code> together.</td>
        </tr>

        <tr>
          <td><code>account\_address</code></td>
          <td><code>STRING</code></td>
          <td>The chain's native holding account: a wallet on EVM chains, a token account on Solana.</td>
        </tr>

        <tr>
          <td><code>account\_owner</code></td>
          <td><code>STRING</code></td>
          <td>The holder. Equal to <code>account\_address</code> where the chain does not distinguish them, and the wallet behind the token account where it does. Group by this for a cap table. Group by <code>account\_address</code> instead and one wallet's several Solana token accounts each count as a separate holder.</td>
        </tr>

        <tr>
          <td><code>balance\_delta</code></td>
          <td><code>BIGNUMERIC</code></td>
          <td>Net balance movement that day, signed, in whole token units.</td>
        </tr>
      </tbody>
    </table>
  </Tab>
</Tabs>

## What is not here, and why

The families currently declared out, and absent from this table rather than approximated:

* **Chains without a balance arm.** Every asset on them, whatever its mechanics.
* **Assets whose balances revalue without moving.** A rebasing token grows every holder at once with no transfer to observe, so a ledger summed from transfer legs holds the value each transfer had and never revalues it.
* **Assets hand-declared out with measured evidence.** Two cases are worth knowing about generally: a chain that migrated balances between token standards without emitting the credit, and a token whose confidential transfers hide the amount from the event that would record it.

Two mechanisms are worth naming, because both are refused rather than approximated. A Solana
**scaled UI amount** multiplies a raw balance by a multiplier the mint can change, and an
**interest-bearing rate** accrues into the holder-facing amount with no transfer to observe. A
Dinari dShare revalues the same way, through a multiplier the issuer writes. In every case the
balance moves without a transfer, so a ledger summed from transfer legs cannot see it, and the
deployment is declared out until a model can convert it.

## Notes

* Filter `token_address` and `chain_id` together. They are the cluster keys; a filter on `token_id` alone reaches neither.
* `balance_delta` is `BIGNUMERIC` throughout, deliberately. Float arithmetic leaves dust where a closed position should read exactly zero, and dust counts as a holder.


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