Docs navigation
Home / Docs / Activity history & stock timeline

Activity history & stock timeline

The per-product timeline of stock movements and record changes — what appears, how the running balance works, who did what, and the API behind it.

Every product, variant, assembly, bundle, work order, and warehouse stock row has an Activity History: stock movements and record changes on one timeline, newest first, with a running on-hand balance. It’s the answer to “why is this number what it is.”

Where it is

  • Product page → the Activity History card near the bottom. Also on variant, assembly, bundle, and work-order pages, and as Movement history in the warehouse stock item sheet.
  • The header reads “N stock movements · M changes”, with one filter: All activity / Stock movements / Changes only.
  • Each row: timestamp, an event badge, the quantity (+12 / −3), the balance before → after, a one-line summary. Expand a row for location, SKU, reason, the reference it came from (linked when it’s an order, PO, work order, or invoice), who did it, and per-field old → new values.

Stock movements

Every change to on-hand is a movement of one of these kinds:

MovementWritten by
RECEIPTReceiving a purchase order
SALEMarking an order fulfilled (this is the only thing a sale writes — status changes don’t)
ADJUSTMENTManual adjustments, with a reason
COUNTApplying a stock count — including the zeroing pass of a full count
TRANSFER_OUT / TRANSFER_INWarehouse transfers and bin moves, as a matched pair
BUILD_CONSUME / BUILD_PRODUCECompleting a work order: parts out, finished units in
UNBUILD_CONSUME / UNBUILD_PRODUCEUnbuilding: the reverse

The running balance

The before → after figures are the SKU’s on-hand in that warehouse, across all its bins. Bins partition where stock sits; the balance is the warehouse total, so a bin move shows as two movements that net to zero.

The balance is anchored to the present: the newest row’s after equals today’s on-hand, and history is walked backwards from there. Stock that existed before movement tracking began therefore shows as a constant offset at the start of the timeline rather than as a phantom receipt.

Record changes

Alongside movements, the timeline shows structural events on the product and its variants: created, promoted from a source SKU, merged, listed on a channel, type converted, archived or restored, trashed or restored, bill-of-materials edits, and warehouse events such as shipped_short (an order shipped beyond counted stock) and inventory_received.

What it deliberately does not show: ordinary field edits — a price, name, or SKU change on the product form — and import or channel-sync events, which are logged against the source or channel rather than the product. For “who changed this price,” see the price-change history on the channel instead.

Who did it

Each activity entry records how it was made:

Shown asMeaning
A user’s emailA signed-in person, in the admin or through a connector authorized as that person (for example Claude via the Foundry connector)
API keyA fims_* API key — an integration, an automation, or Claude connected with a key
Webhook (incoming from a channel)Triggered by a channel’s webhook, such as a new order
System (automatic)A scheduled job — reconciles, auto-listing, nightly rollups

Entries written before attribution existed have no actor and show nothing on the By line. Stock movements themselves carry the reason and reference, not an actor — the actor is on the adjustment or count event that produced them.

API

GET /activity-logs/timeline returns the same merged feed. Scope it with one of productId, variantId, warehouseId, or binId (binId=unassigned for stock with no bin), or by referenceType + referenceId to see everything one order or work order caused. kind=all|stock|activity mirrors the UI filter; types= narrows to specific movement kinds; limit (max 100) and offset page through. Each entry is kind: "movement" (quantity, balanceBefore, balanceAfter, variant, warehouse, bin, reference) or kind: "activity" (action, changes, actor). Requires activity.read; movement rows additionally require warehouses.read, which every human role has.

For an org-wide view rather than one product’s, the Activity page in the sidebar lists everything with entity filters, and the Audit log covers security-relevant events.