Skip to main content
Authenticated API

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

Modifiers API

Manage menu item modifiers, customization options, modifier groups, and pricing rules.

Authentication Required

All endpoints require a valid Bearer token with menu:read or menu:write scopes. See Authentication for details.

Overview

AttributeValue
Base Path/api/v1/modifiers
AuthenticationBearer Token
Required Rolespos_staff, server, restaurant_staff, restaurant_manager, kitchen, host, tenant_admin, platform_admin, system_admin, super_admin

Modifier Groups

List Modifier Groups

GET /api/v1/modifiers/groups

Query Parameters

ParameterTypeDescription
location_iduuidFilter by location
statusstringactive, inactive
typestringsingle, multiple, nested

Response

{
"modifier_groups": [
{
"id": "modgrp_001",
"name": "Steak Temperature",
"display_name": "How would you like it cooked?",
"type": "single",
"required": true,
"min_selections": 1,
"max_selections": 1,
"modifiers": [
{"id": "mod_001", "name": "Rare", "price": 0},
{"id": "mod_002", "name": "Medium Rare", "price": 0, "default": true},
{"id": "mod_003", "name": "Medium", "price": 0},
{"id": "mod_004", "name": "Medium Well", "price": 0},
{"id": "mod_005", "name": "Well Done", "price": 0}
],
"applies_to_items": 5,
"status": "active"
},
{
"id": "modgrp_002",
"name": "Pizza Toppings",
"display_name": "Add Extra Toppings",
"type": "multiple",
"required": false,
"min_selections": 0,
"max_selections": 10,
"pricing_type": "per_modifier",
"modifiers": [
{"id": "mod_010", "name": "Pepperoni", "price": 2.00},
{"id": "mod_011", "name": "Mushrooms", "price": 1.50},
{"id": "mod_012", "name": "Extra Cheese", "price": 2.50},
{"id": "mod_013", "name": "Jalapeños", "price": 1.00}
],
"applies_to_items": 8,
"status": "active"
},
{
"id": "modgrp_003",
"name": "Burger Build",
"display_name": "Build Your Burger",
"type": "nested",
"required": true,
"sub_groups": [
{
"id": "subgrp_001",
"name": "Patty",
"required": true,
"max_selections": 1
},
{
"id": "subgrp_002",
"name": "Cheese",
"required": false,
"max_selections": 2
},
{
"id": "subgrp_003",
"name": "Toppings",
"required": false,
"max_selections": 10
}
],
"status": "active"
}
],
"total": 15
}

Create Modifier Group

POST /api/v1/modifiers/groups

Request Body

{
"name": "Side Choice",
"display_name": "Choose Your Side",
"type": "single",
"required": true,
"min_selections": 1,
"max_selections": 1,
"modifiers": [
{"name": "French Fries", "price": 0, "default": true},
{"name": "Sweet Potato Fries", "price": 1.50},
{"name": "Side Salad", "price": 0},
{"name": "Onion Rings", "price": 2.00},
{"name": "Coleslaw", "price": 0}
],
"display_order": 1,
"locations": ["loc_123"]
}

Response

{
"id": "modgrp_004",
"name": "Side Choice",
"status": "active",
"modifiers_created": 5,
"created_at": "2026-01-24T19:30:00Z"
}

Get Modifier Group

GET /api/v1/modifiers/groups/{group_id}

Response

{
"id": "modgrp_002",
"name": "Pizza Toppings",
"display_name": "Add Extra Toppings",
"description": "Customize your pizza with additional toppings",
"type": "multiple",
"required": false,
"min_selections": 0,
"max_selections": 10,
"pricing_type": "per_modifier",
"free_modifiers": 0,
"modifiers": [
{
"id": "mod_010",
"name": "Pepperoni",
"price": 2.00,
"calories": 140,
"allergens": [],
"available": true,
"display_order": 1
},
{
"id": "mod_011",
"name": "Mushrooms",
"price": 1.50,
"calories": 20,
"allergens": [],
"dietary": ["vegetarian", "vegan"],
"available": true,
"display_order": 2
},
{
"id": "mod_012",
"name": "Extra Cheese",
"price": 2.50,
"calories": 110,
"allergens": ["dairy"],
"dietary": ["vegetarian"],
"available": true,
"display_order": 3
}
],
"applies_to": [
{"item_id": "item_001", "item_name": "Margherita Pizza"},
{"item_id": "item_002", "item_name": "Pepperoni Pizza"}
],
"locations": ["loc_123", "loc_456"],
"status": "active",
"created_at": "2025-06-01T00:00:00Z",
"updated_at": "2026-01-20T00:00:00Z"
}

Update Modifier Group

PUT /api/v1/modifiers/groups/{group_id}

Delete Modifier Group

Deleting Modifier Groups

Deleting a modifier group will remove it from all associated menu items. This cannot be undone. Check the applies_to field before deleting to understand which items will be affected.

DELETE /api/v1/modifiers/groups/{group_id}

Modifiers

List Modifiers

GET /api/v1/modifiers

Query Parameters

ParameterTypeDescription
group_iduuidFilter by group
availablebooleanFilter by availability
searchstringSearch modifier name

Response

{
"modifiers": [
{
"id": "mod_010",
"group_id": "modgrp_002",
"group_name": "Pizza Toppings",
"name": "Pepperoni",
"price": 2.00,
"available": true,
"usage_count_30d": 1250
}
],
"total": 85
}

Create Modifier

POST /api/v1/modifiers

Request Body

{
"group_id": "modgrp_002",
"name": "Bacon",
"price": 2.50,
"calories": 180,
"allergens": [],
"dietary": [],
"description": "Crispy bacon strips",
"available": true,
"display_order": 10,
"sku": "TOP-BACON"
}

Get Modifier

GET /api/v1/modifiers/{modifier_id}

Response

{
"id": "mod_010",
"group_id": "modgrp_002",
"name": "Pepperoni",
"display_name": "Pepperoni",
"description": "Classic pepperoni slices",
"price": 2.00,
"cost": 0.45,
"calories": 140,
"allergens": [],
"dietary": [],
"nutrition": {
"fat": 12,
"protein": 6,
"carbs": 1,
"sodium": 480
},
"available": true,
"availability_schedule": null,
"inventory_tracking": {
"enabled": true,
"current_quantity": 500,
"low_threshold": 100
},
"image_url": "https://...",
"display_order": 1,
"sku": "TOP-PEPP",
"external_ids": {
"pos_id": "12345"
},
"usage": {
"count_30d": 1250,
"revenue_30d": 2500.00
},
"created_at": "2025-06-01T00:00:00Z"
}

Update Modifier

PUT /api/v1/modifiers/{modifier_id}

Update Modifier Availability

PATCH /api/v1/modifiers/{modifier_id}/availability

Request Body

{
"available": false,
"reason": "out_of_stock",
"restore_at": "2026-01-25T08:00:00Z"
}

Delete Modifier

DELETE /api/v1/modifiers/{modifier_id}

Item Modifier Assignments

Get Item Modifiers

GET /api/v1/modifiers/items/{item_id}

Response

{
"item_id": "item_001",
"item_name": "Ribeye Steak",
"modifier_groups": [
{
"group_id": "modgrp_001",
"name": "Steak Temperature",
"required": true,
"display_order": 1,
"overrides": null
},
{
"group_id": "modgrp_004",
"name": "Side Choice",
"required": true,
"display_order": 2,
"overrides": {
"excluded_modifiers": ["mod_025"],
"price_adjustments": [
{"modifier_id": "mod_022", "price": 3.00}
]
}
},
{
"group_id": "modgrp_005",
"name": "Add-Ons",
"required": false,
"display_order": 3,
"overrides": null
}
]
}

Assign Modifier Groups to Item

POST /api/v1/modifiers/items/{item_id}/groups

Request Body

{
"assignments": [
{
"group_id": "modgrp_001",
"required": true,
"display_order": 1
},
{
"group_id": "modgrp_004",
"required": true,
"display_order": 2,
"overrides": {
"excluded_modifiers": ["mod_025"],
"price_adjustments": [
{"modifier_id": "mod_022", "price": 3.00}
]
}
}
]
}

Remove Modifier Group from Item

DELETE /api/v1/modifiers/items/{item_id}/groups/{group_id}

Pricing Rules

Get Pricing Rules

GET /api/v1/modifiers/pricing-rules

Response

{
"rules": [
{
"id": "rule_001",
"name": "Free First Topping",
"type": "free_quantity",
"applies_to": {
"group_ids": ["modgrp_002"]
},
"conditions": {
"free_count": 1
},
"status": "active"
},
{
"id": "rule_002",
"name": "Premium Upcharge",
"type": "size_based",
"applies_to": {
"group_ids": ["modgrp_002"]
},
"conditions": {
"size_multipliers": {
"small": 1.0,
"medium": 1.5,
"large": 2.0
}
},
"status": "active"
},
{
"id": "rule_003",
"name": "Half/Half Pricing",
"type": "portion_based",
"applies_to": {
"item_categories": ["pizza"]
},
"conditions": {
"half_price_multiplier": 0.5
},
"status": "active"
}
]
}

Create Pricing Rule

POST /api/v1/modifiers/pricing-rules

Request Body

{
"name": "Buy 2 Get 1 Free Toppings",
"type": "quantity_discount",
"applies_to": {
"group_ids": ["modgrp_002"]
},
"conditions": {
"buy_quantity": 2,
"free_quantity": 1
},
"locations": ["loc_123"]
}

Bulk Operations

Bulk Update Availability

POST /api/v1/modifiers/bulk/availability

Request Body

{
"updates": [
{"modifier_id": "mod_010", "available": false},
{"modifier_id": "mod_011", "available": false},
{"modifier_id": "mod_012", "available": true}
],
"reason": "inventory_adjustment"
}

Bulk Update Prices

POST /api/v1/modifiers/bulk/prices

Request Body

{
"updates": [
{"modifier_id": "mod_010", "price": 2.50},
{"modifier_id": "mod_011", "price": 2.00}
],
"effective_date": "2026-02-01"
}

Copy Modifier Group

POST /api/v1/modifiers/groups/{group_id}/copy

Request Body

{
"new_name": "Pizza Toppings (Downtown)",
"target_locations": ["loc_456"],
"include_pricing_rules": true
}

Webhooks

EventDescription
modifier.createdNew modifier created
modifier.updatedModifier updated
modifier.availability_changedAvailability changed
modifier_group.createdNew group created
modifier_group.updatedGroup updated

Error Responses

StatusCodeDescription
400invalid_selectionSelection violates min/max rules
400modifier_unavailableModifier not available
404modifier_not_foundModifier ID not found
404group_not_foundGroup ID not found
409modifier_in_useCannot delete modifier in use