One wallet across every chain it traded
The per-chain profiles merged into one header: lifetime totals, the PNL split per chain with each chain's share, and the most profitable chain.
Chains in scope whose wallet data could not be read are listed in unavailable_chains rather than silently counted as zero — a missing chain and a chain that earned nothing are different claims. Omit chains for every served chain.
Path Parameters
the wallet address
1 <= length <= 128Query Parameters
comma-separated chain slugs or ids; omit for every served chain
items <= 32rolling window the metrics are computed over
"30d"Value in
- "1d"
- "7d"
- "30d"
- "1y"
- "all"
Header Parameters
payment methods the client can use, comma-separated, case-insensitive. With x402 in the list, a spent keyless budget answers 402 with the x402 challenge instead of 429.
base64 x402 v2 payment payload for this request. A paid request skips the keyless budget and is settled only when it answers 2xx. The v1 header X-PAYMENT is accepted too.
Response Body
application/json
application/problem+json
application/problem+json
application/json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
curl -X GET "https://example.com/wallets/string/overview"{ "profiles": [ { "address": "string", "chain": { "slug": "hyperliquid", "chain_id": 0 }, "tier": "string", "type": "unknown", "labels": [ { "kind": 0, "name": "string", "confidence": 0.1, "token_address": "string" } ], "human_known": true, "rebuild_skipped": true, "rebuild_skip_reason": "string", "copy_eligible": true, "cluster_id": 0, "first_seen_at": "string", "first_onchain_at": "string", "last_active_at": "string", "age_is_estimated": true, "user_score": { "value": 0, "status": "unknown" }, "scammer_score": { "value": 0, "band": "none" }, "signals": [ { "kind": "string", "title": "string", "detail": "string", "subject": "string", "points": 0.1, "occurrences": 0, "last_seen": "string", "direction": "string", "target": "string" } ], "metrics": [ { "window": "1d", "realized_pnl_usd": 0.1, "unrealized_pnl_usd": 0.1, "total_pnl_usd": 0.1, "rated_pnl_usd": 0.1, "gross_profit_usd": 0.1, "gross_loss_usd": 0.1, "invested_usd": 0.1, "volume_usd": 0.1, "roi": 0.1, "win_rate": 0.1, "trade_win_rate": 0.1, "median_roi": 0.1, "profit_factor": 0.1, "avg_trade_usd": 0.1, "avg_hold_seconds": 0, "trades": 0, "winning_trades": 0, "losing_trades": 0, "tokens_traded": 0, "closed_positions": 0, "open_positions": 0, "rated_positions": 0, "excluded_transfer_only": 0, "excluded_untracked": 0, "excluded_no_outcome": 0 } ] } ], "per_chain": [ { "chain": { "slug": "hyperliquid", "chain_id": 0 }, "realized_pnl_usd": 0.1, "total_pnl_usd": 0.1, "share_of_total": 0.1 } ], "most_profitable_chain": { "slug": "hyperliquid", "chain_id": 0 }, "unavailable_chains": [ { "slug": "hyperliquid", "chain_id": 0 } ], "lifetime": { "deployed_usd": 0.1, "gross_bought_usd": 0.1, "gross_sold_usd": 0.1, "realized_pnl_usd": 0.1, "unrealized_pnl_usd": 0.1, "total_pnl_usd": 0.1, "unrealized_available": true }}Behaviour labels for many wallets POST
Batch by construction: a transaction table calls this once per page to mark robot, sniper and sandwich makers, where a per-row call would be one request per visible trade. It is the one wallet read that is a `POST`, because a list of up to 200 addresses does not belong in a query string. Addresses absent from the response carry no labels.
Chain and DEX protocol boards GET
Precomputed rankings of the chains we index, and of the venues inside one chain. Every row carries its raw metrics beside its dimension scores, so a client can sort on any figure and ignore the composite entirely. `scope=protocols` is one board of DEXes and launchpads together. Every pair counts in exactly one row: the launchpad it was created on when it has one, otherwise the DEX that owns its factory. A launchpad trading on Uniswap pools is its own row, and its volume is never part of Uniswap's. `category` labels each row (`dex`, `launchpad`, `perps`, `aggregator`), `infra` names the protocols its pools trade on, and `metrics.hosted_volume_24h` shows the volume other venues trade on a row's pools without ranking it. Pools no one can name — including v4 pools under a hook with no known brand — stay out of the rows and inside the share denominator, so the named shares fall short of one by exactly that amount. Nothing here is computed on the request: the response is drawn from a snapshot taken on a fixed cadence, and `snapshot_at` says exactly how old it is. Rows the board refused to rank appear in `excluded` with a reason rather than going silently missing. With `seasonal=true` the window is a season instead of the live rolling day. A closed season is frozen and never changes; a running one still moves.