Products

Manage your product catalog — create, update, search, and track inventory. All product endpoints require authentication.

Price Format

All prices are stored as integers in cents. For example, 1499 represents $14.99. This avoids floating-point precision issues in financial calculations.

GET/api/v1/products

List all products for the current vendor

Query Parameters

ParameterTypeDescription
pagenumberPage number (default: 1)
limitnumberItems per page (default: 20, max: 100)
searchstringSearch by name, SKU, or barcode
category_iduuidFilter by category
in_stockbooleanFilter to only in-stock items
sortstringSort field: name, price, created_at, stock
orderstringSort order: ASC or DESC

Response

[
  {
    "id": "uuid",
    "name": "Organic Coffee Beans",
    "sku": "COF-001",
    "barcode": "1234567890123",
    "price": 1499,
    "cost": 800,
    "stock": 150,
    "low_stock_threshold": 20,
    "category_id": "uuid",
    "category": { "id": "uuid", "name": "Beverages" },
    "tax_rate": 0,
    "unit": "bag",
    "image": "/uploads/products/cof-001.jpg",
    "is_active": true,
    "created_at": "2025-01-15T10:00:00Z",
    "updated_at": "2025-05-10T14:30:00Z"
  }
]

Prices are in cents (integer). Divide by 100 for display. Results are paginated.

GET/api/v1/products/:id

Get a single product by ID

Response

{
  "id": "uuid",
  "name": "Organic Coffee Beans",
  "sku": "COF-001",
  "barcode": "1234567890123",
  "price": 1499,
  "cost": 800,
  "stock": 150,
  "low_stock_threshold": 20,
  "category_id": "uuid",
  "category": { "id": "uuid", "name": "Beverages" },
  "variants": [
    { "id": "uuid", "name": "250g", "price": 1499, "sku": "COF-001-250" },
    { "id": "uuid", "name": "500g", "price": 2499, "sku": "COF-001-500" }
  ],
  "modifiers": [],
  "tax_rate": 0,
  "unit": "bag",
  "image": "/uploads/products/cof-001.jpg",
  "is_active": true,
  "created_at": "2025-01-15T10:00:00Z"
}

Includes full variant and modifier details. Returns 404 if not found.

POST/api/v1/products

Create a new product

Request Body

{
  "name": "Organic Coffee Beans",
  "sku": "COF-001",
  "barcode": "1234567890123",
  "price": 1499,
  "cost": 800,
  "stock": 150,
  "low_stock_threshold": 20,
  "category_id": "uuid",
  "tax_rate": 0,
  "unit": "bag",
  "is_active": true
}

Response

{
  "id": "uuid",
  "name": "Organic Coffee Beans",
  "sku": "COF-001",
  ...
}

Required fields: name, price. All other fields are optional. SKU must be unique within the vendor.

PUT/api/v1/products/:id

Update an existing product

Request Body

{
  "name": "Updated Product Name",
  "price": 1599,
  "stock": 200
}

Response

{
  "id": "uuid",
  "name": "Updated Product Name",
  "price": 1599,
  "stock": 200,
  ...
}

Partial updates supported — only include the fields you want to change.

DELETE/api/v1/products/:id

Delete a product

Response

{
  "message": "Product deleted successfully"
}

Soft-deletes the product. Products with existing sales history are deactivated rather than deleted.

POST/api/v1/products/:id/adjust-stock

Adjust product stock level

Request Body

{
  "quantity": 50,
  "type": "add",
  "reason": "New shipment received"
}

Response

{
  "id": "uuid",
  "name": "Organic Coffee Beans",
  "stock": 200,
  "adjustment": {
    "quantity": 50,
    "type": "add",
    "reason": "New shipment received",
    "created_at": "2025-05-18T12:00:00Z"
  }
}

Type can be "add" or "subtract". Creates a stock adjustment record for auditing.

Product Model

FieldTypeDescription
iduuidUnique identifier
namestringProduct name
skustring?Stock keeping unit (unique per vendor)
barcodestring?Barcode (EAN-13, UPC-A, etc.)
priceintegerSelling price in cents
costinteger?Cost price in cents
stockintegerCurrent stock level
low_stock_thresholdintegerAlert when stock falls below this
category_iduuid?Category reference
tax_ratedecimalTax rate (0 to 1, e.g. 0.07 = 7%)
unitstringUnit of measure (piece, kg, bag, etc.)
imagestring?Image URL
is_activebooleanWhether product is available for sale