Menu Structure v3.0
Understand the menu object returned by the Menu Management public API and how categories, items, modifiers, and category groups relate to each other.
Menu structure
Use this reference to understand the menu object returned by the Menu Management public API and how its entities relate to each other.
A Menu is the top-level menu object for a restaurant. It contains Categories (groupings of orderable items), Modifiers (reusable option groups), and CategoryGroups (logical groupings of categories for display).
Hierarchy
Menu
├── categories[]
│ └── Category
│ ├── availabilityOverrides[]
│ └── items[]
│ └── Item (CategoryItem)
│ ├── modifierMembers[] ──references──▶ Modifier (by parentModifierId)
│ ├── pricingProfiles[]
│ ├── charges[]
│ └── availabilityOverrides[]
│
├── modifiers[]
│ └── Modifier
│ └── items[]
│ └── ModifierItem (Item + autoSelectedQuantity)
│ ├── modifierMembers[] ──references──▶ Modifier (nested modifiers)
│ ├── pricingProfiles[]
│ ├── charges[]
│ └── availabilityOverrides[]
│
└── categoryGroups[]
└── CategoryGroup ──references──▶ Categories (by categoryIds[])
Key Concepts
Categories and Items
A Category is a section of the menu (e.g. "Starters", "Mains", "Desserts"). Each category contains an array of Items — the orderable products a customer can add to an order.
Modifiers and ModifierMembers
Modifiers are reusable option groups defined at the menu level (e.g. "Choose your size", "Extra toppings"). They are not nested inside items directly. Instead, items reference modifiers through ModifierMembers.
A ModifierMember is a link from an item to a modifier group. It can override properties such as min, max, and canSameItemBeSelectedMultipleTimes for that item, so the same modifier can behave differently depending on where it is used.
Each Modifier contains ModifierItems — the individual selectable options within that group (e.g. "Small", "Medium", "Large").
ModifierItems can themselves have ModifierMembers, enabling nested modifier chains (e.g. a "Burger" item → "Choose your patty" modifier → "Beef Patty" modifier item → "Choose doneness" modifier).
Pricing Profiles and Price Bands
Each item (CategoryItem or ModifierItem) can have multiple PricingProfiles, one per price band. Each profile defines separate prices for four dispatch types: Collection, Delivery, DineIn, and TakeAway. This allows different pricing based on how the order is fulfilled.
Availability Overrides
AvailabilityOverrides control when and where a category or item is visible. They can restrict availability by:
- Property - specific store locations
- Venue code - sales channels (Flipdish, Deliveroo, JustEats, UberEats, etc.)
- Dispatch type - DineIn, TakeAway, Collection, Delivery
- Day of week - individual day flags (Monday through Sunday)
- Time of day - fromTime / toTime window
Category Groups
CategoryGroups provide a way to logically group categories together for display purposes (e.g. grouping "Starters" and "Soups" under "Light Bites"). They reference categories by ID rather than containing them.
Charges
A Charge is an extra amount applied on top of an item or order — for example a Deposit Return Scheme (DRS) deposit, a bag charge, a service charge, or a tip. Charges are defined once at the org level (each has its own id, scheme, type, and value) and then referenced from individual menu items.
The two halves are distinct:
- The Charge itself lives at the org level. List the charges defined for an org with
GET /menuManagement/orgs/{orgId}/charges. See the Charge entity reference below. - An ItemCharge is the reference on a menu item that links it to a charge, by
chargeId, scoped to apriceBandId. It carries no amount of its own — the amount comes from the org-level charge.
A common case is a DRS deposit — the charge whose scheme is Deposit.Return. See Configuring a DRS (deposit return) fee for a worked example.
Entity Reference
Menu
The root entity containing all menu data.
| Property | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Unique menu identifier |
orgId | string | Yes | Org identifier |
name | string | Yes | Menu name |
description | string | No | Menu description |
type | string | Yes | Menu type: Store, Primary, Reward, or Kiosk |
revisionId | number | Yes | Revision number (incremented on each save) |
createdAt | string (ISO 8601) | Yes | Creation timestamp |
updatedBy | string | No | Email of user who last updated the menu |
updatedAt | string (ISO 8601) | No | Last update timestamp |
categories | Category[] | Yes | Array of categories |
modifiers | Modifier[] | Yes | Array of modifiers |
categoryGroups | CategoryGroup[] | Yes | Array of category groups |
Category
A grouping of items within a menu (e.g. "Starters", "Mains").
| Property | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Unique category identifier |
caption | string | Yes | Display name |
enabled | boolean | Yes | Whether the category is active |
description | string | No | Category description |
imageUrl | string | No | URL of the category image |
backgroundColor | string | No | Background colour (hex) |
foregroundColor | string | No | Foreground/text colour (hex) |
selectedBackgroundColor | string | No | Background colour when selected |
selectedForegroundColor | string | No | Foreground colour when selected |
items | Item[] | Yes | Array of items in this category |
availabilityOverrides | AvailabilityOverride[] | Yes | Availability rules for this category |
Item (CategoryItem)
An orderable product within a category.
| Property | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Unique item identifier |
externalId | string | No | External system identifier |
metadata | string | No | Arbitrary metadata (JSON string) |
caption | string | Yes | Display name |
enabled | boolean | Yes | Whether the item is active |
description | string | No | Item description |
productId | string | No | Associated product identifier |
imageUrl | string | No | URL of the item image |
backgroundColor | string | No | Background colour (hex) |
foregroundColor | string | No | Foreground/text colour (hex) |
selectedBackgroundColor | string | No | Background colour when selected |
selectedForegroundColor | string | No | Foreground colour when selected |
cellLayoutType | string | No | Display layout: Small, Medium, Large, or HiddenImage |
alcohol | boolean | Yes | Whether the item contains alcohol |
allergens | string[] | Yes | List of allergens present (see Allergens) |
disableVouchers | boolean | Yes | Exclude from all discount offers |
excludeFromVoucherDiscounting | boolean | Yes | Exclude from voucher discounts specifically |
modifierMembers | ModifierMember[] | Yes | References to modifier groups |
pricingProfiles | PricingProfile[] | Yes | Pricing per price band |
charges | ItemCharge[] | Yes | Associated charges |
availabilityOverrides | AvailabilityOverride[] | Yes | Availability rules for this item |
Modifier
A reusable group of options defined at the menu level (e.g. "Choose your size").
| Property | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Unique modifier identifier |
caption | string | Yes | Display name |
enabled | boolean | Yes | Whether the modifier is active |
description | string | No | Modifier description |
backgroundColor | string | No | Background colour (hex) |
foregroundColor | string | No | Foreground/text colour (hex) |
selectedBackgroundColor | string | No | Background colour when selected |
selectedForegroundColor | string | No | Foreground colour when selected |
min | number | Yes | Minimum number of selections required |
max | number | Yes | Maximum number of selections allowed |
canSameItemBeSelectedMultipleTimes | boolean | Yes | Whether the same option can be selected more than once |
hiddenInOrderFlow | boolean | Yes | Whether the modifier is visible in the ordering flow |
items | ModifierItem[] | Yes | Array of selectable options |
ModifierItem
An individual option within a modifier group (e.g. "Large", "Extra Cheese"). It includes all Item properties plus one additional property.
| Property | Type | Required | Description |
|---|---|---|---|
| (all Item properties) | See Item above | ||
autoSelectedQuantity | number | No | Default quantity to pre-select |
ModifierMember
A reference from an item to a modifier group, with optional per-item overrides.
| Property | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Unique modifier member identifier |
parentModifierId | string (UUID) | Yes | ID of the referenced modifier |
caption | string | No | Override display name |
min | number | No | Override minimum selections for this item |
max | number | No | Override maximum selections for this item |
enabled | boolean | Yes | Whether this modifier link is active |
canSameItemBeSelectedMultipleTimes | boolean | No | Override repeated selection setting |
PricingProfile
Pricing for a single price band, with separate values for each dispatch type.
| Property | Type | Required | Description |
|---|---|---|---|
priceBandId | string (UUID) | Yes | Price band identifier |
collectionPrice | number | Yes | Price for collection orders |
collectionTax | number | Yes | Tax amount for collection |
collectionTaxable | boolean | Yes | Whether collection price is taxable |
collectionTaxablePrice | number | No | Taxable portion of collection price |
collectionUpsellingPoints | number | No | Upselling points for collection |
deliveryPrice | number | Yes | Price for delivery orders |
deliveryTax | number | Yes | Tax amount for delivery |
deliveryTaxable | boolean | Yes | Whether delivery price is taxable |
deliveryTaxablePrice | number | No | Taxable portion of delivery price |
deliveryUpsellingPoints | number | No | Upselling points for delivery |
dineInPrice | number | Yes | Price for dine-in orders |
dineInTax | number | Yes | Tax amount for dine-in |
dineInTaxable | boolean | Yes | Whether dine-in price is taxable |
dineInTaxablePrice | number | No | Taxable portion of dine-in price |
dineInUpsellingPoints | number | No | Upselling points for dine-in |
takeawayPrice | number | Yes | Price for takeaway orders |
takeawayTax | number | Yes | Tax amount for takeaway |
takeawayTaxable | boolean | Yes | Whether takeaway price is taxable |
takeawayTaxablePrice | number | No | Taxable portion of takeaway price |
takeawayUpsellingPoints | number | No | Upselling points for takeaway |
CategoryGroup
A logical grouping of categories for display purposes.
| Property | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Unique group identifier |
name | string | Yes | Display name |
description | string | No | Group description |
imageUrl | string | No | URL of the group image |
categoryIds | string[] | Yes | IDs of categories in this group |
AvailabilityOverride
Controls when and where a category or item is available.
| Property | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Override rule name |
enabled | boolean | Yes | Whether the entity is enabled under this override |
propertyIds | string[] | Yes | Property (store) IDs this override applies to |
venueCodes | string[] | Yes | Venue codes this override applies to (see Venue Codes) |
dispatchTypes | string[] | Yes | Dispatch types this override applies to (see Dispatch Types) |
mondayEnabled | boolean | No | Available on Mondays |
tuesdayEnabled | boolean | No | Available on Tuesdays |
wednesdayEnabled | boolean | No | Available on Wednesdays |
thursdayEnabled | boolean | No | Available on Thursdays |
fridayEnabled | boolean | No | Available on Fridays |
saturdayEnabled | boolean | No | Available on Saturdays |
sundayEnabled | boolean | No | Available on Sundays |
fromTime | string | No | Start time (e.g. "09:00") |
toTime | string | No | End time (e.g. "17:00") |
ItemCharge
A reference, held in an item's charges array, linking the item to an org-level Charge. It carries no amount itself — the amount comes from the referenced charge.
| Property | Type | Required | Description |
|---|---|---|---|
chargeId | string (UUID) | Yes | The id of the org-level charge |
priceBandId | string (UUID) | Yes | Price band the charge applies to |
Charge
An org-level charge definition. Charges are not created or edited through the menu document — they're managed at the org level and read back with GET /menuManagement/orgs/{orgId}/charges (the org code is accepted directly; the backend resolves the franchisor internally). A menu item opts into a charge by adding an ItemCharge reference to its charges array.
| Property | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Charge identifier — use this as chargeId in an item's charges array |
orgId | string | Yes | Org the charge belongs to |
name | string | Yes | Display name of the charge |
disabled | boolean | Yes | Whether the charge is currently disabled |
type | string | Yes | How the value is applied — Fixed (a flat amount) or Percentage |
scheme | string | Yes | The charge scheme — one of Service.Charge, Deposit.Return, Bag.Charge, Delivery.Charge, Tip.Charge |
target | string | Yes | What the charge applies to — Item or Order |
value | number | Yes | The numeric amount (a currency amount when type is Fixed; a percentage when type is Percentage) |
taxPercentage | number | No | Tax percentage applied to the charge |
Reference: get all charges.
Configuring a DRS (deposit return) fee
A Deposit Return Scheme deposit (e.g. Ireland's Re-turn, or similar container-deposit schemes) is modelled as a Fixed, Item-target charge whose scheme is Deposit.Return. The deposit is created once at the org level, then referenced from each drinks item it applies to.
1. Find the DRS charge for your org. List the org's charges and pick the one whose scheme is Deposit.Return:
curl --silent --request GET \
--url "$FLIPDISH_BASE_URL/menuManagement/orgs/$ORG_ID/charges" \
--header "Authorization: Bearer $TOKEN" \
--header "User-Agent: $FLIPDISH_USER_AGENT" \
| jq '.data[] | select(.scheme == "Deposit.Return")'This returns the charge's id, value (the deposit amount), and type (Fixed for a per-container deposit).
2. Reference it from a drinks item. Add an ItemCharge to the item's charges array, using the charge id as chargeId and scoping it to the relevant priceBandId:
{
"caption": "Cola 500ml",
"enabled": true,
"charges": [
{ "chargeId": "<drs-charge-id>", "priceBandId": "<price-band-id>" }
],
"pricingProfiles": [ /* ... */ ]
}When you PUT the menu back, the deposit is applied on top of the item's price at checkout. To apply the same deposit across multiple container sizes, add the same chargeId to each item's charges array (the value lives on the charge, so the per-container amount is whatever the org-level charge defines). To stop charging the deposit on an item, remove its entry from the charges array.
Enums and Constants
Menu Types
| Value | Description |
|---|---|
Store | Standard store menu |
Primary | Primary menu for a property |
Reward | Rewards/loyalty menu |
Kiosk | Self-service kiosk menu |
Dispatch Types
| Value | Description |
|---|---|
DineIn | Customer eats at the venue |
TakeAway | Customer orders and takes food away |
Collection | Customer collects a pre-placed order |
Delivery | Order is delivered to the customer |
Venue Codes
| Value | Description |
|---|---|
Flipdish | Flipdish own channels |
Deliveroo | Deliveroo marketplace |
JustEats | Just Eat marketplace |
UberEats | Uber Eats marketplace |
Property | Property-specific channel |
ExternalApp | External application channel |
Cell Layout Types
| Value | Description |
|---|---|
Small | Small item card |
Medium | Medium item card |
Large | Large item card |
HiddenImage | Item card with hidden image |
Charge Schemes
The scheme on a Charge identifies what kind of charge it is:
| Value | Description |
|---|---|
Service.Charge | A service charge |
Deposit.Return | A deposit return scheme (DRS) container deposit |
Bag.Charge | A bag charge |
Delivery.Charge | A delivery charge |
Tip.Charge | A tip |
Charge Types
The type on a Charge controls how value is interpreted:
| Value | Description |
|---|---|
Fixed | A flat currency amount |
Percentage | A percentage of the item/order total |
Charge Targets
The target on a Charge is the scope the charge applies to — either each qualifying menu item individually, or the order as a whole:
| Value | Description |
|---|---|
Item | Applied per item — e.g. a DRS deposit added to each eligible drink |
Order | Applied once to the whole order — e.g. a service charge or a bag charge |
target only takes these two values; there is no category-level target. To scope a charge to a group of products, reference it from each of those items (Item), or apply it to the entire order (Order).
Allergens
Items can declare the following allergens (based on EU food allergen regulations):
Celery, Crustaceans, Egg, Fish, Gluten, Lupin, Milk, Molluscs, Mustard, Nuts, Peanuts, Sesame, Soybeans, Sulphur Dioxide, Wheat
Example
A minimal menu with one category, one item, one modifier, and one category group:
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"orgId": "org123",
"name": "Lunch Menu",
"description": "Available 11am - 3pm",
"type": "Store",
"revisionId": 3,
"createdAt": "2025-06-01T10:00:00Z",
"updatedBy": "[email protected]",
"updatedAt": "2025-06-15T14:30:00Z",
"categories": [
{
"id": "c0000001-0000-4000-8000-000000000001",
"caption": "Burgers",
"enabled": true,
"description": "Our handcrafted burgers",
"imageUrl": "https://example.com/images/burgers.jpg",
"availabilityOverrides": [],
"items": [
{
"id": "10000001-0000-4000-8000-000000000001",
"caption": "Classic Burger",
"enabled": true,
"description": "Beef patty with lettuce, tomato, and our secret sauce",
"productId": "prod-burger-classic",
"imageUrl": "https://example.com/images/classic-burger.jpg",
"cellLayoutType": "Large",
"alcohol": false,
"allergens": ["Gluten", "Sesame", "Milk"],
"disableVouchers": false,
"excludeFromVoucherDiscounting": false,
"modifierMembers": [
{
"id": "e0000001-0000-4000-8000-000000000001",
"parentModifierId": "d0000001-0000-4000-8000-000000000001",
"caption": "Choose your size",
"min": 1,
"max": 1,
"enabled": true,
"canSameItemBeSelectedMultipleTimes": false
}
],
"pricingProfiles": [
{
"priceBandId": "f0000001-0000-4000-8000-000000000001",
"collectionPrice": 9.99,
"collectionTax": 1.50,
"collectionTaxable": true,
"deliveryPrice": 10.99,
"deliveryTax": 1.65,
"deliveryTaxable": true,
"dineInPrice": 9.99,
"dineInTax": 1.50,
"dineInTaxable": true,
"takeawayPrice": 9.99,
"takeawayTax": 1.50,
"takeawayTaxable": true
}
],
"charges": [],
"availabilityOverrides": [
{
"name": "Weekday lunch only",
"enabled": true,
"propertyIds": [],
"venueCodes": [],
"dispatchTypes": [],
"mondayEnabled": true,
"tuesdayEnabled": true,
"wednesdayEnabled": true,
"thursdayEnabled": true,
"fridayEnabled": true,
"saturdayEnabled": false,
"sundayEnabled": false,
"fromTime": "11:00",
"toTime": "15:00"
}
]
}
]
}
],
"modifiers": [
{
"id": "d0000001-0000-4000-8000-000000000001",
"caption": "Choose your size",
"enabled": true,
"description": "Select a burger size",
"min": 1,
"max": 1,
"canSameItemBeSelectedMultipleTimes": false,
"hiddenInOrderFlow": false,
"items": [
{
"id": "20000001-0000-4000-8000-000000000001",
"caption": "Regular",
"enabled": true,
"alcohol": false,
"allergens": [],
"disableVouchers": false,
"excludeFromVoucherDiscounting": false,
"modifierMembers": [],
"pricingProfiles": [
{
"priceBandId": "f0000001-0000-4000-8000-000000000001",
"collectionPrice": 0,
"collectionTax": 0,
"collectionTaxable": true,
"deliveryPrice": 0,
"deliveryTax": 0,
"deliveryTaxable": true,
"dineInPrice": 0,
"dineInTax": 0,
"dineInTaxable": true,
"takeawayPrice": 0,
"takeawayTax": 0,
"takeawayTaxable": true
}
],
"charges": [],
"availabilityOverrides": []
},
{
"id": "20000002-0000-4000-8000-000000000002",
"caption": "Large",
"enabled": true,
"alcohol": false,
"allergens": [],
"disableVouchers": false,
"excludeFromVoucherDiscounting": false,
"modifierMembers": [],
"pricingProfiles": [
{
"priceBandId": "f0000001-0000-4000-8000-000000000001",
"collectionPrice": 2.00,
"collectionTax": 0.30,
"collectionTaxable": true,
"deliveryPrice": 2.00,
"deliveryTax": 0.30,
"deliveryTaxable": true,
"dineInPrice": 2.00,
"dineInTax": 0.30,
"dineInTaxable": true,
"takeawayPrice": 2.00,
"takeawayTax": 0.30,
"takeawayTaxable": true
}
],
"charges": [],
"availabilityOverrides": []
}
]
}
],
"categoryGroups": [
{
"id": "a0000001-0000-4000-8000-000000000001",
"name": "Food",
"description": "All food categories",
"imageUrl": null,
"categoryIds": ["c0000001-0000-4000-8000-000000000001"]
}
]
}