## Portfolio
### GET /v1/positions — Positions

**Scope:** `positions.read`

Returns net positions across all products.

#### Response — `200 OK`

```json
{
  "positions": [
    {
      "exchange_segment": "NSE",
      "symbol": "RELIANCE",
      "instrument_id": 12027,
      "product": "I",
      "day_buy_qty": 10,
      "day_buy_amt": 2499750,
      "day_buy_avg_price": 249975,
      "day_sell_qty": 0,
      "day_sell_amt": 0,
      "day_sell_avg_price": 0,
      "open_buy_qty": 10,
      "open_buy_amt": 2499750,
      "open_buy_avg_price": 249975,
      "open_sell_qty": 0,
      "open_sell_amt": 0,
      "open_sell_avg_price": 0,
      "cf_buy_qty": 0,
      "cf_buy_amt": 0,
      "cf_buy_avg_price": 0,
      "cf_sell_qty": 0,
      "cf_sell_amt": 0,
      "cf_sell_avg_price": 0,
      "net_qty": 10,
      "net_avg_price": 249975,
      "total_buy_qty": 10,
      "total_buy_amt": 2499750,
      "total_buy_avg_price": 249975,
      "total_sell_qty": 0,
      "total_sell_amt": 0,
      "total_sell_avg_price": 0,
      "realised_pnl": 0,
      "last_modified_at": 1747798205890
    }
  ]
}
```

`positions` holds one object per position. Every `*_qty` is integer units; every `*_amt` and `*_avg_price` is integer paise. The buy/sell groups come in triples — quantity, amount, quantity-weighted average price — and a side with no quantity has all three at `0`.

| Field | Type | Notes |
|---|---|---|
| `exchange_segment` | string | `NSE` \| `NFO` \| `BSE` \| `BFO`. |
| `symbol` | string | The scrip master's `symbol` column — the same value `POST /v1/orders` takes. |
| `instrument_id` | integer | Scrip-master `id`. Use with the Market Data APIs. |
| `product` | string | `C` \| `I` \| `M` \| `F`. |
| `day_buy_qty`, `day_buy_amt`, `day_buy_avg_price` | integer | Buys executed today. |
| `day_sell_qty`, `day_sell_amt`, `day_sell_avg_price` | integer | Sells executed today. |
| `cf_buy_qty`, `cf_buy_amt`, `cf_buy_avg_price` | integer | The position carried forward from previous days, when it came in long. |
| `cf_sell_qty`, `cf_sell_amt`, `cf_sell_avg_price` | integer | The carried-forward position, when it came in short. |
| `open_buy_qty`, `open_buy_amt`, `open_buy_avg_price` | integer | The current net open position, when net long: the absolute net quantity at `net_avg_price`. |
| `open_sell_qty`, `open_sell_amt`, `open_sell_avg_price` | integer | The current net open position, when net short. |
| `net_qty` | integer | Signed: positive for long, negative for short. Carried-forward plus today's net. |
| `net_avg_price` | integer | Paise. Weighted across the carried-forward position and today's net when they point the same way; otherwise the larger side's average. |
| `total_buy_qty`, `total_buy_amt`, `total_buy_avg_price` | integer | Carried-forward plus today's buys. |
| `total_sell_qty`, `total_sell_amt`, `total_sell_avg_price` | integer | Carried-forward plus today's sells. |
| `realised_pnl` | integer | Realised P&L, paise. |
| `last_modified_at` | integer | Epoch ms of the last change to this position. |

---

### GET /v1/holdings — Holdings

**Scope:** `holdings.read`

Your demat holdings, one entry per ISIN. Today's
delivery-product activity is folded in: `net_qty` adjusts the holding for
today's delivery buys/sells, and the nested `position` object carries the day's
delivery totals for the same ISIN. Returns an empty array when you hold
nothing. An ISIN first bought for delivery today appears with zero settled
quantities (`t1_qty`, `dp_qty`, `holding_qty` all `0`) and today's buys in
`net_qty`/`position`.

#### Response — `200 OK`

```json
{
  "holdings": [
    {
      "isin": "INE002A01018",
      "instrument_ids": [12027, 725069],
      "t1_qty": 0,
      "dp_qty": 10,
      "holding_qty": 10,
      "holding_avg_price": 245050,
      "authorised_qty": 10,
      "net_qty": 15,
      "net_avg_price": 245100,
      "position": {
        "net_qty": 5,
        "net_avg_price": 245200,
        "buy_qty": 5,
        "buy_avg_price": 245200,
        "sell_qty": 0,
        "sell_avg_price": 0
      },
      "last_modified_at": 1747798205890
    }
  ]
}
```

| Field | Type | Notes |
|---|---|---|
| `isin` | string | The holding key. Matches the `isin` column of the scrip master. |
| `instrument_ids` | integer[] | Scrip-master `id` of every listing of this ISIN (e.g. NSE + BSE), ascending. Use with the Market Data APIs. |
| `t1_qty` | integer | Units bought but not yet settled into demat (T+1). |
| `dp_qty` | integer | Units settled in the demat account. |
| `holding_qty` | integer | `t1_qty + dp_qty`. |
| `holding_avg_price` | integer | Paise. Quantity-weighted average of the T1 and demat average prices; `0` when `holding_qty` is `0`. |
| `authorised_qty` | integer | Units EDIS-authorised for sale in the current trading session (or the next one when the market is closed). Delivery sells beyond this are rejected. |
| `net_qty` | integer | `holding_qty` adjusted for today's delivery buys/sells. |
| `net_avg_price` | integer | Paise. Re-weighted with today's delivery buys when today's delivery net is positive; otherwise equals `holding_avg_price`. |
| `position` | object | Today's delivery-product activity for the same ISIN, summed across exchanges. `position.net_qty` is signed (negative when today's delivery sells exceed buys); `*_avg_price` are paise. |
| `last_modified_at` | integer | Epoch ms of the last delivery trade today; `0` when there is none. |

No valuation/LTP fields are included — fetch prices via
[`GET /v1/marketdata/ltp`](#get-v1marketdataltp--last-traded-price) with the
returned `instrument_ids`.

---

