Skip to main content
Distinct from fetch_fills — this surface returns the user-facing aggregated trade row with on-chain fields (tx_hash, owner) and realized_pnl where the venue exposes them.

Parameters

user_address
string?
When None, returns the authenticated caller’s own trades (auth required on both venues). When Some(addr), performs a public lookup for that wallet — Polymarket only; Kalshi returns Err(NotSupported).
market_id
string?
Restrict to one market. Polymarket: condition ID. Kalshi: ticker.
side
OrderSide?
Filter by side. Kalshi applies this client-side (the API doesn’t filter).
start_ts
i64?
Unix seconds. Kalshi-only — Polymarket Data /trades doesn’t support time bounds.
end_ts
i64?
limit
usize?
Per-page cap: 1000 (Kalshi) / 500 (Polymarket).
cursor
string?
Opaque cursor. Polymarket uses offset pagination — the cursor is the numeric offset as a string and OpenPX synthesizes the next cursor only when the page filled.

Returns

trades
UserTrade[]
cursor
string?
null on the last page.
use openpx::UserTradesRequest;

// Caller's own trades (both venues, auth required).
let (trades, _) = ex.fetch_user_trades(UserTradesRequest::default()).await?;

// Public lookup of another wallet (Polymarket only).
let (others, _) = ex.fetch_user_trades(UserTradesRequest {
    user_address: Some("0xabc…".into()),
    limit: Some(50),
    ..Default::default()
}).await?;
{
  "trades": [
    {
      "id": "0xdeadbeef…",
      "market_id": "0xCONDITION",
      "condition_id": "0xCONDITION",
      "asset_id": "1029300…",
      "side": "buy",
      "size": 100.0,
      "price": 0.45,
      "role": null,
      "fee": null,
      "realized_pnl": 12.5,
      "tx_hash": "0xdeadbeef…",
      "owner": "0xabc…",
      "ts_ms": 1714000000000
    }
  ],
  "cursor": "100"
}