Token transfers of an address
Open the address's token transfers →
The token transfers an address sent or received, newest first. Each row gives
the token as its contract declares itself, the raw amount, the parties, the
transaction that emitted the transfer, and who sent that transaction — for a
transfer made through a router or a batch disburser, another party than
from. The method covers ERC-20, ERC-721 and ERC-1155 tokens. A transfer the
address made to itself is shown once.
GET https://tracefast.xyz/api/v1/chains/1/entities/{address}/token-transfers
| Parameter | In | Type | Notes |
|---|---|---|---|
address | path | string | 0x-prefixed, 40 hex characters, any case |
limit | query | integer, optional | 1..100, default 25 |
cursor | query | string, optional | nextCursor of the previous page, unchanged |
direction | query | string, optional | sent or received |
token | query | string, optional | only transfers of this token contract |
fromBlock | query | integer, optional | inclusive lower block bound |
toBlock | query | integer, optional | inclusive upper block bound |
Access — an API key on the Investigation 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_transfers on the MCP server. Stable — see stability.
chains/1 is a literal: the method serves Ethereum mainnet data. Other chain
ids answer 404 chain_not_supported. An unknown parameter is refused rather
than ignored.
What it covers, and what it does not
- Amounts are raw.
valueis in the token's smallest unit, not divided bydecimals. Each row carries the token's declareddecimalsto scale it. - The token is described as it declares itself.
symbolandnameare verbatim contract values, not verified names. Any contract can declare any symbol. No price rides this feed. fromis not always the sender of the transaction. On an approvedtransferFromor a batch disburser,txSenderis a different party. Where it could not be resolved it is absent —fromnever stands in for it.- Filters on a very active address need a block window. Paging without
filters always works. A filter (
direction,token) searches the address's history, so on an address with a very large history it is answered only inside afromBlock/toBlockwindow. The refusal names the widest window it accepts.
Response
200 application/json, here with ?limit=2:
{
"data": {
"address": "0xf977814e90da44bfa03b6295a0616a897441acec",
"transfers": [
{
"blockNumber": 25947259,
"txIndex": 67,
"logIndex": 327,
"txHash": "0x10c5b6a6c8c92a8edd39123b6bd204354da1e954df822001f954fe892ae1cc02",
"timestamp": 1789046567,
"token": {
"address": "0xa35923162c49cf95e6bf26623385eb431ad920d3",
"standard": "erc20",
"symbol": "TURBO",
"name": "Turbo",
"decimals": 18
},
"eventType": "transfer",
"from": "0x28c6c06298d514db089934071355e5743bf21d60",
"to": "0xf977814e90da44bfa03b6295a0616a897441acec",
"value": "205242550000000000000000000",
"role": "receiver",
"txSender": "0x28c6c06298d514db089934071355e5743bf21d60",
"txTo": "0xa35923162c49cf95e6bf26623385eb431ad920d3"
},
{
"blockNumber": 25924455,
"txIndex": 103,
"logIndex": 53,
"txHash": "0xb2c2c65ca4b670f6415a0edefea474aa56919ae2c859424dd02921bd0380a271",
"timestamp": 1788771755,
"token": {
"address": "0x000000fa00b200406de700041cfc6b19bbfb4d13",
"standard": "erc20",
"symbol": "TOWNS",
"name": "Towns",
"decimals": 18
},
"eventType": "transfer",
"from": "0x28c6c06298d514db089934071355e5743bf21d60",
"to": "0xf977814e90da44bfa03b6295a0616a897441acec",
"value": "43150787000000000000000000",
"role": "receiver",
"txSender": "0x28c6c06298d514db089934071355e5743bf21d60",
"txTo": "0x000000fa00b200406de700041cfc6b19bbfb4d13"
}
],
"nextCursor": "AVsyNTkyNDQ1NSwxMDMsNTMsMCwwXRJSPzvoJtWnd_bE4qlgXoI"
},
"meta": {
"chain": "ethereum",
"timestamp": 1789047648311,
"cached": false,
"docs": "https://docs.tracefast.xyz/api/entity-token-transfers"
}
}The first row moved 205242550000000000000000000 / 10^18 = 205,242,550 TURBO.
data
| Field | Meaning |
|---|---|
address | the address the feed is about, lowercase |
transfers[] | at most limit rows, newest first |
nextCursor | pass it back as cursor for the next page. Absent on the last page |
A transfer
| Field | Meaning |
|---|---|
blockNumber | the block the transfer was emitted in |
txIndex | the transaction's position in the block |
logIndex | the log's position in the block |
txHash | the transaction that emitted the transfer. Absent on the rare occasion it could not be resolved |
timestamp | block time, Unix seconds. Absent for the same reason as txHash |
token | the token moved — see below |
eventType | the log that carried the transfer, for example transfer, transfer_single, transfer_batch |
from | whose balance decreased. Absent on a mint |
to | whose balance increased. Absent on a burn |
value | the raw amount, a decimal string, not scaled by decimals. Absent where the standard carries no amount |
tokenId | the NFT's token id, a decimal string |
operator | the party that executed an approved ERC-1155 transfer, when the log names one |
role | sender, receiver or self — this address's part in the transfer |
txSender | who sent the transaction that emitted the transfer. Absent when it could not be resolved |
txTo | the transaction's top-level recipient — on a router or a disburser, not the token |
token
| Field | Meaning |
|---|---|
address | the token contract, lowercase |
standard | the token standard: erc20, erc721, erc1155, erc777 or erc4626 |
symbol | symbol() as declared, verbatim. Absent when the contract declares none |
name | name() as declared, verbatim. Absent when the contract declares none |
decimals | decimals() as declared. Absent — never 18 — when the contract declares none |
Pagination
The feed pages by keyset. Pass nextCursor back as cursor, with the same
filters, until nextCursor is absent. A cursor is valid only for this
method, this address and these filters; any other use answers
400 invalid_cursor, and the recovery is to restart from the first page. A
page can hold fewer than limit rows while nextCursor is still present. See
pagination.
Errors
Every error is JSON: { "error": { "code": "...", "message": "...", "details": { … } } }
| Status | code | When | details |
|---|---|---|---|
| 400 | bad_request | a filter on an address this active, without a narrow enough block window | reason: filter_needs_block_window, filters, rowCount, maxUnboundedRowCount, spanBlocks, maxSpanBlocks |
| 400 | bad_request | direction outside sent / received | reason: direction_invalid, direction |
| 400 | bad_request | token is not an address | reason: address_invalid |
| 400 | bad_request | fromBlock above toBlock | reason: block_window_inverted, fromBlock, toBlock |
| 400 | bad_request | limit outside 1..100 | reason: limit_out_of_range, maxLimit: 100 |
| 400 | invalid_cursor | the cursor is not valid for this request — restart from the first page | — |
When a filter is refused, pass a fromBlock/toBlock window no wider than
details.maxSpanBlocks, or drop the filter. The refusal has the same shape as
on transfers of a token.
Malformed input, unknown parameters and the key check's 401/403/429 are the same for every method — see conventions and API keys.
Related pages
- Transfers of a token — the other direction: every transfer of one token
- Address portfolio — what the address holds now, valued
- Transactions of an address — the transactions behind the transfers
- Activity Feeds — the same feed in the app
Last updated 22 Oct 2026, 08:06 UTC · verified against TraceFast v1.0.261 · Markdown