Skip to main content
Authenticated API

This endpoint requires a valid JWT Bearer token. Accessible via the API gateway at /v1/commerce/*.

Inventory API

Track inventory levels and manage stock across locations.

Authentication Required

All endpoints require a valid Bearer token. See Authentication for details.

Overview

AttributeValue
Base Path/api/v1/inventory
AuthenticationBearer Token
Required Rolespos_staff, manager, chef, bartender, server, host, cashier, restaurant_staff, inventory_manager, restaurant_manager, tenant_admin, platform_admin, system_admin, super_admin

The Inventory API provides:

FeatureDescription
Stock TrackingReal-time inventory levels
Par LevelsMinimum stock thresholds
Auto-DeductionReduce stock on orders
Waste TrackingLog and analyze waste
Reorder AlertsLow stock notifications
Purchase OrdersVendor ordering

Get Inventory

Request

GET /api/v1/inventory?
location_id=loc-xyz789&
category=proteins&
below_par=true
Authorization: Bearer {access_token}

Response

{
"items": [
{
"id": "inv-chicken",
"name": "Chicken Breast",
"sku": "PROT-001",
"category": "proteins",
"unit": "lb",
"quantity": 25.5,
"par_level": 50,
"reorder_point": 30,
"cost_per_unit": 4.50,
"total_value": 114.75,
"status": "low",
"last_count": "2026-01-17T22:00:00Z",
"supplier": {
"id": "sup-sysco",
"name": "Sysco"
}
}
],
"summary": {
"total_items": 1,
"below_par": 1,
"total_value": 114.75
}
}

Update Stock Level

Request

PUT /api/v1/inventory/{item_id}/quantity
Authorization: Bearer {access_token}
Content-Type: application/json
{
"quantity": 75.0,
"reason": "delivery_received",
"reference": "PO-12345",
"notes": "Weekly Sysco delivery"
}

Adjustment Reasons

ReasonDescription
delivery_receivedNew stock delivered
manual_countPhysical count adjustment
wasteItems wasted/spoiled
theftSuspected theft
transfer_inTransfer from another location
transfer_outTransfer to another location

Response

{
"id": "inv-chicken",
"previous_quantity": 25.5,
"new_quantity": 75.0,
"adjustment": 49.5,
"reason": "delivery_received",
"adjusted_by": "user-456",
"adjusted_at": "2026-01-18T08:00:00Z"
}

Create Inventory Item

Request

POST /api/v1/inventory
Authorization: Bearer {access_token}
Content-Type: application/json
{
"location_id": "loc-xyz789",
"name": "Ground Beef",
"sku": "PROT-002",
"category": "proteins",
"unit": "lb",
"quantity": 100,
"par_level": 80,
"reorder_point": 40,
"reorder_quantity": 100,
"cost_per_unit": 5.25,
"supplier_id": "sup-sysco",
"storage_location": "Walk-in Cooler",
"expiry_tracking": true
}

Set Par Levels

Request

PUT /api/v1/inventory/{item_id}/par
Authorization: Bearer {access_token}
Content-Type: application/json
{
"par_level": 60,
"reorder_point": 35,
"reorder_quantity": 80
}

Log Waste

Request

POST /api/v1/inventory/{item_id}/waste
Authorization: Bearer {access_token}
Content-Type: application/json
{
"quantity": 5.0,
"reason": "spoiled",
"notes": "Found expired in walk-in"
}

Waste Reasons

ReasonDescription
spoiledItem expired or spoiled
damagedPhysical damage
overproductionMade too much
customer_returnReturned by customer
quality_issueFailed quality check

Response

{
"id": "waste-001",
"item_id": "inv-chicken",
"quantity": 5.0,
"value_lost": 22.50,
"reason": "spoiled",
"logged_by": "user-456",
"logged_at": "2026-01-18T08:30:00Z"
}

Inventory Count

Start Count Session

POST /api/v1/inventory/counts
Authorization: Bearer {access_token}
Content-Type: application/json
{
"location_id": "loc-xyz789",
"type": "full",
"categories": ["proteins", "produce", "dairy"]
}

Submit Counts

POST /api/v1/inventory/counts/{count_id}/items
Authorization: Bearer {access_token}
Content-Type: application/json
{
"counts": [
{"item_id": "inv-chicken", "counted_quantity": 72.5},
{"item_id": "inv-beef", "counted_quantity": 95.0},
{"item_id": "inv-lettuce", "counted_quantity": 20}
]
}

Complete Count

POST /api/v1/inventory/counts/{count_id}/complete
Authorization: Bearer {access_token}

Response

{
"id": "count-001",
"status": "completed",
"items_counted": 45,
"variances": [
{
"item": "Chicken Breast",
"expected": 75.0,
"counted": 72.5,
"variance": -2.5,
"variance_value": -11.25
}
],
"total_variance_value": -45.50,
"completed_at": "2026-01-18T23:00:00Z"
}

Purchase Orders

Create Purchase Order

POST /api/v1/inventory/purchase-orders
Authorization: Bearer {access_token}
Content-Type: application/json
{
"location_id": "loc-xyz789",
"supplier_id": "sup-sysco",
"delivery_date": "2026-01-20",
"items": [
{"item_id": "inv-chicken", "quantity": 100, "unit_cost": 4.50},
{"item_id": "inv-beef", "quantity": 80, "unit_cost": 5.25}
],
"notes": "Rush order"
}

Response

{
"id": "po-12345",
"status": "pending",
"supplier": "Sysco",
"items": 2,
"total": 870.00,
"delivery_date": "2026-01-20",
"created_at": "2026-01-18T09:00:00Z"
}

Receive Purchase Order

POST /api/v1/inventory/purchase-orders/{po_id}/receive
Authorization: Bearer {access_token}
Content-Type: application/json
{
"items": [
{"item_id": "inv-chicken", "received_quantity": 100},
{"item_id": "inv-beef", "received_quantity": 75, "notes": "Short 5 lbs"}
]
}

Supplier Management

List Suppliers

GET /api/v1/inventory/suppliers?location_id=loc-xyz789
Authorization: Bearer {access_token}

Response

{
"suppliers": [
{
"id": "sup-sysco",
"name": "Sysco",
"contact_name": "John Smith",
"phone": "555-123-4567",
"email": "orders@sysco.com",
"lead_time_days": 2,
"minimum_order": 200.00,
"items_supplied": 45
}
]
}

Recipe Costing

Get Item Cost

GET /api/v1/inventory/recipes/{menu_item_id}/cost
Authorization: Bearer {access_token}

Response

{
"menu_item": "Classic Burger",
"sell_price": 14.99,
"ingredients": [
{"name": "Beef Patty", "quantity": 0.33, "unit": "lb", "cost": 1.73},
{"name": "Bun", "quantity": 1, "unit": "each", "cost": 0.35},
{"name": "Lettuce", "quantity": 0.05, "unit": "lb", "cost": 0.08},
{"name": "Tomato", "quantity": 0.1, "unit": "lb", "cost": 0.15}
],
"total_cost": 2.31,
"food_cost_percentage": 15.4,
"margin": 12.68
}

Alerts & Notifications

Automatic Stock Deduction

When orders are placed, inventory is automatically deducted based on recipe mappings. Items that drop below their reorder_point will trigger inventory.low_stock webhook events and push notifications to managers. Configure par_level and reorder_point per item to control alert thresholds.

Low Stock Alert

{
"type": "inventory.low_stock",
"item": {
"id": "inv-chicken",
"name": "Chicken Breast",
"quantity": 25.5,
"par_level": 50
},
"location": "Main Street Location",
"timestamp": "2026-01-18T10:00:00Z"
}

Error Responses

Insufficient Stock (400)

{
"error": {
"code": "INSUFFICIENT_STOCK",
"message": "Not enough Chicken Breast in stock",
"available": 25.5,
"requested": 30
}
}