Skip to content

Menus

The Menu API provides access to restaurant menus, categories, items, and modifiers.

List Menus

Get all available menus for a concept at a location.

GET /v1/ecommerce/locations/{location}/concepts/{concept}/menus

Authentication: None (Public)

Rate Limit: 100/min per IP

Path Parameters

ParameterTypeDescription
locationstringLocation hashkey
conceptstringConcept hashkey

Response

json
{
  "status": "success",
  "data": [
    {
      "menu_id": "mnu_00000k1L2m3N4o5",
      "name": "All Day Menu",
      "description": "Our complete menu available all day",
      "menu_type": "regular",
      "hero_url": "https://cdn.example.com/menus/allday.jpg",
      "status": "live",
      "display_order": 1,
      "channel_restrictions": []
    },
    {
      "menu_id": "mnu_00000p1Q2r3S4t5",
      "name": "Breakfast Menu",
      "description": "Morning favorites served until 11am",
      "menu_type": "breakfast",
      "hero_url": "https://cdn.example.com/menus/breakfast.jpg",
      "status": "live",
      "display_order": 2,
      "availability_rules": {
        "days": ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"],
        "time_ranges": [{"start": "06:00", "end": "11:00"}]
      },
      "channel_restrictions": ["kiosk", "online"]
    }
  ]
}
FieldTypeDescription
menu_idstringUnique menu identifier
namestringDisplay name
descriptionstringMenu description
menu_typestringregular, breakfast, lunch, dinner, late_night, happy_hour
hero_urlstringMenu banner image
statusstringdraft, live, archived
display_orderintegerSort order
availability_rulesobjectWhen menu is available
channel_restrictionsarrayChannels where menu is available (empty = all)

Get Menu Items

Retrieve the full menu hierarchy including categories, subcategories, and items.

GET /v1/ecommerce/locations/{location}/concepts/{concept}/menus/{menu}/items

Authentication: None (Public)

Rate Limit: 100/min per IP

Path Parameters

ParameterTypeDescription
locationstringLocation hashkey
conceptstringConcept hashkey
menustringMenu hashkey

Response

json
{
  "status": "success",
  "data": {
    "menu": {
      "menu_id": "mnu_00000k1L2m3N4o5",
      "name": "All Day Menu",
      "hero_url": "https://cdn.example.com/menus/allday.jpg"
    },
    "hierarchy": [
      {
        "item_id": "itm_cat_appetizers",
        "name": "Appetizers",
        "description": "Start your meal right",
        "type": "category",
        "display_order": 1,
        "hero_url": "https://cdn.example.com/categories/appetizers.jpg",
        "children": [
          {
            "item_id": "itm_sub_fried",
            "name": "Fried Favorites",
            "type": "subcategory",
            "display_order": 1,
            "children": [
              {
                "item_id": "itm_00000a1B2c3D4e5",
                "name": "Mozzarella Sticks",
                "description": "Six golden fried mozzarella sticks served with marinara",
                "type": "item",
                "base_price": 8.99,
                "hero_url": "https://cdn.example.com/items/mozz.jpg",
                "nutritional_info": {
                  "calories": 450,
                  "protein": 18,
                  "carbs": 35,
                  "fat": 28,
                  "sodium": 890,
                  "sugar": 3
                },
                "allergens": ["dairy", "gluten", "eggs"],
                "dietary_tags": ["vegetarian"],
                "tags": ["popular", "shareable"],
                "prep_time_minutes": 8,
                "is_featured": true,
                "is_86d": false,
                "display_order": 1,
                "status": "live"
              },
              {
                "item_id": "itm_00000f5G6h7I8j9",
                "name": "Onion Rings",
                "description": "Crispy battered onion rings",
                "type": "item",
                "base_price": 6.99,
                "hero_url": "https://cdn.example.com/items/onion-rings.jpg",
                "allergens": ["gluten"],
                "dietary_tags": ["vegetarian", "vegan"],
                "is_featured": false,
                "is_86d": false,
                "display_order": 2,
                "status": "live"
              }
            ]
          }
        ]
      },
      {
        "item_id": "itm_cat_entrees",
        "name": "Entrees",
        "type": "category",
        "display_order": 2,
        "children": []
      }
    ]
  }
}

Item Fields

FieldTypeDescription
item_idstringUnique item identifier
namestringDisplay name
descriptionstringItem description
typestringcategory, subcategory, or item
base_pricedecimalPrice before modifiers
hero_urlstringMain item image
nutritional_infoobjectNutrition facts
allergensarrayAllergen warnings
dietary_tagsarrayDiet compatibility
tagsarrayCustom tags (popular, signature, etc.)
prep_time_minutesintegerEstimated prep time
is_featuredbooleanFeatured item flag
is_86dbooleanOut of stock flag
display_orderintegerSort order within parent
statusstringdraft or live
childrenarrayChild items (for categories)

Allergens

Common allergen values:

ValueDescription
dairyContains milk products
eggsContains eggs
fishContains fish
shellfishContains shellfish
tree_nutsContains tree nuts
peanutsContains peanuts
wheatContains wheat
glutenContains gluten
soyContains soy
sesameContains sesame

Dietary Tags

ValueDescription
vegetarianNo meat
veganNo animal products
gluten-freeNo gluten
ketoKeto-friendly
halalHalal certified
kosherKosher certified

Get Item Details

Get detailed item information including modifiers/customizations.

GET /v1/ecommerce/locations/{location}/concepts/{concept}/items/{item}

Authentication: None (Public)

Rate Limit: 100/min per IP

Response

json
{
  "status": "success",
  "data": {
    "item_id": "itm_00000a1B2c3D4e5",
    "name": "Classic Burger",
    "description": "1/3 lb beef patty with lettuce, tomato, onion, and pickles",
    "type": "item",
    "base_price": 12.99,
    "hero_url": "https://cdn.example.com/items/burger.jpg",
    "gallery_images": [
      {"url": "https://cdn.example.com/items/burger-1.jpg", "alt_text": "Burger front view"},
      {"url": "https://cdn.example.com/items/burger-2.jpg", "alt_text": "Burger side view"}
    ],
    "nutritional_info": {
      "calories": 750,
      "protein": 42,
      "carbs": 45,
      "fat": 48
    },
    "allergens": ["gluten", "dairy", "eggs"],
    "dietary_tags": [],
    "prep_time_minutes": 12,
    "is_featured": true,
    "is_86d": false,
    "option_groups": [
      {
        "option_group_id": "opg_00000k1L2m3N4o5",
        "name": "Choose Your Cheese",
        "description": "Select your cheese preference",
        "is_required": true,
        "min_selections": 1,
        "max_selections": 1,
        "sort_order": 1,
        "modifiers": [
          {
            "modifier_id": "mod_american",
            "name": "American Cheese",
            "price_adjustment": 0,
            "is_default": true,
            "sort_order": 1
          },
          {
            "modifier_id": "mod_cheddar",
            "name": "Cheddar Cheese",
            "price_adjustment": 0,
            "sort_order": 2
          },
          {
            "modifier_id": "mod_swiss",
            "name": "Swiss Cheese",
            "price_adjustment": 0.50,
            "sort_order": 3
          },
          {
            "modifier_id": "mod_none",
            "name": "No Cheese",
            "price_adjustment": 0,
            "sort_order": 4
          }
        ]
      },
      {
        "option_group_id": "opg_00000p5Q6r7S8t9",
        "name": "Add Toppings",
        "description": "Customize with extra toppings",
        "is_required": false,
        "min_selections": 0,
        "max_selections": 5,
        "sort_order": 2,
        "modifiers": [
          {
            "modifier_id": "mod_bacon",
            "name": "Bacon",
            "price_adjustment": 2.00,
            "sort_order": 1
          },
          {
            "modifier_id": "mod_avocado",
            "name": "Avocado",
            "price_adjustment": 1.50,
            "sort_order": 2
          },
          {
            "modifier_id": "mod_jalapeno",
            "name": "Jalapenos",
            "price_adjustment": 0.50,
            "sort_order": 3
          },
          {
            "modifier_id": "mod_egg",
            "name": "Fried Egg",
            "price_adjustment": 1.50,
            "sort_order": 4
          }
        ]
      }
    ]
  }
}

Option Group Fields

FieldTypeDescription
option_group_idstringUnique option group identifier
namestringDisplay name
descriptionstringInstructions for customer
is_requiredbooleanMust select before adding to cart
min_selectionsintegerMinimum choices required
max_selectionsintegerMaximum choices allowed
sort_orderintegerDisplay order
modifiersarrayAvailable choices

Modifier Fields

FieldTypeDescription
modifier_idstringUnique modifier identifier
namestringDisplay name
price_adjustmentdecimalPrice to add (positive) or subtract (negative)
is_defaultbooleanPre-selected by default
sort_orderintegerDisplay order

Check Item Availability

Batch check if items are available (not 86'd).

POST /v1/ecommerce/locations/{location}/items/check-availability

Authentication: OAuth Token

Scope: kitchenclick:menus.read

Rate Limit: 200/min per client

Request Body

json
{
  "items": [
    { "item_id": "itm_00000a1B2c3D4e5", "quantity": 2 },
    { "item_id": "itm_00000f5G6h7I8j9", "quantity": 1 }
  ],
  "order_type": "pickup"
}
FieldTypeRequiredDescription
itemsarrayYesItems to check
items[].item_idstringYesMenu item ID
items[].quantityintegerNoQuantity (echoed through)
scheduled_atstringNoCheck availability for a future time
order_typestringNoOrder type; flags items paused for that type

Response

data is an array, one entry per requested item.

json
{
  "status": "success",
  "data": [
    {
      "item_id": "itm_00000a1B2c3D4e5",
      "name": "Classic Burger",
      "available": true,
      "is_86d": false,
      "reason": null,
      "expected_back_at": null,
      "price": 14.99
    },
    {
      "item_id": "itm_00000f5G6h7I8j9",
      "name": "Side Salad",
      "available": false,
      "is_86d": true,
      "reason": "86d",
      "expected_back_at": "2026-06-18T00:00:00Z",
      "price": 5.99
    }
  ],
  "meta": { "location": "loc_00000k1L2m3N4o5" }
}
FieldTypeDescription
item_idstringMenu item ID
availablebooleanWhether the item can currently be ordered
is_86dbooleantrue if 86'd (out of stock)
reasonstring | nullUnavailability reason, e.g. 86d, order_type_paused, not_live
expected_back_atstring | nullWhen the item is expected back, if known
pricenumberEffective price at this location

Example: Build Menu UI

javascript
async function loadMenuData(locationId, conceptId) {
  // Get all menus
  const menusResponse = await fetch(
    `/api/v1/ecommerce/locations/${locationId}/concepts/${conceptId}/menus`
  );
  const { data: menus } = await menusResponse.json();

  // Filter to currently available menus
  const now = new Date();
  const availableMenus = menus.filter(menu => {
    if (menu.status !== 'live') return false;
    if (!menu.availability_rules) return true;

    const dayOfWeek = now.toLocaleDateString('en-US', { weekday: 'lowercase' });
    const currentTime = now.toTimeString().slice(0, 5);

    const { days, time_ranges } = menu.availability_rules;
    if (!days.includes(dayOfWeek)) return false;

    return time_ranges.some(range =>
      currentTime >= range.start && currentTime <= range.end
    );
  });

  // Load items for first available menu
  if (availableMenus.length > 0) {
    const menuId = availableMenus[0].menu_id;
    const itemsResponse = await fetch(
      `/api/v1/ecommerce/locations/${locationId}/concepts/${conceptId}/menus/${menuId}/items`
    );
    const { data } = await itemsResponse.json();

    return {
      menus: availableMenus,
      currentMenu: data.menu,
      hierarchy: data.hierarchy,
    };
  }

  return { menus: [], currentMenu: null, hierarchy: [] };
}

Changelog
DateChange
2026-06-17Corrected response ID fields to the _id convention (menu_id, item_id, option_group_id, modifier_id); fixed the Check Item Availability request/response to the real items[].item_id shape.
2026-01-15Initial publication.

ShopHero CommerceCore Platform