---
title: "Cost basis for the caller’s active wallet: holdings valued at read time, realized disposals, unmatched disposals, and skipped legs"
method: GET
path: "/users/{id}/cost-basis"
tags: ["cost-basis"]
---

# Cost basis for the caller’s active wallet: holdings valued at read time, realized disposals, unmatched disposals, and skipped legs

`GET /users/{id}/cost-basis`

## Path parameters

- `id` number, required

## Query parameters

- `method` 'fifo' | 'lifo'

## Response `200`

Cost basis, derived per request. Every USD field is a decimal string or null; null means unknown and is never zero.

- CostBasisResponseDto
  - `method` 'fifo' | 'lifo', required — The lot method that produced this result.
  - `holdings` CostBasisHoldingDto[], required
    - `chainId` number, required
    - `assetAddress` string, required — Lowercase. Zero address for a native asset.
    - `symbol` object, nullable, required
    - `decimals` object, nullable, required
    - `quantity` string, required — Raw units held. String — can exceed 2^53.
    - `costBasisUsd` string, required — Cost of the lots whose basis is known. A PARTIAL sum whenever `hasUnknownBasis` is true — unpriced lots contribute nothing rather than zero.
    - `averageUnitCostUsd` string, nullable, required — Cost per whole unit. Decimal string, or null for UNKNOWN. Never zero-for-unknown. Null when nothing is held, or when any lot's basis is unknown — an average over a partial sum invites being multiplied back out.
    - `hasEstimatedBasis` boolean, required — Any open lot's basis is a market estimate.
    - `hasUnknownBasis` boolean, required — Any open lot was acquired with no price at all, so the cost is incomplete. Gates `averageUnitCostUsd` and `unrealizedGainLossUsd`.
    - `lotCount` number, required
    - `currentUnitPriceUsd` string, nullable, required — The unit price the valuation used. Decimal string, or null for UNKNOWN. Never zero-for-unknown.
    - `valuationPriceSource` 'registry' | 'registry_stale' | 'none', required — `registry_stale` is a bounded last-known price; `none` always accompanies a null valuation.
    - `marketValueUsd` string, nullable, required — quantity × currentUnitPriceUsd. Decimal string, or null for UNKNOWN. Never zero-for-unknown.
    - `unrealizedGainLossUsd` string, nullable, required — marketValueUsd − costBasisUsd. Decimal string, or null for UNKNOWN. Never zero-for-unknown. Also null when `hasUnknownBasis` — an unrealized figure against a partial basis reports the missing lots' whole value as gain.
  - `disposals` CostBasisDisposalDto[], required
    - `actionId` string, required
    - `actionType` string, required
    - `chainId` number, required
    - `assetAddress` string, required
    - `symbol` object, nullable, required
    - `quantity` string, required — Raw units disposed from this lot.
    - `proceedsUsd` string, nullable, required — Decimal string, or null for UNKNOWN. Never zero-for-unknown. Null when the disposal leg carried no USD value at ingest.
    - `costBasisUsd` string, nullable, required — Decimal string, or null for UNKNOWN. Never zero-for-unknown. Null when the lot behind it was opened with no price.
    - `realizedGainLossUsd` string, nullable, required — Proceeds minus basis; negative is a loss. Decimal string, or null for UNKNOWN. Never zero-for-unknown. Null when either side is unknown.
    - `acquiredAt` number, required — Unix seconds.
    - `disposedAt` number, required — Unix seconds.
    - `longTerm` boolean, required — Over a year held. Jurisdiction-specific — a hint, not advice.
    - `estimatedBasis` boolean, required — The lot's basis was a market estimate.
    - `basisUnknown` boolean, required — The lot had no acquisition price, so basis and gain are null. Summing gains without checking this silently understates the total.
  - `unmatchedDisposals` CostBasisUnmatchedDisposalDto[], required — Returned verbatim. A non-empty list is a real gap in the history, not a failure of the request.
    - `actionId` string, required
    - `chainId` number, required
    - `assetAddress` string, required
    - `symbol` object, nullable, required
    - `quantity` string, required — Raw units with no lot behind them.
    - `proceedsUsd` string, nullable, required — Decimal string, or null for UNKNOWN. Never zero-for-unknown.
    - `disposedAt` number, required — Unix seconds.
    - `reason` 'no_open_lots' | 'insufficient_lots', required
  - `skipped` CostBasisSkippedDto[], required
    - `legId` string, required
    - `reason` string, required — Why it was dropped — e.g. the action was not completed.

## Other responses

- `401` — Unauthorized
- `403` — Forbidden — can only request own cost basis
- `422` — History exceeds the 50000-leg matching limit. Raised rather than truncated: a partial history yields wrong numbers, not partial ones.

---

[API](https://skmtc.dev/dre/apis/dre-api.md) · [All operations](https://skmtc.dev/dre/apis/dre-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/dre/dre-api/revisions/5d14beb9482b/schema)
