Overview
Modifiers allow customers to customize menu items. The modifier system has two levels:
- Modifier Groups: Collections of related options (e.g., “Protein Choice”, “Extras”, “Spice Level”)
- Modifiers: Individual options within a group (e.g., “Chicken +S/. 5”, “Extra Cheese +S/. 3”)
Modifier groups can be:
- Required (customer must select)
- Optional (customer may select)
- Configured with min/max selection limits
Modifier Group Object
Unique identifier for the modifier group
ID of the branch this group belongs to
ID of the parent organization
Group name (1-255 characters). Example: “Choose Your Protein”
Minimum required selections (default: 0)
Maximum allowed selections (default: 1)
Whether customer must make a selection (default: false)
Modifier Object
Unique identifier for the modifier
ID of the parent modifier group
Modifier name (1-255 characters). Example: “Extra Cheese”
Additional price in cents (default: 0). Example: 300 = +S/. 3.00
Current availability status (default: true)
List Modifier Groups
GET /menu/modifier-groups
Retrieve all modifier groups for the current branch, including their modifiers
Required Permission: menu:read
Request:
curl https://api.restai.com/v1/menu/modifier-groups \
-H "Authorization: Bearer <token>"
Response:
{
"success": true,
"data": [
{
"id": "group-001",
"branch_id": "550e8400-e29b-41d4-a716-446655440000",
"organization_id": "123e4567-e89b-12d3-a456-426614174000",
"name": "Elige tu Proteína",
"min_selections": 1,
"max_selections": 1,
"is_required": true,
"modifiers": [
{
"id": "mod-001",
"group_id": "group-001",
"name": "Pollo",
"price": 0,
"is_available": true
},
{
"id": "mod-002",
"group_id": "group-001",
"name": "Carne",
"price": 500,
"is_available": true
},
{
"id": "mod-003",
"group_id": "group-001",
"name": "Pescado",
"price": 700,
"is_available": true
}
]
},
{
"id": "group-002",
"branch_id": "550e8400-e29b-41d4-a716-446655440000",
"organization_id": "123e4567-e89b-12d3-a456-426614174000",
"name": "Extras",
"min_selections": 0,
"max_selections": 5,
"is_required": false,
"modifiers": [
{
"id": "mod-004",
"group_id": "group-002",
"name": "Queso Extra",
"price": 300,
"is_available": true
},
{
"id": "mod-005",
"group_id": "group-002",
"name": "Aguacate",
"price": 400,
"is_available": true
}
]
}
]
}
Create Modifier Group
POST /menu/modifier-groups
Create a new modifier group
Required Permission: menu:create
Body Parameters:
Group name (1-255 characters)
Minimum required selections (min: 0)
Maximum allowed selections (min: 1)
Whether customer must make a selection
Request:
curl -X POST https://api.restai.com/v1/menu/modifier-groups \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Nivel de Picante",
"minSelections": 1,
"maxSelections": 1,
"isRequired": true
}'
Response (201 Created):
{
"success": true,
"data": {
"id": "group-003",
"branch_id": "550e8400-e29b-41d4-a716-446655440000",
"organization_id": "123e4567-e89b-12d3-a456-426614174000",
"name": "Nivel de Picante",
"min_selections": 1,
"max_selections": 1,
"is_required": true
}
}
Update Modifier Group
PATCH /menu/modifier-groups/:id
Update an existing modifier group
Required Permission: menu:update
Path Parameters:
Body Parameters (all optional):
Group name (1-255 characters)
Minimum required selections (min: 0)
Maximum allowed selections (min: 1)
Whether customer must make a selection
Request:
curl -X PATCH https://api.restai.com/v1/menu/modifier-groups/group-003 \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"maxSelections": 2,
"isRequired": false
}'
Response:
{
"success": true,
"data": {
"id": "group-003",
"branch_id": "550e8400-e29b-41d4-a716-446655440000",
"organization_id": "123e4567-e89b-12d3-a456-426614174000",
"name": "Nivel de Picante",
"min_selections": 1,
"max_selections": 2,
"is_required": false
}
}
Delete Modifier Group
DELETE /menu/modifier-groups/:id
Delete a modifier group and all its modifiers
Required Permission: menu:delete
Path Parameters:
Request:
curl -X DELETE https://api.restai.com/v1/menu/modifier-groups/group-003 \
-H "Authorization: Bearer <token>"
Response:
{
"success": true,
"data": {
"message": "Grupo eliminado"
}
}
Deleting a modifier group will cascade delete all modifiers in that group and remove all links to menu items. This action cannot be undone.
Create Modifier
POST /menu/modifiers
Create a new modifier within a group
Required Permission: menu:create
Body Parameters:
ID of the parent modifier group
Modifier name (1-255 characters)
Additional price in cents (min: 0)
Whether modifier is currently available
Request:
curl -X POST https://api.restai.com/v1/menu/modifiers \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"groupId": "group-001",
"name": "Camarones",
"price": 1000,
"isAvailable": true
}'
Response (201 Created):
{
"success": true,
"data": {
"id": "mod-006",
"group_id": "group-001",
"name": "Camarones",
"price": 1000,
"is_available": true
}
}
Error Response:
// 404 Not Found - Group doesn't exist
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Grupo no encontrado"
}
}
Update Modifier
PATCH /menu/modifiers/:id
Update an existing modifier
Required Permission: menu:update
Path Parameters:
Body Parameters (all optional):
Modifier name (1-255 characters)
Additional price in cents (min: 0)
Whether modifier is currently available
Request:
curl -X PATCH https://api.restai.com/v1/menu/modifiers/mod-006 \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"price": 1200,
"isAvailable": false
}'
Response:
{
"success": true,
"data": {
"id": "mod-006",
"group_id": "group-001",
"name": "Camarones",
"price": 1200,
"is_available": false
}
}
Delete Modifier
DELETE /menu/modifiers/:id
Delete a modifier
Required Permission: menu:delete
Path Parameters:
Request:
curl -X DELETE https://api.restai.com/v1/menu/modifiers/mod-006 \
-H "Authorization: Bearer <token>"
Response:
{
"success": true,
"data": {
"message": "Modificador eliminado"
}
}
Common Modifier Patterns
Required Single Selection
Customer must choose exactly one option (e.g., protein choice, cooking temperature):
{
"name": "Choose Your Protein",
"minSelections": 1,
"maxSelections": 1,
"isRequired": true
}
Optional Multiple Selections
Customer can choose 0 or more options up to a limit (e.g., toppings, extras):
{
"name": "Add Toppings",
"minSelections": 0,
"maxSelections": 5,
"isRequired": false
}
Required Multiple Selections
Customer must choose at least X options (e.g., “Choose 2 sides”):
{
"name": "Choose 2 Side Dishes",
"minSelections": 2,
"maxSelections": 2,
"isRequired": true
}
Free Preferences
No price impact, just preferences (e.g., spice level):
{
"name": "Spice Level",
"minSelections": 0,
"maxSelections": 1,
"isRequired": false,
"modifiers": [
{ "name": "Mild", "price": 0 },
{ "name": "Medium", "price": 0 },
{ "name": "Hot", "price": 0 }
]
}
Validation Rules
maxSelections must be greater than or equal to minSelections
- If
isRequired is true, minSelections should be at least 1
- Modifier prices cannot be negative
Best Practices
Use clear naming: Name groups with action words like “Choose Your…”, “Add…”, “Select…”
Set reasonable limits: Don’t allow unlimited selections unless truly needed
Base option at $0: When offering choices where one is included (like protein), set the base option to 0 and charge extra for premium options
Group related options: Keep modifier groups focused (don’t mix protein choices with spice levels)
After creating modifier groups, link them to menu items:
curl -X POST https://api.restai.com/v1/menu/items/{itemId}/modifier-groups \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "groupId": "group-001" }'
See Menu Items documentation for more details.