# userPnlLeaderboard

Returns a ranked list of users by realized PnL, win rate, or volume traded over a configurable window. Quality filters (`minTrades`, `minDaysActive`, `minAccountAgeDays`, `minHumanScore`) let you exclude one-shot accounts, brand-new wallets, and high-frequency bots.

`dex` is optional. Omit for a leaderboard aggregated across every perp DEX. Set to `"main_dex"` for the native Hyperliquid dex, or to a HIP-3 dex name (e.g. `"xyz"`) to scope the leaderboard to that dex. When the filter is set, each user's `tradedPairs` is scoped to the dex; `accountAgeDays` is always lifetime by design.

**note: data used to compute the leaderboard is starting from 1st of aug 2025**

## POST Request

<table><thead><tr><th width="180">Field</th><th width="105">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>type</code></td><td>string</td><td>Must be <code>"userPnlLeaderboard"</code></td></tr><tr><td><code>window</code></td><td>string</td><td>One of <code>"1d"</code>, <code>"7d"</code>, <code>"30d"</code>, <code>"90d"</code>, <code>"all"</code>. Default <code>"30d"</code> (optional)</td></tr><tr><td><code>sortBy</code></td><td>string</td><td>One of <code>"totalPnl"</code>, <code>"winRate"</code>, <code>"volumeTraded"</code>. Default <code>"totalPnl"</code> (optional)</td></tr><tr><td><code>limit</code></td><td>int</td><td>Max results to return. Default 100, max 1000 (optional)</td></tr><tr><td><code>offset</code></td><td>int</td><td>Pagination offset. Default 0 (optional)</td></tr><tr><td><code>minTrades</code></td><td>int</td><td>Minimum completed trades to include a user. Default 5 (optional)</td></tr><tr><td><code>minDaysActive</code></td><td>int</td><td>Minimum distinct active days to include a user. Default 1 (optional)</td></tr><tr><td><code>minAccountAgeDays</code></td><td>int</td><td>Minimum account age in days. Default 0 (optional)</td></tr><tr><td><code>minHumanScore</code></td><td>int</td><td>Minimum human score (0–100). Filters out users below this score (optional)</td></tr><tr><td><code>dex</code></td><td>string</td><td>Scope the leaderboard to a single perp DEX. <code>"main_dex"</code> for the native Hyperliquid dex, or a HIP-3 dex name (e.g. <code>"xyz"</code>). Omit for all dexes (optional)</td></tr></tbody></table>

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST https://api.hydromancer.xyz/info \
  -H "Authorization: Bearer $HYDROMANCER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "userPnlLeaderboard",
    "window": "30d",
    "sortBy": "totalPnl",
    "limit": 50,
    "minTrades": 10,
    "minHumanScore": 60
  }'
```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import os

response = requests.post(
    'https://api.hydromancer.xyz/info',
    json={
        'type': 'userPnlLeaderboard',
        'window': '30d',
        'sortBy': 'totalPnl',
        'limit': 50,
        'minTrades': 10,
        'minHumanScore': 60
    },
    headers={
        'Authorization': f'Bearer {os.environ.get("HYDROMANCER_API_KEY")}',
        'Content-Type': 'application/json'
    }
)

print(response.json())
```

{% endtab %}

{% tab title="Javascript" %}

```javascript
import axios from 'axios';

try {
    const response = await axios.post('https://api.hydromancer.xyz/info', {
        type: 'userPnlLeaderboard',
        window: '30d',
        sortBy: 'totalPnl',
        limit: 50,
        minTrades: 10,
        minHumanScore: 60
    }, {
        headers: {
            'Authorization': `Bearer ${process.env.HYDROMANCER_API_KEY}`,
            'Content-Type': 'application/json'
        }
    });

    console.log(response.data);
} catch (error) {
    console.error('Error:', error.message);
}
```

{% endtab %}
{% endtabs %}

***

## Response Fields

The response is an object with `users`, `total`, `limit`, and `offset` fields. Each entry in `users` has the same shape as a [userPnlSummary](/readme/rest-api/user-performance/userpnlsummary.md) response (minus `lossRate`).

| Field    | Type      | Description                                                         |
| -------- | --------- | ------------------------------------------------------------------- |
| `users`  | object\[] | Ranked list of user entries (see below)                             |
| `total`  | int       | Total users matching all filters before `limit`/`offset` is applied |
| `limit`  | int       | Echo of the request's `limit`                                       |
| `offset` | int       | Echo of the request's `offset`                                      |

### `users[]` entry

| Field            | Type      | Description                                                                                                                                                                        |
| ---------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `user`           | string    | Ethereum address                                                                                                                                                                   |
| `totalPnl`       | string    | Sum of net PnL across the user's completed trades in the window. Net PnL is `gross_pnl - fees + funding_pnl`                                                                       |
| `winRate`        | float     | Fraction of trades with `net_pnl > 0`, rounded to 4 decimals (0–1)                                                                                                                 |
| `totalTrades`    | int       | Number of completed trades in the window                                                                                                                                           |
| `volumeTraded`   | string    | Sum of `\|px × sz\|` across all of the user's fills in the window                                                                                                                  |
| `totalFees`      | string    | Sum of fees paid across completed trades                                                                                                                                           |
| `totalFunding`   | string    | Sum of cumulative funding PnL across completed trades. Already included in `totalPnl`                                                                                              |
| `daysActive`     | int       | Number of distinct UTC days on which the user had any fill in the window                                                                                                           |
| `accountAgeDays` | int?      | Days between the user's earliest known fill and now. `null` if the user has never had a fill on record                                                                             |
| `tradedPairs`    | string\[] | Distinct coin symbols the user has ever filled on (lifetime)                                                                                                                       |
| `humanScore`     | int       | Heuristic 0–100 score, higher = more likely a human trader. Combines average fills per trade, average distinct trading hours per active day, and the ratio of maker to taker fills |

<details>

<summary>Response</summary>

```json
{
  "users": [
    {
      "user": "0xabc0000000000000000000000000000000000001",
      "totalPnl": "248913.50",
      "winRate": 0.7124,
      "totalTrades": 178,
      "volumeTraded": "12450000.00",
      "totalFees": "2490.10",
      "totalFunding": "412.33",
      "daysActive": 28,
      "accountAgeDays": 145,
      "tradedPairs": ["BTC", "ETH", "HYPE"],
      "humanScore": 88
    },
    {
      "user": "0xabc0000000000000000000000000000000000002",
      "totalPnl": "187654.21",
      "winRate": 0.6489,
      "totalTrades": 312,
      "volumeTraded": "9821000.00",
      "totalFees": "1964.20",
      "totalFunding": "-87.41",
      "daysActive": 30,
      "accountAgeDays": 312,
      "tradedPairs": ["SOL", "BTC", "ETH", "HYPE"],
      "humanScore": 75
    }
  ],
  "total": 1842,
  "limit": 50,
  "offset": 0
}
```

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hydromancer.xyz/readme/rest-api/user-performance/userpnlleaderboard.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
