Skip to content
TraceFast Docs

Address counterparties

See this ranking on an entity page →

Who does this address actually deal with? The method ranks the addresses one address interacts with most, by successful transactions, counting three surfaces at once: top-level transactions, internal calls and token transfers.

GET https://tracefast.xyz/api/v1/chains/1/entities/{address}/counterparties
ParameterInTypeNotes
addresspathstring0x-prefixed, 40 hex characters, any case
blockqueryinteger, optionalThe ranking as it stood at the end of this block — everything up to and including it. Absent: the current all-time ranking
limitqueryinteger, optional1..100, default 100

chains/1 is a literal: the method serves Ethereum mainnet data. Other chain ids answer 404 chain_not_supported.

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_counterparties on the MCP server. Stable — see stability.

Response

200 application/json, trimmed to one row:

{
  "data": {
    "address": "0x28c6c06298d514db089934071355e5743bf21d60",
    "window": { "kind": "all", "asOfBlock": 25893676 },
    "corpus": 16301939,
    "corpusBasis": "precomputed",
    "boundaryTieCount": 0,
    "counterparties": [
      {
        "counterparty": "0xdac17f958d2ee523a2206206994597c13d831ec7",
        "succeededTxCount": 3664523,
        "interactionTxCount": 3665029,
        "sentTxCount": 3665029,
        "receivedTxCount": 4,
        "firstBlock": 12509940,
        "lastBlock": 25893673,
        "surfaces": ["external", "token"],
        "tokenClasses": ["fungible", "nft"]
      }
    ]
  },
  "meta": {
    "chain": "ethereum",
    "timestamp": 1788446231548,
    "cached": false,
    "docs": "https://docs.tracefast.xyz/api/address-counterparties"
  }
}

data

FieldMeaning
addressthe address the ranking is about, lowercase
window.kindall — the whole history up to asOfBlock; block — everything up to and including the requested block
window.asOfBlockthe block the ranking is true as of: for all, the block the current ranking is valid at; for block, the block you asked for
corpushow many distinct counterparties the ranking covered — the size of the set this list is the top of. 100 out of 216,770 is a different statement from 100 out of 104
corpusBasisprecomputed for the current ranking, at_block for a past one
boundaryTieCounthow many counterparties are level with the last row served and did not make the list
counterparties[]the rows, in ranking order, at most limit of them

A counterparty row

FieldMeaning
counterpartythe address, lowercase
succeededTxCountthe ranking key: transactions between the two that succeeded
interactionTxCountall transactions between the two, attempts included — reverted ones too
sentTxCount, receivedTxCountdirection, relative to the ranked address
firstBlock, lastBlockthe first and last block the two interacted in, within the window
surfaceswhere the relation was observed: external (top-level transactions), internal (calls inside transactions), token (token transfers). A surface missing here had no interaction between the two
surfaceCountstransactions per listed surface, on the attempts scale. A transaction touching two surfaces counts on both, so these do not add up to the ranking key. Absent when the breakdown was not computed for this address — absence means "not computed", never zero
tokenClassesfungible, nft or both; present only when surfaces includes token. It says which classes, not in what proportion

Ranking, ties and the corpus

Rows are ordered — most successful transactions first, then most recent, then by address — and they carry no rank number. That is deliberate: at the hundredth place of a mid-sized address there are typically hundreds of counterparties with identical counts, and numbering them would invent a precision the data does not have. boundaryTieCount says how many equals were left just outside the list, and corpus says how large the set was that these rows are the top of. Read the two together before calling a list "the counterparties of an address".

Asking about a past block

?block=N reconstructs the ranking from the full history up to and including block N. Two answers are refused rather than approximated:

  • An address too large to rank at a past block is refused with the bound stated (details.reason = peer_count_over_limit or row_count_over_limit, with the measured value and the maximum). The current ranking — the same call without block — is still available.
  • A block past the covered history answers 422 block_not_available with details.maxAvailableBlock, the highest block that can be answered.

Neither case returns a narrowed set that looks like a complete answer.

Errors

Every error is JSON: { "error": { "code": "...", "message": "...", "details": { … } } }

StatuscodeWhendetails
400bad_requestmalformed address; block not positive; limit outside 1..100; an unknown query parameterreason: limit_out_of_range, limit, maxLimit
400bad_requestwith block: the address is too large to rank at a past blockreason: peer_count_over_limit, peerCount, maxPeerCount; or reason: row_count_over_limit, rowCount, maxRowCount
422block_not_availableblock is past the covered historyreason: block_not_available, maxAvailableBlock
404chain_not_supporteda chain id other than 1—
402—payment required, or payment rejected — see Paying with x402—

Numbers a client has to act on are always in details. Never parse them out of message, which is written for a human reader.

What to expect

A full response at limit=100 stays under 27 KB.


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