Skip to main content

Overview

Modifiers allow customers to customize menu items. The modifier system has two levels:
  1. Modifier Groups: Collections of related options (e.g., “Protein Choice”, “Extras”, “Spice Level”)
  2. 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

id
string (uuid)
Unique identifier for the modifier group
branch_id
string (uuid)
ID of the branch this group belongs to
organization_id
string (uuid)
ID of the parent organization
name
string
Group name (1-255 characters). Example: “Choose Your Protein”
min_selections
integer
Minimum required selections (default: 0)
max_selections
integer
Maximum allowed selections (default: 1)
is_required
boolean
Whether customer must make a selection (default: false)

Modifier Object

id
string (uuid)
Unique identifier for the modifier
group_id
string (uuid)
ID of the parent modifier group
name
string
Modifier name (1-255 characters). Example: “Extra Cheese”
price
integer
Additional price in cents (default: 0). Example: 300 = +S/. 3.00
is_available
boolean
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:
name
string
required
Group name (1-255 characters)
minSelections
integer
default:"0"
Minimum required selections (min: 0)
maxSelections
integer
default:"1"
Maximum allowed selections (min: 1)
isRequired
boolean
default:"false"
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:
id
string (uuid)
required
Modifier group ID
Body Parameters (all optional):
name
string
Group name (1-255 characters)
minSelections
integer
Minimum required selections (min: 0)
maxSelections
integer
Maximum allowed selections (min: 1)
isRequired
boolean
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:
id
string (uuid)
required
Modifier group ID
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:
groupId
string (uuid)
required
ID of the parent modifier group
name
string
required
Modifier name (1-255 characters)
price
integer
default:"0"
Additional price in cents (min: 0)
isAvailable
boolean
default:"true"
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:
id
string (uuid)
required
Modifier ID
Body Parameters (all optional):
name
string
Modifier name (1-255 characters)
price
integer
Additional price in cents (min: 0)
isAvailable
boolean
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:
id
string (uuid)
required
Modifier ID
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)

Linking to Menu Items

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.

Build docs developers (and LLMs) love