---
title: "KOL activity leaderboard on Robinhood Chain (BASIC+)"
method: GET
path: "/rhc/kol/leaderboard"
tags: ["Robinhood Chain"]
---

# KOL activity leaderboard on Robinhood Chain (BASIC+)

`GET /rhc/kol/leaderboard`

## Request

- Base URL: `https://madeonsol.com/api/v1`
- URL: `https://madeonsol.com/api/v1/rhc/kol/leaderboard`
- Auth: HTTP bearer

KOLs on Robinhood Chain ranked by trade count, then net ETH flow, over the chosen window. Tier: **BASIC**. (Net ETH is buy−sell flow, not realized PnL.)

**Win-rate ranking (PRO+, 2026-10-14).** `?sort=winrate_7d` or `winrate_30d` ranks KOLs by FIFO win rate instead: the share of fully closed positions (last sell in the window) with positive realized PnL, precomputed from the same 90-day wallet snapshot as `/rhc/kol/{wallet}?include_performance` (identical numbers, see `data_fingerprint`). Only scores computed in the last 2 hours with at least `min_closed` closed positions (default 3) are ranked; ties break on realized PnL. Rows then carry `evm_address`, `winrate_7d`/`winrate_30d`, `closed_positions_*`, `pnl_*_eth`, `median_hold_minutes_30d`, `auto_strategy_tag` and `computed_at` instead of the activity fields, and `period` is ignored. 503 `kol_scores_unavailable` when the precomputed scores cannot be read (never an empty ranking).

## Query parameters

- `period` '24h' | '7d' | '30d'
- `limit` integer
- `sort` 'trades' | 'winrate_7d' | 'winrate_30d'
- `min_closed` integer

## Response `200`

OK.

- object
  - `chain` 'robinhood'
  - `period` '24h' | '7d' | '30d'
  - `leaderboard` object[]
    - `kol_name` string, nullable
    - `kol_twitter` string, nullable
    - `trades` integer
    - `buys` integer
    - `sells` integer
    - `buy_eth` number: Total ETH bought in the window.
    - `sell_eth` number: Total ETH sold in the window.
    - `net_eth` number: buy_eth − sell_eth (flow, not realized PnL).
    - `tokens_traded` integer: Distinct tokens traded in the window.
    - `last_trade_at` string, date-time
    - `evm_address` string: Win-rate sorts only.
    - `status` 'available' | 'partial': Win-rate sorts only. partial = wallet over the 50,000-trade analysis cap.
    - `winrate_7d` number, nullable: Win-rate sorts only. Percent (0-100).
    - `winrate_30d` number, nullable
    - `closed_positions_7d` integer
    - `closed_positions_30d` integer
    - `pnl_7d_eth` number, nullable
    - `pnl_30d_eth` number, nullable
    - `median_hold_minutes_30d` number, nullable
    - `auto_strategy_tag` 'scalper' | 'day_trader' | 'swing_trader' | 'hodler', nullable
    - `data_fingerprint` string, nullable
    - `computed_at` string, date-time
  - `count` integer
  - `sort` 'winrate_7d' | 'winrate_30d': Win-rate sorts only.
  - `min_closed` integer: Win-rate sorts only.
  - `scores_meta` object: Win-rate sorts only: source, fresh_within_minutes, definition.

## Other responses

- `400`: Invalid query parameters.
- `401`: Missing or invalid API key, or an expired free-tier key. Authentication-stage error: no `X-RateLimit-*` headers, no `_rid`.
- `403`: sort=winrate_* requires PRO+.
- `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`: kol_scores_unavailable: precomputed win-rate scores cannot be read.

---

[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/d9531a28d83b?raw)
