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

# Get User PNL

> Calculate profit and loss for a user's trading activity

## Overview

Returns a comprehensive PNL (Profit and Loss) summary for a user, including:

* **Realized PNL** - Profit/loss from completed trades and settlements
* **Unrealized PNL** - Estimated profit/loss on open positions
* **Net PNL** - Combined realized and unrealized PNL
* **Total Fees** - All trading fees paid
* **Time Series** - Optional PNL over time

<Info>
  To avoid ambiguity, we denote the smallest possible multiple of USDC (0.000001 USDC) as one `uusdc`,
  which stands for µUSDC (micro-USDC), and denote the smallest possible multiple of a contract (0.01 contract)
  as one `ccontract` (centicontract).

  User-facing USDC balances are specified as fixed-point strings (e.g. `"1.2625"` for USDC). Contract quantities
  in the API and SDK are specified as integer `ccontracts` strings (e.g. `"1050"` for 10.50 contracts at precision 2).
</Info>

## PNL Calculation

**Realized PNL** is calculated as:

```
Realized PNL = Sell Revenue + Settlement Payouts - Buy Costs - Fees
```

**Unrealized PNL** estimates the value of open positions based on their cost basis compared to an estimated current value.

<ParamField query="userId" type="string" required>
  User's Ethereum wallet address (e.g., `0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266`)
</ParamField>

<ParamField query="marketId" type="string">
  Filter PNL calculation to a specific market. When set, deposits and withdrawals are excluded from the calculation.
</ParamField>

<ParamField query="startTime" type="number">
  Start timestamp in milliseconds. Only includes transactions after this time.
</ParamField>

<ParamField query="endTime" type="number">
  End timestamp in milliseconds. Only includes transactions before this time.
</ParamField>

<ParamField query="granularity" type="string" default="all">
  Time-series granularity for the `timeSeries` field:

  * `all` - No time series returned (default)
  * `hour` - Hourly PNL snapshots
  * `day` - Daily PNL snapshots
</ParamField>

## Response

<ResponseField name="totalDeposits" type="string" required>
  Total USDC deposited in µUSDC (integer string). Excluded when filtering by `marketId`.
</ResponseField>

<ResponseField name="totalWithdrawals" type="string" required>
  Total USDC withdrawn (claimed) in µUSDC (integer string). Excluded when filtering by `marketId`.
</ResponseField>

<ResponseField name="realizedPnl" type="string" required>
  Realized profit/loss in µUSDC (integer string). Positive = profit, negative = loss.
</ResponseField>

<ResponseField name="unrealizedPnl" type="string" required>
  Estimated unrealized profit/loss in µUSDC based on open positions (integer string).
</ResponseField>

<ResponseField name="netPnl" type="string" required>
  Total PNL (realized + unrealized) in µUSDC (integer string).
</ResponseField>

<ResponseField name="totalFeesPaid" type="string" required>
  Total trading fees paid in µUSDC (integer string).
</ResponseField>

<ResponseField name="timeSeries" type="array">
  Cumulative PNL over time. Only returned when `granularity` is `hour` or `day`.

  <Expandable>
    <ResponseField name="timestamp" type="number">Unix timestamp in milliseconds (start of the time bucket)</ResponseField>
    <ResponseField name="cumulativePnl" type="string">Cumulative PNL at this point in µUSDC (integer string)</ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash Basic PNL theme={null}
  curl "https://api.bison.markets/user/pnl?userId=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
  ```

  ```bash PNL for specific market theme={null}
  curl "https://api.bison.markets/user/pnl?userId=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266&marketId=KXFEDDECISION-26JAN-T425"
  ```

  ```bash Daily PNL time series theme={null}
  curl "https://api.bison.markets/user/pnl?userId=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266&granularity=day"
  ```

  ```bash PNL for date range theme={null}
  curl "https://api.bison.markets/user/pnl?userId=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266&startTime=1733011200000&endTime=1735689600000"
  ```
</RequestExample>

<ResponseExample>
  ```json 200 Basic theme={null}
  {
    "totalDeposits": "500000000",
    "totalWithdrawals": "100000000",
    "realizedPnl": "25000000",
    "unrealizedPnl": "5000000",
    "netPnl": "30000000",
    "totalFeesPaid": "150000"
  }
  ```

  ```json 200 With Time Series theme={null}
  {
    "totalDeposits": "500000000",
    "totalWithdrawals": "100000000",
    "realizedPnl": "25000000",
    "unrealizedPnl": "5000000",
    "netPnl": "30000000",
    "totalFeesPaid": "150000",
    "timeSeries": [
      {
        "timestamp": 1733011200000,
        "cumulativePnl": "-5000000"
      },
      {
        "timestamp": 1733097600000,
        "cumulativePnl": "10000000"
      },
      {
        "timestamp": 1733184000000,
        "cumulativePnl": "25000000"
      }
    ]
  }
  ```

  ```json 400 theme={null}
  {
    "error": "Valid Ethereum address is required"
  }
  ```
</ResponseExample>

## Use Cases

### Portfolio Dashboard

Display overall trading performance:

```typescript theme={null}
const pnl = await fetch('/user/pnl?userId=0x...').then(r => r.json());

console.log(`Net P&L: $${Number(pnl.netPnl) / 1_000_000}`);
console.log(`Fees Paid: $${Number(pnl.totalFeesPaid) / 1_000_000}`);
```

### Performance Chart

Build a PNL chart over time:

```typescript theme={null}
const pnl = await fetch('/user/pnl?userId=0x...&granularity=day').then(r => r.json());

// pnl.timeSeries contains daily cumulative PNL points
const chartData = pnl.timeSeries.map(point => ({
  date: new Date(point.timestamp),
  pnl: Number(point.cumulativePnl) / 1_000_000
}));
```

### Market-Specific Analysis

Analyze performance on a specific market:

```typescript theme={null}
const marketPnl = await fetch(
  '/user/pnl?userId=0x...&marketId=KXFEDDECISION-26JAN-T425'
).then(r => r.json());

console.log(`Market P&L: $${Number(marketPnl.realizedPnl) / 1_000_000}`);
```
