Balance of one token on an address
See holdings on an entity page →
The balance of one token contract on one address: the value
balanceOf(address) returns at the end of a block, served for the covered
token contracts.
GET https://tracefast.xyz/api/v1/chains/1/entities/{address}/tokens/{token}/balance
| Parameter | In | Type | Notes |
|---|---|---|---|
address | path | string | the holder, 0x-prefixed, 40 hex characters, any case |
token | path | string | the token contract, same format |
block | query | integer, optional | the balance at the end of this block. Absent: the current balance |
chains/1 is a literal: the method serves Ethereum mainnet data. Other chain
ids answer 404 chain_not_supported. There is no limit and no other
parameter — this method answers about exactly one pair.
Access — an API key on the Intelligence plan or higher (plans), or no key at all: pay per call with x402 at the same path on https://mpp.tracefast.xyz/api/v1, at the price its 402 states. As a tool for AI agents: get_entity_token_balance on the MCP server. Stable — see stability.
Response
200 application/json, here with ?block=25500000:
{
"data": {
"address": "0xf977814e90da44bfa03b6295a0616a897441acec",
"token": "0xdac17f958d2ee523a2206206994597c13d831ec7",
"balance": "16900000000000000",
"decimals": 6,
"symbol": "USDT",
"window": { "kind": "block", "asOfBlock": 25500000 }
},
"meta": {
"chain": "ethereum",
"timestamp": 1788524630509,
"cached": true,
"docs": "https://docs.tracefast.xyz/api/address-token-balance"
}
}Without block, the same pair answers window.kind: "current" with
asOfBlock set to the block the balance is valid at.
| Field | Meaning |
|---|---|
address, token | the pair the answer is about, lowercase |
balance | a decimal string in the token's smallest unit, not divided by decimals. USDT has 6, so "16900000000000000" is 16,900,000,000 USDT |
decimals | as declared by the contract; absent when it declares none |
symbol | the ticker as declared by the contract, absent when it declares none. Not proof of identity: any contract can declare any symbol |
window.kind / window.asOfBlock | current or block, and the block the balance is true at — the state at the end of it |
window.nativeFreshness | not sent by this method: nativeFreshness describes the native ETH balance, which only the portfolio returns. Here window.asOfBlock alone says what the balance is valid at |
A refusal is not a zero
This is the whole point of the method. Balances are served for the covered
token contracts, and that set grows. A token outside it is refused with 422 token_not_covered instead of
being answered with a meaningless 0. Likewise, a pair with no balance
recorded at the block you asked about — for example a block before the token
was deployed — is refused with 422 balance_not_available. A rebasing token
such as stETH, whose balance grows without transfer events, is answered at a
past block with its balanceOf at the end of that block.
So "0" here always means a real zero: the token is covered, and the
address holds none of it at window.asOfBlock.
When you want everything an address holds rather than one token, ask
address portfolio — where an uncovered token is
simply absent, and hiddenCount says how much was left unvalued.
Errors
Every error is JSON: { "error": { "code": "...", "message": "...", "details": { … } } }
| Status | code | When | details |
|---|---|---|---|
| 400 | bad_request | malformed address or token; block not positive; an unknown query parameter | — |
| 422 | token_not_covered | the token is not covered, so no balance can be stated — not zero | token |
| 422 | balance_not_available | no balance of this pair is recorded at block — for example a block before the token was deployed. Not zero | reason: no_history_row, token, block |
| 422 | block_not_available | block is past the covered history | reason: block_not_available, maxAvailableBlock |
| 500 | internal_error | our source returned two balances for this pair at one block; neither is chosen | — |
| 404 | chain_not_supported | a chain id other than 1 | — |
| 402 | — | payment required, or payment rejected — see Paying with x402 | — |
Numbers a client has to act on are in details, never parsed out of message.
Related pages
- Address portfolio — everything held, valued in USD
- Token holders — the other side: who holds a token
- Paying with x402 — how a call is paid for
- Tokens & Collections — how the app reads a token
Last updated 22 Oct 2026, 08:06 UTC · verified against TraceFast v1.0.261 · Markdown