> ## Documentation Index
> Fetch the complete documentation index at: https://firespark.cloud/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Multi-level modifier groups

> Three levels of nested modifier groups on a combo product.

Some POS flows ask follow-up questions only after a prior choice — pick a burger, then a patty, then a doneness. In Fire spark, **modifiers are products**. A modifier can list nested groups in `modifier_group_ids`, and its `pricing.modifiers` entry describes how it appears inside the group that lists it.

## What this example includes

| Level | Parent / group                   | Modifier product | Nested group      |
| ----- | -------------------------------- | ---------------- | ----------------- |
| 1     | `meal-combo` → `choose-burger`   | `cheeseburger`   | `choose-patty`    |
| 2     | `cheeseburger` → `choose-patty`  | `beef-patty`     | `choose-doneness` |
| 3     | `beef-patty` → `choose-doneness` | `medium-rare`    | —                 |

```mermaid theme={null}
flowchart TB
    COMBO["meal-combo"]
    COMBO --> G1["choose-burger"]
    G1 --> CB["cheeseburger"]
    CB --> G2["choose-patty"]
    G2 --> BEEF["beef-patty"]
    BEEF --> G3["choose-doneness"]
    G3 --> MR["medium-rare"]
    G3 --> WD["well-done"]
```

## Request

All products and groups live in the same [Upsert menus](/docs/integrations-api/menus/put) payload. Attach the next group on the modifier product the customer selects at the previous level.

```bash theme={null}
curl --request PUT \
  --url 'https://firespark.cloud/api/integrations/v1/menus?fulfillment_id=delivery&store_id=downtown&channel_id=app&brand_id=0001' \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d @multi-level-modifiers.json
```

```json multi-level-modifiers.json theme={null}
{
  "style": "DEFAULT",
  "products": [
    {
      "id": "meal-combo",
      "name": { "en_us": "Meal combo" },
      "description": { "en_us": "Burger and a drink." },
      "image_url": null,
      "status": "ACTIVE",
      "bundled_items": [],
      "pricing": {
        "minimum_quantity": 1,
        "maximum_quantity": 5,
        "is_tax_inclusive": true,
        "tax_rate": 0.15,
        "price": 10.99,
        "anchor_price": 10.99,
        "anchor_price_percentage": 0,
        "modifier_group_ids": ["choose-burger"],
        "modifiers": []
      },
      "availability": {
        "status": "AVAILABLE",
        "schedules": null,
        "out_of_stock_until": null
      },
      "metadata": {}
    },
    {
      "id": "cheeseburger",
      "name": { "en_us": "Cheeseburger" },
      "description": null,
      "image_url": null,
      "status": "ACTIVE",
      "bundled_items": [],
      "pricing": {
        "minimum_quantity": 0,
        "maximum_quantity": 1,
        "is_tax_inclusive": true,
        "tax_rate": 0.15,
        "price": 0,
        "anchor_price": 0,
        "anchor_price_percentage": 0,
        "modifier_group_ids": ["choose-patty"],
        "modifiers": [
          {
            "modifier_group_id": "choose-burger",
            "minimum_quantity": 0,
            "maximum_quantity": 1,
            "is_tax_inclusive": true,
            "tax_rate": 0.15,
            "price": 0,
            "anchor_price": 0,
            "anchor_price_percentage": 0,
            "default_quantity": 0,
            "charge_above_quantity": 0,
            "display_type": "RADIO"
          }
        ]
      },
      "availability": {
        "status": "AVAILABLE",
        "schedules": null,
        "out_of_stock_until": null
      },
      "metadata": {}
    },
    {
      "id": "veggie-burger",
      "name": { "en_us": "Veggie burger" },
      "description": null,
      "image_url": null,
      "status": "ACTIVE",
      "bundled_items": [],
      "pricing": {
        "minimum_quantity": 0,
        "maximum_quantity": 1,
        "is_tax_inclusive": true,
        "tax_rate": 0.15,
        "price": 0,
        "anchor_price": 0,
        "anchor_price_percentage": 0,
        "modifier_group_ids": [],
        "modifiers": [
          {
            "modifier_group_id": "choose-burger",
            "minimum_quantity": 0,
            "maximum_quantity": 1,
            "is_tax_inclusive": true,
            "tax_rate": 0.15,
            "price": 0,
            "anchor_price": 0,
            "anchor_price_percentage": 0,
            "default_quantity": 0,
            "charge_above_quantity": 0,
            "display_type": "RADIO"
          }
        ]
      },
      "availability": {
        "status": "AVAILABLE",
        "schedules": null,
        "out_of_stock_until": null
      },
      "metadata": {}
    },
    {
      "id": "beef-patty",
      "name": { "en_us": "Beef patty" },
      "description": null,
      "image_url": null,
      "status": "ACTIVE",
      "bundled_items": [],
      "pricing": {
        "minimum_quantity": 0,
        "maximum_quantity": 1,
        "is_tax_inclusive": true,
        "tax_rate": 0.15,
        "price": 0,
        "anchor_price": 0,
        "anchor_price_percentage": 0,
        "modifier_group_ids": ["choose-doneness"],
        "modifiers": [
          {
            "modifier_group_id": "choose-patty",
            "minimum_quantity": 0,
            "maximum_quantity": 1,
            "is_tax_inclusive": true,
            "tax_rate": 0.15,
            "price": 0,
            "anchor_price": 0,
            "anchor_price_percentage": 0,
            "default_quantity": 0,
            "charge_above_quantity": 0,
            "display_type": "RADIO"
          }
        ]
      },
      "availability": {
        "status": "AVAILABLE",
        "schedules": null,
        "out_of_stock_until": null
      },
      "metadata": {}
    },
    {
      "id": "veggie-patty",
      "name": { "en_us": "Veggie patty" },
      "description": null,
      "image_url": null,
      "status": "ACTIVE",
      "bundled_items": [],
      "pricing": {
        "minimum_quantity": 0,
        "maximum_quantity": 1,
        "is_tax_inclusive": true,
        "tax_rate": 0.15,
        "price": 0,
        "anchor_price": 0,
        "anchor_price_percentage": 0,
        "modifier_group_ids": [],
        "modifiers": [
          {
            "modifier_group_id": "choose-patty",
            "minimum_quantity": 0,
            "maximum_quantity": 1,
            "is_tax_inclusive": true,
            "tax_rate": 0.15,
            "price": 0,
            "anchor_price": 0,
            "anchor_price_percentage": 0,
            "default_quantity": 0,
            "charge_above_quantity": 0,
            "display_type": "RADIO"
          }
        ]
      },
      "availability": {
        "status": "AVAILABLE",
        "schedules": null,
        "out_of_stock_until": null
      },
      "metadata": {}
    },
    {
      "id": "medium-rare",
      "name": { "en_us": "Medium rare" },
      "description": null,
      "image_url": null,
      "status": "ACTIVE",
      "bundled_items": [],
      "pricing": {
        "minimum_quantity": 0,
        "maximum_quantity": 1,
        "is_tax_inclusive": true,
        "tax_rate": 0.15,
        "price": 0,
        "anchor_price": 0,
        "anchor_price_percentage": 0,
        "modifier_group_ids": [],
        "modifiers": [
          {
            "modifier_group_id": "choose-doneness",
            "minimum_quantity": 0,
            "maximum_quantity": 1,
            "is_tax_inclusive": true,
            "tax_rate": 0.15,
            "price": 0,
            "anchor_price": 0,
            "anchor_price_percentage": 0,
            "default_quantity": 0,
            "charge_above_quantity": 0,
            "display_type": "RADIO"
          }
        ]
      },
      "availability": {
        "status": "AVAILABLE",
        "schedules": null,
        "out_of_stock_until": null
      },
      "metadata": {}
    },
    {
      "id": "well-done",
      "name": { "en_us": "Well done" },
      "description": null,
      "image_url": null,
      "status": "ACTIVE",
      "bundled_items": [],
      "pricing": {
        "minimum_quantity": 0,
        "maximum_quantity": 1,
        "is_tax_inclusive": true,
        "tax_rate": 0.15,
        "price": 0,
        "anchor_price": 0,
        "anchor_price_percentage": 0,
        "modifier_group_ids": [],
        "modifiers": [
          {
            "modifier_group_id": "choose-doneness",
            "minimum_quantity": 0,
            "maximum_quantity": 1,
            "is_tax_inclusive": true,
            "tax_rate": 0.15,
            "price": 0,
            "anchor_price": 0,
            "anchor_price_percentage": 0,
            "default_quantity": 0,
            "charge_above_quantity": 0,
            "display_type": "RADIO"
          }
        ]
      },
      "availability": {
        "status": "AVAILABLE",
        "schedules": null,
        "out_of_stock_until": null
      },
      "metadata": {}
    }
  ],
  "categories": [
    {
      "id": "combos",
      "name": { "en_us": "Combo meals" },
      "description": null,
      "status": "ACTIVE",
      "items": [{ "type": "PRODUCT", "id": "meal-combo" }],
      "availability": {
        "status": "AVAILABLE",
        "schedules": null,
        "out_of_stock_until": null
      },
      "metadata": {}
    }
  ],
  "modifier_groups": [
    {
      "id": "choose-burger",
      "title": { "en_us": "Choose a burger" },
      "description": null,
      "display_type": "LIST",
      "modifier_ids": ["cheeseburger", "veggie-burger"],
      "minimum_quantity": 1,
      "maximum_quantity": 1,
      "charge_above_quantity": null,
      "metadata": {}
    },
    {
      "id": "choose-patty",
      "title": { "en_us": "Choose a patty" },
      "description": null,
      "display_type": "LIST",
      "modifier_ids": ["beef-patty", "veggie-patty"],
      "minimum_quantity": 1,
      "maximum_quantity": 1,
      "charge_above_quantity": null,
      "metadata": {}
    },
    {
      "id": "choose-doneness",
      "title": { "en_us": "Choose doneness" },
      "description": null,
      "display_type": "LIST",
      "modifier_ids": ["medium-rare", "well-done"],
      "minimum_quantity": 1,
      "maximum_quantity": 1,
      "charge_above_quantity": null,
      "metadata": {}
    }
  ],
  "menus": [
    {
      "id": "all-day-delivery",
      "name": { "en_us": "All-day delivery" },
      "description": null,
      "schedules": null,
      "metadata": {},
      "category_ids": ["combos"],
      "status": "ACTIVE"
    }
  ]
}
```

## Key points

* **Nest through modifier products.** Each level is a real product with its own external `id` for kitchen tickets and order injection.
* **`modifiers` describes the option in a group.** `beef-patty` carries a `pricing.modifiers` entry with `modifier_group_id: "choose-patty"`.
* **`modifier_group_ids` opens the next question.** `cheeseburger` lists `choose-patty` so patty choices appear after the customer picks cheeseburger.
* **Leaf modifiers have empty nested groups.** `medium-rare` sets `modifier_group_ids: []` because the chain ends there.
* **Branching paths.** `veggie-burger` skips patty and doneness groups because it has no nested `modifier_group_ids`.

## Related

<CardGroup cols={2}>
  <Card title="Products — modifier groups" icon="list-tree" href="/docs/concepts/products">
    How groups and modifiers relate
  </Card>

  <Card title="Simple menu" icon="utensils" href="/docs/integrations-api/examples/menu-sync/simple-menu">
    Single-level modifier example
  </Card>
</CardGroup>
