Tracing

Follow an address's money forward to where it was cashed out

Value-weighted forward walk. Follows the largest outgoing flows hop by hop and reports two things: cashout_summary (funds that reached a labelled exchange / OTC / mixer / service — where the money left the chain's anonymous part) and hanging (funds sitting in unlabelled dead ends).

Bounded by wall clock, not by completeness: a partial walk is returned rather than a timeout, so hops_traced may be below max_hops. This is a lead-generating tool, not an exhaustive accounting of the funds.

On ethereum and bsc the walk continues THROUGH a DEX (terminals[].transit, with the swap in terminals[].swaps[]). A swap whose output returned to the sender, or that was settled in a batch with other people's orders, is listed with followed: false and a reason: in a batch auction net balances cannot say which recipient received this sender's leg, so no branch is attributed to it rather than attributing all of them. Such an entry carries candidates — the receivers that did not take the asset this sender was selling, offered as leads. When exactly one candidate is an address the same sender/venue pair paid in a settlement that WAS attributable, that branch is walked and marked attribution: same-payee-as-attributable-settlement.

A cross-chain bridge is a terminal: the walk is single-chain and stops there. Where one leg of the crossing is a protocol vault we hold a registry for, the terminal additionally carries crosschain[]: the SAME vault of that protocol on another chain, matched 1:1 on the source's own key, each entry with its own chain and hop: 0. Read it as an OBSERVATION, never as an edge: it carries no amount and no direction (a bridge pool is a shared mailbox, N legs in against M legs out), it moves no risk across the chain boundary, and the node on the far side is hop 0 of a SEPARATE walk you have to run on that chain. Absent unless the deployment enables it.

post/v1/trace

Request

  • Base URL: https://intelapi.publicaml.org
  • URL: https://intelapi.publicaml.org/v1/trace
  • Auth: one of:
    • API key in header X-API-Key
    • none

Request body

addressstring required

The address whose outgoing funds to follow.

The address to look up, in its normal display form.

  • bitcoin — base58 (1…, 3…) or bech32/bech32m (bc1…, bc1p…). Case is SIGNIFICANT for base58; do not lowercase it. A 64-character lowercase TRANSACTION HASH is also accepted here: on bitcoin the graph is bipartite (address → transaction → address), so a transaction is a node with its own neighbours and its own findings. CoinJoin is classified on the transaction, not on the participants, and this is how you read it.
  • ethereum, bsc — 0x + 40 hex characters, any case.
  • tron — base58 (T…, 34 characters); the 0x 20-byte form is accepted too and is what the API stores and echoes.
chain'bitcoin' | 'ethereum' | 'bsc' | 'tron' required

Which blockchain the address belongs to. Send one of the four values in the enum. The short forms used by the older clients (ETH, BTC, TRX, BNB) and any capitalisation are still accepted, but responses always echo the canonical spelling.

Getting this wrong is the single commonest integration bug: the same 0x-prefixed address exists on ethereum, bsc and tron and means a different wallet on each, so the chain is part of the identity, never a hint. If it does not match the address format the call fails with invalid_address_format, which names the chain the address does look like.

max_hopsinteger

Default 5 (8 on bitcoin). On bitcoin one hop is HALF an economic step: the graph runs address → transaction → address.

max_widthinteger

How many outgoing edges to follow per address, largest first. A value outside 2-12 is pinned and named in clamped.

max_nodesinteger

Ceiling on addresses visited. Hitting it stops the walk with node_ceiling among the cut reasons; the frontier is reported as still moving. A value outside the range is pinned and named in clamped.

budget_secnumber

Wall-clock ceiling, clamped to 1-90 s. Default 15 s on ethereum/bsc (swap-through costs a query per DEX hop), 8 s on other EVM chains, 40 s on bitcoin. A value outside the range is pinned and named in clamped.

Response

The forward trace.

addressstring
chainstring
hops_tracedinteger

Below max_hops means the budget ran out, not that the money stopped.

elapsed_msinteger
hangingobject[]

Unlabelled dead ends — funds that are resting, not exited.

still_movingobject[]

Addresses the walk stopped at because of the hop or time limit, not because the money stopped.

partialboolean

True when the walk was cut short, by the clock or by the node ceiling. The result is a lead, not a complete accounting.

stop_reason'done' | 'deadline' | 'node_ceiling' | 'max_hops'

Why the walk ended.

clampedstring[]

Request fields the server pinned to a supported range.

Example response

{
  "terminals": [
    {
      "crosschain": [
        {
          "via": "crosschain:thorchain",
          "kind": "protocol_vault_peer",
          "method": "thorchain:asgard/pub_key",
          "key": {
            "type": "pub_key"
          }
        }
      ]
    }
  ]
}

Changes

No recorded changes to this operation across all 1 revision of this API.