Skip to main content
All endpoints require an Authorization: Bearer <token> header.

Endpoint

POST /api/stock-movements

Request body

productId
string
required
UUID of the product the movement applies to.
type
string
required
Direction of the movement. Must be "IN" (stock received) or "OUT" (stock dispatched).
quantity
number
required
Number of units to move.
reason
string
Human-readable explanation for the movement (e.g., "received from supplier", "sold to customer").
The reason field is optional but recommended. It is stored on the movement record and is useful for auditing inventory changes over time.

Response

Returns the created stock movement record.
id
string
required
Unique identifier for the stock movement (UUID).
productId
string
required
UUID of the product this movement applies to.
type
string
required
Direction of the movement: "IN" or "OUT".
quantity
number
required
Number of units moved.
reason
string
Explanation for the movement. null if not provided.
tenantId
string
required
UUID of the tenant this movement belongs to.
createdAt
string
required
ISO 8601 timestamp of when the movement was recorded.
updatedAt
string
required
ISO 8601 timestamp of when the movement was last updated.

Side effects: inventory update

Recording a movement also updates the corresponding inventory quantity automatically. The response only contains the movement record — query GET /api/inventory to see the updated quantity.
Movement typeEffect on inventory.quantity
INinventory.quantity += quantity
OUTinventory.quantity -= quantity
This is the code that performs the update in stock-movements.ts:
// Update inventory
if (type === "IN") {
  await prisma.inventory.update({
    where: { productId },
    data: { quantity: { increment: quantity } },
  })
} else if (type === "OUT") {
  await prisma.inventory.update({
    where: { productId },
    data: { quantity: { decrement: quantity } },
  })
}
Outbound movements (type: "OUT") can push inventory.quantity below zero. The current implementation has no guard against negative stock. Validate that sufficient stock is available before recording an OUT movement.

Examples

curl --request POST \
  --url http://localhost:5000/api/stock-movements \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "productId": "d4e5f6a7-b8c9-0123-defa-456789012345",
    "type": "IN",
    "quantity": 50,
    "reason": "received from supplier"
  }'

Example response

{
  "id": "e5f6a7b8-c9d0-1234-efab-567890123456",
  "productId": "d4e5f6a7-b8c9-0123-defa-456789012345",
  "type": "IN",
  "quantity": 50,
  "reason": "received from supplier",
  "tenantId": "f0e1d2c3-b4a5-6789-cdef-012345678901",
  "createdAt": "2024-03-18T14:00:00.000Z",
  "updatedAt": "2024-03-18T14:00:00.000Z"
}

Build docs developers (and LLMs) love