---
title: "Records one purchase or sale as a lot. Pass `optionContract` with the OCC symbol to record an option contract, or omit it for shares. `quantity` is signed — negative for a short sale or a written option — and `costPerUnit` is always a positive price per share, because the direction is carried by the sign of the quantity alone. Repeating an identical request within a few minutes returns the lot already recorded with `deduplicated: true` and HTTP 200 instead of adding a second holding, so a retried timeout is safe."
method: POST
path: "/v1/portfolios/{id}/lots"
tags: ["Portfolios"]
---

# Records one purchase or sale as a lot. Pass \`optionContract\` with the OCC symbol to record an option contract, or omit it for shares. \`quantity\` is signed — negative for a short sale or a written option — and \`costPerUnit\` is always a positive price per share, because the direction is carried by the sign of the quantity alone. Repeating an identical request within a few minutes returns the lot already recorded with \`deduplicated: true\` and HTTP 200 instead of adding a second holding, so a retried timeout is safe.

`POST /v1/portfolios/{id}/lots`

## Request

- Base URL: `https://api.equibles.com`
- URL: `https://api.equibles.com/v1/portfolios/{id}/lots`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/equibles/apis/equibles-api/docs/v1/portfolios/:id/lots/post.ts> (a function with typed inputs; its response is checked against the schema)

## Path parameters

- `id` string, uuid, required

## Request body

- AddPortfolioLotRequest
  - `ticker` string, required: Stock ticker, or MIC:TICKER for a listing on another exchange (e.g. XPAR:AIR). For an option, the ticker of the UNDERLYING, as MIC:TICKER for a Canadian contract (e.g. XTSE:RY).
  - `optionContract` string, nullable: Optional OCC option symbol, e.g. O:AAPL260116C00250000. When present the contract's expiration, strike, type and contract size are read back from the live options data, so an unknown or expired symbol is rejected rather than stored. Omit it to record shares.
  - `quantity` number, double, required: Signed size: shares for a stock, contracts for an option. Negative for a short sale or a written (sold-to-open) option.
  - `costPerUnit` number, double, required: Price per share, always positive: paid for a long, received for a short. For an option this is the premium per share of the underlying, so a $3.20 contract is 3.20, not 320. In the currency the stock trades in, in major units: London prices in pounds, not pence.
  - `acquiredDate` string, date, required: The trade date, yyyy-MM-dd. Cannot be in the future.
  - `note` string, nullable: Optional note about this lot.
  - `fxRate` number, double, nullable: Optional broker exchange rate on the trade: units of the portfolio's currency per 1 unit of the lot's currency (the stock's trading currency; USD for an option). Only for a lot in another currency than the portfolio's. Omitted, the cost converts at the official rate on acquiredDate.

## Response `200`

OK

- PortfolioLotResponse
  - `portfolioId` string, uuid
  - `portfolioName` string, nullable
  - `deduplicated` boolean: True when this request repeated an add that had already landed, so nothing was created and the existing lot is returned. A client that retried a timed-out request reads this instead of discovering a second holding. The response is 200 rather than 201.
  - `lot` PortfolioLotDto
    - `id` string, uuid
    - `instrumentKind` string, nullable: Stock or Option.
    - `ticker` string, nullable: The listed symbol: the stock itself, or an option's underlying.
    - `exchange` string, nullable: The exchange's market identifier code (MIC, e.g. XPAR) for a listing outside the U.S.; null for a U.S. listing. Together with ticker it names the listing, e.g. XPAR:AIR.
    - `name` string, nullable
    - `occTicker` string, nullable: OCC option symbol, e.g. O:AAPL260116C00250000. Null on a stock lot.
    - `expirationDate` string, date, nullable
    - `strikePrice` number, double, nullable
    - `contractType` string, nullable: Call or Put. Null on a stock lot.
    - `sharesPerContract` integer, nullable: Shares of the underlying one contract controls — the P&L multiplier. Null on a stock lot.
    - `quantity` number, double: Signed: shares for a stock, contracts for an option; negative is short or written.
    - `costPerUnit` number, double: Price per share the lot was opened at, always positive. For an option, the premium per share of the underlying rather than per contract.
    - `costBasis` number, double, nullable
    - `currency` string, nullable: ISO 4217 code the lot's prices and own figures are in: its listing's currency.
    - `purchaseFxRate` number, double, nullable: The broker exchange rate recorded with the lot: units of purchaseFxCurrency per 1 unit of currency. Null when none was recorded.
    - `purchaseFxCurrency` string, nullable
    - `acquiredDate` string, date
    - `note` string, nullable
    - `closedDate` string, date, nullable: Set on a closed lot; null while the lot is open.
    - `closePricePerUnit` number, double, nullable
    - `marketValue` number, double, nullable: Null when this pass could not price the instrument — never a zero, which would read as a total loss.
    - `unrealizedGain` number, double, nullable
    - `realizedGain` number, double, nullable: Realized profit or loss on a closed lot; null while the lot is open.
    - `convertedCostBasis` number, double, nullable: The lot's figures in the portfolio's currency: cost at the purchase rate, value at the current rate, and a closed lot's proceeds at the official rate on its closing date. Null on a lot returned by a write, which carries no valuation.
    - `convertedMarketValue` number, double, nullable
    - `convertedUnrealizedGain` number, double, nullable
    - `convertedRealizedGain` number, double, nullable
    - `purchaseRate` PortfolioFxRateDto
      - `from` string, nullable
      - `to` string, nullable
      - `rate` number, double
      - `asOf` string, date, nullable: The official observation date. Weekly releases make a rate a few days old normal.
    - `closeRate` PortfolioFxRateDto
      - `from` string, nullable
      - `to` string, nullable
      - `rate` number, double
      - `asOf` string, date, nullable: The official observation date. Weekly releases make a rate a few days old normal.
    - `isOpen` boolean

## Other responses

- `201`: Created
- `400`: Bad Request
- `403`: Forbidden
- `404`: Not Found

---

[API](https://skmtc.dev/equibles/apis/equibles-api.md) - [All operations](https://skmtc.dev/equibles/apis/equibles-api/llms.txt) - [OpenAPI document](https://skmtc.dev/equibles/apis/equibles-api/revisions/666e06778588?raw)
