---
title: "Get a stockchange by ID"
method: GET
path: "/v1/stock-change/{id}"
tags: ["StockChange"]
---

# Get a stockchange by ID

`GET /v1/stock-change/{id}`

## Request

- Base URL: `https://api.finalpos.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.finalpos.com/v1/stock-change/{id}`
- Auth: API key in header `x-api-key`

Retrieves a single stockchange by its unique identifier.

## Path parameters

- `id` string, required

## Response `200`

The stockchange has been successfully retrieved.

- StockChangeResponseDto
  - `id` string: Unique identifier for the StockChange.
  - `createdAt` string, date-time: Timestamp when the StockChange was created.
  - `updatedAt` string, date-time: Timestamp when the StockChange was last updated.
  - `companyId` string: Company ID associated with the StockChange.
  - `userId` string: User ID who made the stock change.
  - `source` string: Source of the Stock Change Event.
  - `productId` string: Product ID affected by the stock change.
  - `variantId` string: Variant ID affected by the stock change.
  - `variantName` string: How `variantId` read on the day — attribute values or SKU, frozen at write. A rename or a deletion must not rewrite the ledger; the id above stays so the variant is findable historically. Absent on rows written before names were frozen — resolve those by id.
  - `outletId` string: Outlet ID where the stock change occurred.
  - `baseAction` 'ADD' | 'REMOVE' | 'RECOUNT' | 'SKIP': Base action type for the stock change.
  - `specificAction` 'STOCK_RECEIVED' | 'INVENTORY_RECOUNT' | 'DAMAGE' | 'THEFT' | 'LOSS' | 'RESTOCK_RETURN' | 'REFUND_RESTOCK_RETURN' | 'REFUND_DAMAGE' | 'SALE' | 'COMPOSED_FOR_SALE' | 'UNIT_FAMILY_CHANGED' | 'TRANSFER' | 'BULK_RECOUNT' | 'APPLIED_FROM_WOO' | 'PO_RECEIVED' | 'EXTERNAL_SALE' | 'EXTERNAL_RESTOCK' | 'CUSTOM': Specific action type for the stock change.
  - `customActionId` string: The company action used when `specificAction` is CUSTOM.
  - `customActionName` string: How the custom action was named on the day — renaming it later does not rewrite history.
  - `quantity` number: How much the shelf moved, in WHOLE BASE UNITS of the family — grams, millilitres, pieces. Not in `unitId`: that names the unit the movement was keyed in, and the two differ by the unit's ratio. `unitQuantity` is the same movement as the person keyed it.
  - `updatedQuantity` number: On-hand level after the change, in the SAME base units as `quantity` — again not in `unitId`. It has no keyed counterpart: a reader renders it by dividing with the ratio, so unlike `unitQuantity` this figure does restate if the unit is later re-rated.
  - `unitId` string: Unit this movement was keyed in — the one the person saw on screen. Differs from what moved when a variant draws from a sibling pool: three burgers leave a kilogram pool. Absent on entries written before units existed, which are pieces.
  - `unitQuantity` number: The amount as keyed, in `unitId` — frozen, never recomputed. `quantity` stays in base units for arithmetic; this is what the movement meant to the person who made it. Dividing the base amount by the unit ratio at read time would rewrite history: receive 5 burgers today, double the burger's weight tomorrow, and yesterday's entry would claim 2.5.
  - `viaVariantId` string: The variant the movement was keyed through when it is not `variantId` — the Glass that was sold when a Bottle pool drains. The row lands on the pool owner, whose balance moved; without this the ledger never names what was actually sold. Absent on direct movements.
  - `viaVariantName` string: How `viaVariantId` read on the day — same freeze as `variantName`.
  - `compositeProductId` string: The composite this item was sold (or refunded) in — "Sold in Combo #1" (FT-83, D26). Absent on every other movement.
  - `compositeName` string: How that composite read on the day — same freeze as `variantName`.
  - `idempotencyKey` string: Caller-supplied key that lets the writer safely retry a stock mutation. The unique index drops duplicates so the same logical change is not applied twice. Keys prefixed `sarnia:` are RESERVED for the FinalPOS sync lane — its outbound subscriber skips those events as its own writes, so external callers must not use that prefix or their movements will not sync to connected platforms.

## Other responses

- `400`: Bad request. Returns validation errors or other request-related errors.
- `404`: The stockchange was not found. The resource was not found.

---

[API](https://skmtc.dev/finalpos/apis/final-pos-public-api.md) · [All operations](https://skmtc.dev/finalpos/apis/final-pos-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/finalpos/apis/final-pos-public-api/revisions/6a6842dcb479?raw)
