Tokens and holders
Token pages for ERC-20 tokens on Ethereum (eip155:1), Monad (eip155:143) and Arc (eip155:5042): what a token is, who holds it, its largest recent transfers, how its holders connect, and its price. A token in a path is a 0x address of 40 hex digits in any case, which Sona lowercases. An address that is not an ERC-20 token answers 404 not_found. An address is a token when it answers both decimals() and totalSupply().
Search
Find a token by symbol, name or full address. q is 2 to 64 characters. The route is not chain-scoped, costs 0 credits and still counts toward the rate limit.
curl -s "https://api.sonaintel.com/v1/tokens/search?q=usdc"A token matches when its symbol starts with q, then when its name starts with q, then when its symbol contains it, then when its name does. Tokens on a curated list have verified: true and come first, so a token that copies the name of a real one never ranks before it. Being on a list only says someone put the address there. It is not an endorsement. The native coin is not a token and is never listed.
Token info
The head of a token page.
curl -s "https://api.sonaintel.com/v1/chains/eip155:143/tokens/0x754704Bc059F8C67012fEd69BC8A327a5aafb603"| Field | Meaning |
|---|---|
name, symbol, decimals, total_supply | From the contract. name and symbol are null when the contract does not answer them. |
price_usd | Current price, null when none is known |
fdv_usd | total_supply times price_usd, null without a price |
market_cap_usd | The circulating market cap a data provider reports, null when none |
holder_count, top10_share | Holders and the share held by the 10 largest |
logo_url | An https URL, or null |
sources, coverage | The sources that answered and the limits that apply |
Providers count a token's supply on every chain. For a bridged token such as USDC, market_cap_usd is above this chain's fdv_usd, and coverage holds token_market_cap_multichain. When a provider fails the answer still arrives, with the fields it feeds set to null and token_source_unavailable in coverage.
Holders
The holder table, largest first. limit is 1 to 100 (default 25). Pass next_cursor back as cursor for the next page. It is null on the last page.
curl -s "https://api.sonaintel.com/v1/chains/eip155:143/tokens/0x754704Bc059F8C67012fEd69BC8A327a5aafb603/holders?limit=5"Each item has the holder address, its balance and its share of the total supply.
| Chain | Source | Notes |
|---|---|---|
| Ethereum | A provider ranking, source names it. coverage has token_holders_ranked_by_provider. | is_contract and label (a name tag or contract name) are filled. index is null. |
| Monad and Arc | Sona's own index of the token's transfers, source: sona_index | is_contract and label are null |
Monad and Arc index
The first request for a Monad or Arc token starts building its index. The answer is 200 with what is indexed so far, and index.state shows the progress.
index.state | Meaning |
|---|---|
queued, indexing | Partial list with token_index_partial in coverage. Poll again. |
ready | Complete, then followed to within about a minute of the chain head |
unavailable | The index cannot take the token and the list is empty |
In activity mode (token_holders_from_activity in coverage) the list holds the addresses that moved the token since index.start_block, because a full history of a busy token is out of reach.
Transfers
The largest Transfer events in a recent window, largest first, then newest. A mint has the zero address as from and a burn as to. window gives the first and last block with their times. limit is 1 to 100, default 25.
curl -s "https://api.sonaintel.com/v1/chains/eip155:143/tokens/0x754704Bc059F8C67012fEd69BC8A327a5aafb603/transfers?limit=5"| Chain | Window |
|---|---|
| Ethereum | The last 7,200 blocks, about a day. Shorter for a busy token, with token_transfer_window_cut in coverage. When the data source's quota is spent the answer is 503 upstream_unavailable and retry_after_s says when to retry. |
| Monad and Arc | At most the last 7 days, the largest transfers of each UTC day from Sona's index. window is null until the index has read a block. |
Holder map
The largest holders as a map: nodes, the links between them, and the clusters the links form. limit is 50 to 250, default 100. Each limit is its own map with its own links.
curl -s "https://api.sonaintel.com/v1/chains/eip155:1/tokens/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984/holder-map?limit=50"| Part | Meaning |
|---|---|
nodes | The holders, largest first, each with balance, share, label, kind and cluster |
links | Pairs of nodes that sent each other the token, with a status |
clusters | Groups of nodes that links connect |
On Ethereum the nodes have kind contract or wallet and a label. On Monad and Arc the nodes come from Sona's index, only when the token's index is complete, with kind unknown and no label. Otherwise nodes is empty, with token_holder_map_index_incomplete or token_index_unavailable in coverage.
Links
Links are read on Ethereum only. They are the Transfer logs of the last 30 days between two nodes. Each item is one unordered pair: from is the lower address of the two and not the sender, transfers counts both directions and amount sums them in token units. On Monad and Arc links.status is unavailable with token_holder_map_links_ethereum_only.
links.status | Meaning |
|---|---|
ready | items holds the stored read. built_at says when it finished and window_days the days it covers. |
building | No read is stored yet and one is queued, so items is empty. Ask again in a minute or a few. |
unavailable | No read will come for now, and coverage says why |
A busy token whose 30 days do not fit in the read gets a shorter window that ends at the newest block (token_holder_map_window_cut).
A cluster says the holders moved the token between each other. That can be one owner's wallets, an exchange and its hot wallets, or a pool and a router. It does not say they share an owner. Only clusters of two or more nodes are listed, largest share first, and id is that rank from 1.
Prices
A price chart and the current price of a coin. token is native for the chain's own coin (ETH on Ethereum, MON on Monad, USDC on Arc) or an address.
curl -s "https://api.sonaintel.com/v1/chains/eip155:143/tokens/native/prices?range=7d"range | Points |
|---|---|
1d | 25, hourly |
7d | 168, hourly (default) |
30d | 180, every 4 hours |
90d | 180, every 12 hours |
1y | 365, daily |
all | Up to 500, from the first price |
| Field | Meaning |
|---|---|
points | Oldest first, t in Unix seconds and usd in US dollars. interval_s is the step. |
current | The latest price with its own time t |
change_pct | Change from the first point to current, in percent to 2 decimals. null when the points do not cover the range or there are none, so show a dash and not 0. |
confidence | A score from 0 to 1 for how reliable the price is |
stale | true when the source could not answer and the chart is an older copy, or when the points do not cover the range. Do not treat it as live. |
Points before the chain's price floor are left out: 2015-07-30 on Ethereum and 2025-11-24, the Monad mainnet launch. A bridged token priced with the history of its original, such as USDC on Monad, therefore starts at the floor. A coin with no price answers 404 price_not_found. Charts can trail the market by a few minutes, and the current price by up to a minute.
Reference pages: Tokens endpoints and Prices endpoints.