> For the complete documentation index, see [llms.txt](https://docs.hydromancer.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hydromancer.xyz/readme/rest-api/user-performance/usercompletedtrades.md).

# userCompletedTrades

Get a user's most recent completed (fully closed) positions, newest-first.

Returns the latest N completed trades for a user, newest-first. A completed trade represents a position that has been fully closed (size returned to \~0). Each record includes gross/net/funding PnL, average entry and exit prices, fees, fill counts (total and maker), open/close timestamps, duration, peak position size during the position's lifetime, leverage at close, and last-touch builder attribution.

`dex` is optional. Omit to return trades from 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 trade list to that dex.

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

`outcomes` is optional. Set it to `true` to return trades from HIP-4 outcome markets (coins like `#8131`) instead of perp and spot trades. The two sets are disjoint and are never mixed in one response.

Outcome records **omit** `positionType`, `fundingPnl`, `leverage` and `isCross` entirely. These are not unknown values — they do not apply. Outcome exposure is a token holding, so there is no short side, no leverage and no funding, and emitting `"Long"` or `"0"` would assert facts about the market that are not true.

On a perp or spot record all four are **always present and always carry a value**, so a client may read them directly there. Treat an absent field as "not applicable to this market type" — equivalently, as "this record is from an outcome market".

## POST Request

<table><thead><tr><th width="161.9998779296875">Field</th><th width="119">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>type</code></td><td>string</td><td>Must be <code>"userCompletedTrades"</code></td></tr><tr><td><code>user</code></td><td>string</td><td>Ethereum address (0x-prefixed, 42 characters)</td></tr><tr><td><code>builder</code></td><td>string</td><td>Filter to trades whose closing fill was routed through this builder address (last-touch attribution, 0x-prefixed). Omit (or send <code>null</code>) for no filtering. A malformed, empty or non-string value is a <code>400</code> rather than a silently unfiltered result (optional)</td></tr><tr><td><code>limit</code></td><td>int</td><td>Max results to return. Default 100, max 500 (optional)</td></tr><tr><td><code>dex</code></td><td>string</td><td>Scope 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><tr><td><code>outcomes</code></td><td>bool</td><td>Return HIP-4 outcome-market trades instead of perp/spot trades. Defaults to <code>false</code>. Cannot be combined with <code>dex</code>, since outcome markets are not dex-scoped. Outcome records <strong>omit</strong> <code>positionType</code>, <code>fundingPnl</code>, <code>leverage</code> and <code>isCross</code> entirely, rather than reporting placeholder values: outcome exposure is a token holding that is only ever long, is unlevered, and accrues no funding. All four are always present on perp and spot records (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": "userCompletedTrades",
    "user": "0x0000000000000000000000000000000000000000",
    "limit": 100
  }'
```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import os

response = requests.post(
    'https://api.hydromancer.xyz/info',
    json={
        'type': 'userCompletedTrades',
        'user': '0x0000000000000000000000000000000000000000',
        'limit': 100
    },
    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: 'userCompletedTrades',
        user: '0x0000000000000000000000000000000000000000',
        limit: 100
    }, {
        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 a JSON array of completed-trade records, ordered newest-first by `close_time` then `tx_index`.

| Field                  | Type    | Description                                                                                                                                                                           |
| ---------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `user`                 | string  | Ethereum address                                                                                                                                                                      |
| `coin`                 | string  | Asset symbol                                                                                                                                                                          |
| `position_type`        | string  | `"Long"` or `"Short"`. Omitted on outcome markets, which are only ever long                                                                                                           |
| `gross_pnl`            | string  | Realized PnL before fees (`exit_value - entry_value`, sign-adjusted for shorts)                                                                                                       |
| `net_pnl`              | string  | Realized PnL after fees and funding (`gross_pnl - fees + funding_pnl`)                                                                                                                |
| `funding_pnl`          | string  | Cumulative funding PnL accrued while the position was open (positive = received, negative = paid). Already included in `net_pnl`. Omitted on outcome markets, which accrue no funding |
| `entry_px`             | string  | Volume-weighted average entry price                                                                                                                                                   |
| `exit_px`              | string  | Volume-weighted average exit price                                                                                                                                                    |
| `position_closed_size` | string  | Size of the closed position, in contracts                                                                                                                                             |
| `fees`                 | string  | Total fees paid on fills attributed to this position                                                                                                                                  |
| `fills`                | int     | Number of fills on this position                                                                                                                                                      |
| `maker_fills`          | int     | Number of uncrossed (maker) fills on this position                                                                                                                                    |
| `open_time`            | int     | Time the position was opened (Unix ms)                                                                                                                                                |
| `close_time`           | int     | Time the position was fully closed (Unix ms)                                                                                                                                          |
| `duration_ms`          | int     | `close_time - open_time` in milliseconds                                                                                                                                              |
| `max_position_size`    | string  | Peak absolute position size reached during the position's lifetime                                                                                                                    |
| `builder`              | string? | Builder address from the closing fill, if any (last-touch attribution)                                                                                                                |
| `tx_index`             | int     | Transaction index of the closing fill (use with `close_time` for cursor-based pagination)                                                                                             |
| `leverage`             | int     | Leverage multiplier at close (e.g. `10` = 10x). Omitted on outcome markets, which are unlevered                                                                                       |
| `is_cross`             | boolean | `true` = cross margin, `false` = isolated. Omitted on outcome markets                                                                                                                 |

<details>

<summary>Response</summary>

```json
[
  {
    "user": "0x0000000000000000000000000000000000000000",
    "coin": "BTC",
    "position_type": "Long",
    "gross_pnl": "1240.50",
    "net_pnl": "1215.15",
    "funding_pnl": "-3.10",
    "entry_px": "45000.00",
    "exit_px": "45620.00",
    "position_closed_size": "2.0",
    "fees": "22.25",
    "fills": 4,
    "maker_fills": 2,
    "open_time": 1734567890123,
    "close_time": 1734571490123,
    "duration_ms": 3600000,
    "max_position_size": "2.5",
    "builder": null,
    "tx_index": 12,
    "leverage": 10,
    "is_cross": true
  }
]
```

</details>
