> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kuru.io/llms.txt
> Use this file to discover all available pages before exploring further.

# List user trades

> Read finalized maker and taker trades with allocated fees and PnL.

> [!NOTE]
>
> Response JSON below is an illustrative testnet snapshot, not a live mainnet result. Use the selected server and its network-specific addresses for actual requests.

**userId** `string` *required*

Unsigned decimal Kuru user ID.

**limit** `integer` (default: 100)

Page size from `1` through `500`.

**cursor** `string`

Opaque exclusive continuation cursor from `pagination.nextCursor`.

**marketAddress** `string`

Optional lowercase 20-byte market filter for trade rows only. It does not filter `data.positions`.

**from** `integer`

Inclusive Unix time in seconds.

**to** `integer`

Inclusive Unix time in seconds. When both bounds are present, `to` must be
greater than `from`.

**feedEpoch** `integer | null` *required*

Feed epoch containing `globalUserSeq`.

**globalUserSeq** `string | null` *required*

Finalized user sequence covered by the materialized response.

**data** `object` *required*

Trade history and the complete position baseline.

**Data fields**

**trades** `array` *required*

Maker and taker user legs ordered newest first by canonical source position.

**trades\[].tradeId** `string` *required*

**trades\[].recordIdx** `integer` *required*

**trades\[].marketAddress** `string` *required*

**trades\[].symbol** `string` *required*

**trades\[].isMaker** `boolean` *required*

**trades\[].isBuy** `boolean` *required*

Side of this user leg.

**trades\[].liquidity** `string` *required*

`active` for active FIFO liquidity or `passive` for passive-band liquidity.

**trades\[].price** `string` *required*

Execution price in market price precision (pp).

**trades\[].filledSize** `string` *required*

Fill quantity in the market's native size precision.

**trades\[].updatedSize** `string` *required*

Remaining active-order or passive-liquidity size after the fill.

**trades\[].fees** `object` *required*

Actual allocated fee amounts. Every value is normalized to x18 using integer
floor division.

**trades\[].pnl** `object` *required*

Per-fill realized PnL and the available post-trade cost-basis cut.

**trades\[].blockTimestamp** `integer` *required*

Block proposal time in Unix seconds.

**trades\[].blockNumber** `string` *required*

**trades\[].transactionHash** `string` *required*

**positions** `array` *required*

Position baseline across all tracked markets for this user, ordered by market
address. Independent of trade pagination, market filters, and time filters.
Includes tracked closed positions with zero size and cost; returns `[]` when
there are no tracked positions. These are trade-accounting positions, not token balances.

**Position fields**

**marketAddress** `string` *required*

Lowercase market address.

**openSize** `string` *required*

Open base inventory in native market size precision (sp).

**openCost** `string` *required*

Cost basis of that inventory in native quote-token units. Divide by
`10^quoteTokenDecimals` for display, using the market's quote token metadata.

**pagination.nextCursor** `string | null` *required*

The fee fields are `makerFee`, `takerFee`, `builderFeeBase`, and
`builderFeeQuote`. Inapplicable amounts are zero. These are allocated fee
amounts, not PPS rates.

The PnL fields are `grossRealizedPnl`, `realizedPnl`, `openSize`, and
`openCost`. Realized PnL fields remain x18; `openCost` uses native quote-token
units and `openSize` uses native market size precision. This matches the units
of `data.positions[].openCost` and `data.positions[].openSize`. `openSize` and `openCost` are `null` when the row does not publish
an authoritative post-trade position cut.

On the first page, `data.positions` and the replay cursor describe the same committed
state, after complete trade matches. Historical `data.trades[].pnl` values still describe
their individual trades, not this current baseline. Continuation pages retain
the first page's positions and replay cursor, even when newer trades arrive.

When both cursor fields are non-null, install `data.positions` once as the accounting
baseline and subscribe to `userTrades@f`, using `feedEpoch` and passing
`globalUserSeq` as the subscription's `seq`. Do not overwrite live positions
when loading additional history pages. A fresh first-page request establishes
a new baseline. If either cursor field is null, the response cannot establish
a replay handoff; do not interpret a missing cursor as zero.

The example below illustrates the response shape; cursor values are opaque.

```json 200 theme={null}
{
  "feedEpoch": 18,
  "globalUserSeq": null,
  "data": {
    "trades": [
      {
        "tradeId": "101",
        "recordIdx": 1,
        "marketAddress": "0x0a082280e4ea3d822e23ec1186685477241a039d",
        "symbol": "WETHUSDC",
        "isMaker": true,
        "isBuy": false,
        "liquidity": "active",
        "price": "24707100",
        "filledSize": "60000000",
        "updatedSize": "940000000",
        "fees": {
          "makerFee": "0",
          "takerFee": "0",
          "builderFeeBase": "0",
          "builderFeeQuote": "0"
        },
        "pnl": {
          "grossRealizedPnl": "-327912000000000000",
          "realizedPnl": "-327912000000000000",
          "openSize": "260000000",
          "openCost": "65640954"
        },
        "blockTimestamp": 1788353771,
        "blockNumber": "59066947",
        "transactionHash": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
      },
      {
        "tradeId": "98",
        "recordIdx": 0,
        "marketAddress": "0x0a082280e4ea3d822e23ec1186685477241a039d",
        "symbol": "WETHUSDC",
        "isMaker": true,
        "isBuy": true,
        "liquidity": "active",
        "price": "25227200",
        "filledSize": "80000000",
        "updatedSize": "920000000",
        "fees": {
          "makerFee": "0",
          "takerFee": "0",
          "builderFeeBase": "0",
          "builderFeeQuote": "0"
        },
        "pnl": {
          "grossRealizedPnl": "0",
          "realizedPnl": "0",
          "openSize": "320000000",
          "openCost": "80788866"
        },
        "blockTimestamp": 1788342297,
        "blockNumber": "59028992",
        "transactionHash": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
      },
      {
        "tradeId": "97",
        "recordIdx": 0,
        "marketAddress": "0x0a082280e4ea3d822e23ec1186685477241a039d",
        "symbol": "WETHUSDC",
        "isMaker": true,
        "isBuy": false,
        "liquidity": "active",
        "price": "25277700",
        "filledSize": "80000000",
        "updatedSize": "920000000",
        "fees": {
          "makerFee": "0",
          "takerFee": "0",
          "builderFeeBase": "0",
          "builderFeeQuote": "0"
        },
        "pnl": {
          "grossRealizedPnl": "19736000000000000",
          "realizedPnl": "19736000000000000",
          "openSize": "240000000",
          "openCost": "60600794"
        },
        "blockTimestamp": 1788342296,
        "blockNumber": "59028988",
        "transactionHash": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
      },
      {
        "tradeId": "96",
        "recordIdx": 0,
        "marketAddress": "0x0a082280e4ea3d822e23ec1186685477241a039d",
        "symbol": "WETHUSDC",
        "isMaker": true,
        "isBuy": true,
        "liquidity": "active",
        "price": "25566900",
        "filledSize": "80000000",
        "updatedSize": "920000000",
        "fees": {
          "makerFee": "0",
          "takerFee": "0",
          "builderFeeBase": "0",
          "builderFeeQuote": "0"
        },
        "pnl": {
          "grossRealizedPnl": "0",
          "realizedPnl": "0",
          "openSize": "320000000",
          "openCost": "80801058"
        },
        "blockTimestamp": 1788342288,
        "blockNumber": "59028961",
        "transactionHash": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
      },
      {
        "tradeId": "95",
        "recordIdx": 0,
        "marketAddress": "0x0a082280e4ea3d822e23ec1186685477241a039d",
        "symbol": "WETHUSDC",
        "isMaker": true,
        "isBuy": false,
        "liquidity": "active",
        "price": "25618000",
        "filledSize": "80000000",
        "updatedSize": "920000000",
        "fees": {
          "makerFee": "0",
          "takerFee": "0",
          "builderFeeBase": "0",
          "builderFeeQuote": "0"
        },
        "pnl": {
          "grossRealizedPnl": "375708000000000000",
          "realizedPnl": "375708000000000000",
          "openSize": "240000000",
          "openCost": "60342878"
        },
        "blockTimestamp": 1788342287,
        "blockNumber": "59028956",
        "transactionHash": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
      }
    ],
    "positions": [
      {
        "marketAddress": "0x0a082280e4ea3d822e23ec1186685477241a039d",
        "openSize": "260000000",
        "openCost": "65640954"
      }
    ]
  },
  "pagination": {
    "nextCursor": "eyJ2IjoxLCJyIjoidXNlci10cmFkZXMiLCJmIjoiYzJmNThiMGRjNDQyOWQ1MjBlYzczZDgyNzRjN2I1NDUzYmViODk3NDRkMTQ3YzVmOTRiMjkzYzY0YzJkZjYxNiIsInMiOiJlZWIzM2I0ZTFmYjMyNTZmNzc5YWYxOTEwMjU5ZDE4YzQzYjliNjc5ZWQ4MzIzOTQ1MWM0ZGU5ZmMwZTkwYjg4IiwibyI6MCwiZSI6MTc4ODQzNDA0OH0.cJ6grTznYNiRPhNs2QZq3ErEyxuc7g9A9i2RTj6FmRg"
  }
}
```


## OpenAPI

````yaml api/data-source/openapi.yaml GET /api/v1/users/{userId}/trades
openapi: 3.1.0
info:
  title: Kuru Data Source API
  version: 1.0.0
servers:
  - url: https://api.mainnet.kuru.io
    description: Monad mainnet (default)
  - url: https://api.testnet.kuru.io
    description: Monad testnet
security: []
paths:
  /api/v1/users/{userId}/trades:
    get:
      summary: Get user trades
      operationId: getUserTrades
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: integer
        - name: marketAddress
          in: query
          schema:
            type: string
        - name: limit
          in: query
          schema:
            type: integer
        - name: cursor
          in: query
          schema:
            type: string
        - name: from
          in: query
          schema:
            type: integer
        - name: to
          in: query
          schema:
            type: integer
      responses:
        '200':
          description: User trades

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.