---
title: "Wallet profile on Robinhood Chain (PRO+)"
method: GET
path: "/rhc/wallet/{address}"
tags: ["Robinhood Chain"]
---

# Wallet profile on Robinhood Chain (PRO+)

`GET /rhc/wallet/{address}`

## Request

- Base URL: `https://madeonsol.com/api/v1`
- URL: `https://madeonsol.com/api/v1/rhc/wallet/{address}`
- Auth: HTTP bearer

Any Robinhood Chain wallet's 90-day trading profile: FIFO cost-basis PnL, per-token breakdown, recent trades, and a reputation block (tracked KOL, known deployer + tier, alpha-ranked, dump-cluster membership, early-buyer count).

**Denomination is ETH**, matching the rest of the RHC tree (`eth_amount`, `net_eth`) — not USD. A USD cost basis would silently mix in the tokenized-stock quote assets some flap bonding curves price in.

**Sourced from `trader_eoa` — the effective trading account, never the swap-log `trader`**, which is the router address on any aggregated swap.

`stats.analyzed_trades + stats.unattributed_trades + stats.unsized_trades === stats.total_trades` always holds — no trade silently vanishes from the accounting. The two exclusions mean different things: **`unattributed_trades`** is swaps with no token side at all (token↔token exotic pools, unclassified pools) and is routine, often large for MM bots; **`unsized_trades`** is a token-side trade whose quantity could not be reconstructed from `rhc_trades`' raw uint256 leg amounts, which is the actual quality signal and should be ~0.

**Attribution floor:** analysis starts at `notes.attribution_complete_from` (2026-07-18) rather than the full 90 days — `trader_eoa` was written for under half of earlier trades, and a partial view produces positions the wallet no longer holds.

A wallet exceeding the 50,000-trade analysis cap returns `stats.partial: true`. Heavy wallets that blow the query budget return the reputation block with `stats_unavailable: true` rather than a 500. Responses are cached 60s per address. Tier: **PRO+**.

## Path parameters

- `address` string, required

## Response `200`

OK. `stats` is null only when the wallet is known solely through a reputation table (e.g. a deployer that has never traded).

- object
  - `chain` 'robinhood'
  - `address` string
  - `stats` object, nullable
    - `first_seen` string, date-time, nullable
    - `last_seen` string, date-time, nullable
    - `total_trades` integer
    - `analyzed_trades` integer: Trades that entered the FIFO computation.
    - `unattributed_trades` integer: Swaps with no token side or direction — token↔token exotic pools and pools our resolver has not classified. Routine, and a large share for MM bots (47% on one 512k-trade fleet wallet). NOT a data-quality signal.
    - `unsized_trades` integer: Token-side trades whose QUANTITY could not be reconstructed — excluded from PnL entirely. This IS the quality signal and should be ~0 (measured 0 across a 512k-trade wallet).
    - `buys` integer
    - `sells` integer
    - `bought_eth` number
    - `sold_eth` number
    - `realized_pnl_eth` number
    - `unrealized_pnl_eth` number: Mark-to-market on FIFO-open positions using rhc_token_prices.last_price_native. Unpriced positions contribute 0. **FIFO figure, not a holding**: it includes lots transferred out since the buy. For PnL on what is actually held use `holdings.unrealized_known_eth`.
    - `total_pnl_eth` number: realized_pnl_eth + unrealized_pnl_eth (FIFO).
    - `held_value_eth` number: FIFO-unmatched DEX buys x current price. **Not an on-chain balance**: a token sent out by transfer still counts here. The proven current value is `holdings.verified_value_eth`.
    - `unique_tokens` integer
    - `open_positions` integer: FIFO-open positions (unmatched DEX buys). How many are actually still held is in `holdings`.
    - `window_days` integer
    - `partial` boolean: Present only when the 50,000-trade cap was hit.
  - `flags` object
    - `is_kol` boolean
    - `kol_name` string, nullable
    - `is_deployer` boolean
    - `deployer_tier` 'elite' | 'good' | 'neutral' | 'spammer', nullable
    - `deployer_tokens` integer, nullable
    - `deployer_runner_rate` number, nullable
    - `is_alpha_tracked` boolean
    - `alpha_win_rate` number, nullable
    - `alpha_net_eth` number, nullable
    - `alpha_tokens_traded` integer, nullable
    - `likely_bot` boolean, nullable: Atomic-arb / MM signature from mv_rhc_alpha_wallets.
    - `is_dumper` boolean: ≥5 dump cohorts AND 0 runner cohorts, rolling 42d. Rebuilt daily — up to ~48h stale. Absence means NOT OBSERVED, not verified clean.
    - `dump_cluster` object, nullable
    - `early_buyer_tokens` integer: Tokens where this wallet was in the first-20 buyer cohort.
  - `top_tokens` object[]
    - `still_holding` boolean: FIFO meaning: an unmatched DEX buy exists. NOT an on-chain balance; see holding_status.
    - `holding_status` 'HELD' | 'PARTIALLY_REDUCED' | 'TRANSFERRED_OR_DISPOSED' | 'EXTERNAL_INFLOW' | 'BALANCE_UNVERIFIED', nullable: On-chain status of a FIFO-open token; null when the token is FIFO-closed.
  - `holdings` object, nullable: On-chain verification of every FIFO-open position: balanceOf + decimals read from our own Robinhood Chain node in one Multicall3 batch (cached 30 s). `complete: false` means at least one position is BALANCE_UNVERIFIED (node unreachable, call reverted, non-standard token, decimals mismatch) and contributes NO value.
    - `balance_source` 'rhc_node_multicall3'
    - `checked_at` string, date-time
    - `complete` boolean
    - `fifo_open_positions` integer
    - `held` integer
    - `partially_reduced` integer
    - `transferred_or_disposed` integer
    - `external_inflow` integer
    - `unverified` integer
    - `verified_value_eth` number: PROVEN balances x current price: the current value of the tokens this wallet bought on a DEX and still holds. Unverified and unpriced positions contribute nothing.
    - `unpriced_held` integer
    - `cost_basis_held_eth` number: Cost basis of the FIFO-known portion still in the wallet.
    - `unrealized_known_eth` number: Unrealized PnL on the portion whose cost basis is known AND still held. External inflows never add trading profit.
    - `cost_basis_not_held_eth` number: Cost basis of FIFO lots no longer in the wallet (transferred out or disposed outside indexed swaps). Outcome unknown: neither realized nor unrealized.
  - `recent_trades` object[]
  - `derived` object, nullable
    - `win_rate` number, nullable
    - `wins` integer
    - `losses` integer
    - `avg_trade_size_eth` number, nullable
    - `is_active` boolean
  - `stats_unavailable` boolean: Present when the trade aggregation was skipped on a timeout. Absence of stats is then UNPROVEN — do not read it as an inactive wallet.
  - `cache_hit` boolean

## Other responses

- `400`: Invalid EVM address.
- `401`: Missing or invalid API key, or an expired free-tier key. Authentication-stage error: no `X-RateLimit-*` headers, no `_rid`.
- `403`: Requires Pro or Ultra tier.
- `404`: No recorded Robinhood Chain activity for this address as a trading account (`trader_eoa`). The body carries `address_type` (`eoa` / `eoa_7702` / `contract` / `unknown`, from eth_getCode); for a contract also `contract_trader_swaps_last_hour` (swaps where it is the swap-log trader; null = not measured) and a `note`. A contract cannot sign transactions, so its own swaps are never attributed to a wallet here; identities are not merged.
- `429`: Too many requests. Every 429 carries `Retry-After`. A quota 429 (`rate_limit_exceeded`, with `X-RateLimit-*`), a heavy-query concurrency 429 (`error_kind` `concurrency`/`capacity`), or the per-IP authentication-failure block (30 failed auths/min; plain `error` + `retry_after_seconds`, no `X-RateLimit-*`).
- `500`: Unexpected server error from the route (`Internal server error`, with `_rid`). Safe to retry with backoff. A failed API-key lookup is a 503 `auth_backend_unavailable`, never a 500.
- `503`: Temporarily unavailable — a Postgres statement timeout while the dataset is under load or maintenance (`statement_timeout`, with `X-RateLimit-*` and `_rid`), or the API-key lookup itself unavailable (`auth_backend_unavailable`, authentication stage: no `X-RateLimit-*`, no `_rid`, not counted as a failed authentication). Always carries `Retry-After`; honour it.

---

[API](https://skmtc.dev/madeonsol/apis/madeonsol-api.md) · [All operations](https://skmtc.dev/madeonsol/apis/madeonsol-api/llms.txt) · [OpenAPI document](https://skmtc.dev/madeonsol/apis/madeonsol-api/revisions/96ce84657f55?raw)
