Documentation

Inventory Routes

These pages document the live inventory endpoints mounted under /api/inventory.

GET /api/inventory/movements/types

Returns the stock movement type catalog used by the inventory operation and movement logging interfaces.

Request
GET /api/inventory/movements/types

Response 200
{
  "types": [
    {
      "key": "STOCK_IN",
      "label": "Receive Stock"
    },
    {
      "key": "TRANSFER_OUT",
      "label": "Transfer Out"
    }
  ]
}

GET /api/inventory

Lists inventory summaries for products in the authenticated account's organization.

Request
GET /api/inventory

Response 200
{
  "inventory": [
    {
      "productId": "uuid",
      "ownerId": "uuid",
      "productName": "Widget A",
      "sku": "WIDGET-A",
      "unitCost": 19.99,
      "quantity": 25,
      "valuation": 499.75,
      "updatedAt": "2026-03-29T12:00:00.000Z"
    }
  ]
}

GET /api/inventory/summary

Returns the current stock snapshot for products in the authenticated account's organization.

Request
GET /api/inventory/summary

Response 200
{
  "inventory": [
    {
      "productId": "uuid",
      "ownerId": "uuid",
      "productName": "Widget A",
      "sku": "WIDGET-A",
      "unitCost": 19.99,
      "quantity": 25,
      "valuation": 499.75,
      "updatedAt": "2026-03-29T12:00:00.000Z"
    }
  ]
}

GET /api/inventory/:productId

Returns the inventory summary for one product in the authenticated account's organization.

Request
GET /api/inventory/11111111-1111-1111-1111-111111111111

Response 200
{
  "inventory": {
    "productId": "uuid",
    "ownerId": "uuid",
    "productName": "Widget A",
    "sku": "WIDGET-A",
    "unitCost": 19.99,
    "quantity": 25,
    "valuation": 499.75,
    "updatedAt": "2026-03-29T12:00:00.000Z"
  }
}

POST /api/inventory

Creates the 1:1 inventory balance row for a product.

Request
POST /api/inventory
Content-Type: application/json

{
  "productId": "uuid",
  "quantity": 25
}

Response 201
{
  "inventory": {
    "productId": "uuid",
    "ownerId": "uuid",
    "productName": "Widget A",
    "sku": "WIDGET-A",
    "unitCost": 19.99,
    "quantity": 25,
    "valuation": 499.75,
    "updatedAt": "2026-03-29T12:00:00.000Z"
  }
}

PATCH /api/inventory/:productId

Updates the stored inventory quantity for a product.

Request
PATCH /api/inventory/11111111-1111-1111-1111-111111111111
Content-Type: application/json

{
  "quantity": 30
}

Response 200
{
  "inventory": {
    "productId": "uuid",
    "ownerId": "uuid",
    "productName": "Widget A",
    "sku": "WIDGET-A",
    "unitCost": 19.99,
    "quantity": 30,
    "valuation": 599.7,
    "updatedAt": "2026-03-29T12:00:00.000Z"
  }
}

DELETE /api/inventory/:productId

Deletes the stored inventory balance row for a product.

Request
DELETE /api/inventory/11111111-1111-1111-1111-111111111111

Response 200
{
  "inventory": {
    "productId": "uuid",
    "ownerId": "uuid",
    "productName": "Widget A",
    "sku": "WIDGET-A",
    "unitCost": 19.99,
    "quantity": 25,
    "valuation": 499.75,
    "updatedAt": "2026-03-29T12:00:00.000Z"
  }
}

POST /api/inventory/adjustments

Records a manual inventory adjustment. The backend derives the correct ADJUSTMENT_* movement type from the provided direction.

Request
POST /api/inventory/adjustments
Content-Type: application/json

{
  "productId": "uuid",
  "direction": "increase",
  "quantity": 10,
  "reason": "Cycle count reconciliation"
}

Response 201
{
  "movement": {
    "id": "uuid",
    "ownerId": "uuid",
    "actorId": "uuid",
    "productId": "uuid",
    "productName": "Widget A",
    "type": "ADJUSTMENT_INCREASE",
    "quantity": 10,
    "reason": "Cycle count reconciliation",
    "createdAt": "2026-03-29T12:00:00.000Z"
  },
  "inventory": {
    "productId": "uuid",
    "ownerId": "uuid",
    "productName": "Widget A",
    "sku": "WIDGET-A",
    "unitCost": 19.99,
    "quantity": 25,
    "valuation": 499.75,
    "updatedAt": "2026-03-29T12:00:00.000Z"
  }
}

Notes
- Use this route for inventory adjustment and reconciliation screens.
- Send direction, not raw ADJUSTMENT_* movement types.
- The backend derives actorId from the authenticated account.
- The backend requires and persists a human-entered adjustment reason.

GET /api/inventory/movements

Lists stock movement history with optional filters and pagination.

Request
GET /api/inventory/movements?limit=25&offset=0&type=STOCK_IN&productId=uuid&actorId=uuid

Response 200
{
  "movements": [
    {
      "id": "uuid",
      "ownerId": "uuid",
      "actorId": "uuid",
      "productId": "uuid",
      "productName": "Widget A",
      "type": "STOCK_IN",
      "quantity": 10,
      "reason": "Overflow transfer from warehouse A",
      "createdAt": "2026-03-29T12:00:00.000Z"
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1,
    "hasMore": false
  }
}

Supported filters
- limit (default 50, max 200)
- offset (default 0)
- productId
- actorId
- type
- createdFrom
- createdTo

POST /api/inventory/movements

Records a stock movement and updates inventory quantities. The backend derives actorId from the authenticated account. Prefer POST /api/inventory/adjustments for manual adjustment UIs.

Request
POST /api/inventory/movements
Content-Type: application/json

{
  "productId": "uuid",
  "type": "STOCK_IN",
  "quantity": 10,
  "reason": "Overflow transfer from warehouse A"
}

Response 201
{
  "movement": {
    "id": "uuid",
    "ownerId": "uuid",
    "actorId": "uuid",
    "productId": "uuid",
    "productName": "Widget A",
    "type": "STOCK_IN",
    "quantity": 10,
    "reason": "Overflow transfer from warehouse A",
    "createdAt": "2026-03-29T12:00:00.000Z"
  },
  "inventory": {
    "productId": "uuid",
    "ownerId": "uuid",
    "productName": "Widget A",
    "sku": "WIDGET-A",
    "unitCost": 19.99,
    "quantity": 25,
    "valuation": 499.75,
    "updatedAt": "2026-03-29T12:00:00.000Z"
  }
}

Notes
- Generic stock movement reasons are optional but persisted when provided.