Skip to content
TraceFast Docs

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
ParameterInTypeNotes
addresspathstring0x-prefixed, 40 hex characters, any case
limitqueryinteger, optional1..100, default 25
cursorquerystring, optionalnextCursor of the previous page, unchanged
directionquerystring, optionalsent or received
tokenquerystring, optionalonly transfers of this token contract
fromBlockqueryinteger, optionalinclusive lower block bound
toBlockqueryinteger, optionalinclusive 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. value is in the token's smallest unit, not divided by decimals. Each row carries the token's declared decimals to scale it.
  • The token is described as it declares itself. symbol and name are verbatim contract values, not verified names. Any contract can declare any symbol. No price rides this feed.
  • from is not always the sender of the transaction. On an approved transferFrom or a batch disburser, txSender is a different party. Where it could not be resolved it is absent — from never 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 a fromBlock/toBlock window. 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

FieldMeaning
addressthe address the feed is about, lowercase
transfers[]at most limit rows, newest first
nextCursorpass it back as cursor for the next page. Absent on the last page

A transfer

FieldMeaning
blockNumberthe block the transfer was emitted in
txIndexthe transaction's position in the block
logIndexthe log's position in the block
txHashthe transaction that emitted the transfer. Absent on the rare occasion it could not be resolved
timestampblock time, Unix seconds. Absent for the same reason as txHash
tokenthe token moved — see below
eventTypethe log that carried the transfer, for example transfer, transfer_single, transfer_batch
fromwhose balance decreased. Absent on a mint
towhose balance increased. Absent on a burn
valuethe raw amount, a decimal string, not scaled by decimals. Absent where the standard carries no amount
tokenIdthe NFT's token id, a decimal string
operatorthe party that executed an approved ERC-1155 transfer, when the log names one
rolesender, receiver or self — this address's part in the transfer
txSenderwho sent the transaction that emitted the transfer. Absent when it could not be resolved
txTothe transaction's top-level recipient — on a router or a disburser, not the token

token

FieldMeaning
addressthe token contract, lowercase
standardthe token standard: erc20, erc721, erc1155, erc777 or erc4626
symbolsymbol() as declared, verbatim. Absent when the contract declares none
namename() as declared, verbatim. Absent when the contract declares none
decimalsdecimals() 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": { … } } }

StatuscodeWhendetails
400bad_requesta filter on an address this active, without a narrow enough block windowreason: filter_needs_block_window, filters, rowCount, maxUnboundedRowCount, spanBlocks, maxSpanBlocks
400bad_requestdirection outside sent / receivedreason: direction_invalid, direction
400bad_requesttoken is not an addressreason: address_invalid
400bad_requestfromBlock above toBlockreason: block_window_inverted, fromBlock, toBlock
400bad_requestlimit outside 1..100reason: limit_out_of_range, maxLimit: 100
400invalid_cursorthe 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.


Last updated 22 Oct 2026, 08:06 UTC · verified against TraceFast v1.0.261 · Markdown