Skip to content

Item Configurator

Some menu items use a configurator — a guided, multi-step "build your own" flow (e.g. build-a-pizza, custom platters) instead of a flat list of modifier groups. The configurator endpoints return the step definitions for an item and validate a customer's in-progress build before it is added to the cart.

These endpoints are public (no authentication required). Items that do not have a configurator return 404 — fall back to the standard option groups returned by GET .../items/{item}.

Get Item Configurator

Fetch the configurator template (ordered steps + resolved option groups) for an item.

GET /v1/ecommerce/items/{item}/configurator

Authentication: None (Public)

Rate Limit: 100/min per IP

Path Parameters

ParameterTypeDescription
itemstringMenu item ID (e.g. itm_00000a1B2c3D4e5)

Response

json
{
  "status": "success",
  "data": {
    "id": "cfg_00000a1B2c3D4e5",
    "menu_item_id": "itm_00000a1B2c3D4e5",
    "name": "Build Your Pizza",
    "status": "active",
    "steps": [
      {
        "step_number": 1,
        "name": "Select Size",
        "type": "single_select",
        "option_group_id": "opg_size123",
        "required": true,
        "ui_hint": "size_picker",
        "help_text": "Choose your pizza size"
      },
      {
        "step_number": 2,
        "name": "Add Toppings",
        "type": "multi_select",
        "option_group_id": "opg_toppings456",
        "required": false,
        "ui_hint": "checkbox_grid",
        "help_text": "Select as many as you like"
      },
      {
        "step_number": 3,
        "name": "Special Instructions",
        "type": "text_input",
        "option_group_id": null,
        "required": false,
        "max_length": 500,
        "price_impact": 0,
        "ui_hint": "textarea",
        "help_text": "Any notes for the kitchen?"
      }
    ],
    "option_groups": [
      {
        "option_group_id": "opg_size123",
        "name": "Pizza Size",
        "selection_type": "single",
        "pricing_type": "per_modifier",
        "modifiers": [
          {
            "modifier_id": "mod_small",
            "name": "Small (10\")",
            "description": "Feeds 1-2 people",
            "price_adjustment": 0.00,
            "is_default": true,
            "sort_order": 1
          },
          {
            "modifier_id": "mod_large",
            "name": "Large (14\")",
            "description": "Feeds 3-4 people",
            "price_adjustment": 5.00,
            "is_default": false,
            "sort_order": 2
          }
        ]
      },
      {
        "option_group_id": "opg_toppings456",
        "name": "Toppings",
        "selection_type": "multiple",
        "pricing_type": "per_modifier",
        "modifiers": [
          {
            "modifier_id": "mod_pepperoni",
            "name": "Pepperoni",
            "price_adjustment": 1.50,
            "is_default": false,
            "sort_order": 1
          }
        ]
      }
    ]
  }
}

Step Fields

FieldTypeDescription
step_numberinteger1-indexed execution order
namestringDisplay name for the step
typestringsingle_select, multi_select, text_input, or image_upload
option_group_idstring | nullOption group resolved in option_groups (select steps only)
requiredbooleanWhether the step must be completed before checkout
max_lengthinteger | nullMax characters for text_input steps
price_impactnumber | nullFlat price added when a non-select step is completed
ui_hintstring | nullRendering hint (e.g. size_picker, checkbox_grid, textarea)
help_textstring | nullInstructional copy shown to the customer

The option_groups array contains the same option-group / modifier shape used elsewhere in the Menus API. See Menus → Item Details.

Validate Configuration

Validate a customer's in-progress build and compute its price impact before adding it to the cart. Use this to drive inline validation in your UI; the canonical price is always re-computed server-side at POST /orders/calculate.

POST /v1/ecommerce/items/{item}/configurator/validate

Authentication: None (Public)

Rate Limit: 100/min per IP

Request Body

json
{
  "selections": [
    { "step_number": 1, "type": "single_select", "value": "mod_large" },
    { "step_number": 2, "type": "multi_select", "value": ["mod_pepperoni"] },
    { "step_number": 3, "type": "text_input", "value": "Light cheese" }
  ]
}
FieldTypeRequiredDescription
selectionsarrayYesAt least one selection
selections[].step_numberintegerYesMust match a step in the template
selections[].typestringYesThe step type (single_select, multi_select, text_input, image_upload)
selections[].valuemixedYessingle_select: a modifier ID string · multi_select: an array of modifier ID strings · text_input/image_upload: a string

Response

json
{
  "status": "success",
  "data": {
    "valid": true,
    "errors": [],
    "price_impact": 6.50
  }
}
FieldTypeDescription
validbooleantrue when all required steps are present and within constraints
errorsarrayHuman-readable constraint violations (empty when valid), e.g. "Step 1 (Select Size) is required."
price_impactnumberTotal price added by the current selections, rounded to 2 decimals

Errors

StatusCondition
404Item not found, or the item has no configurator
422Malformed request body (e.g. missing selections)

Changelog
DateChange
2026-06-17Initial publication.

ShopHero CommerceCore Platform