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
| Attribute | Value |
|---|---|
| Base Path | /api/v1/inventory |
| Authentication | Bearer Token |
| Required Roles | pos_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:
| Feature | Description |
|---|---|
| Stock Tracking | Real-time inventory levels |
| Par Levels | Minimum stock thresholds |
| Auto-Deduction | Reduce stock on orders |
| Waste Tracking | Log and analyze waste |
| Reorder Alerts | Low stock notifications |
| Purchase Orders | Vendor 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
| Reason | Description |
|---|---|
delivery_received | New stock delivered |
manual_count | Physical count adjustment |
waste | Items wasted/spoiled |
theft | Suspected theft |
transfer_in | Transfer from another location |
transfer_out | Transfer 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
| Reason | Description |
|---|---|
spoiled | Item expired or spoiled |
damaged | Physical damage |
overproduction | Made too much |
customer_return | Returned by customer |
quality_issue | Failed 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
}
}
Related Documentation
- Menu API - Menu management
- Orders API - Order processing