Skip to main content

Menu Create

Creating Menus

The MenuCreate mutation enables integrators to create market-ready location level menus. Due to the size of menu creation requests, when one is received we return a menuCreationRequestId and enqueue the menu to be processed asynchronously. The provided UUID can be used with the Menu Creation Request query to retrieve detailed information about the status of the specific menu creation request. To be automatically infromed when the request has completed and this information is available we recommend Subscribing to Menu Notifications.

Note: Please make sure to validate the Menu Schema Reference before making your MenuCreate request.

Mutation

Mutation

mutation MenuCreate($menu: MenuInput!) {
menuCreate(menu: $menu) {
errors {
details
message
}
success
menuCreationRequestId
}
}

Variables

Variables

{
"menu": {
"name": "Your Menu Name",
"locationId": "ezcater-caterer-id",
"posId": "your-menu-version-id",
"startDate": "2025-05-01",
"endDate": "2025-06-01",
"categories": [
{
"name": "Pizzas",
"posId": "pizzas-category-id",
"sortOrder": 2,
"description": "A selection of our famous pizzas",
"itemPosIds": [
"margherita-pizza-item-id"
]
},
{
"name": "Desserts",
"posId": "desserts-category-id",
"sortOrder": 3,
"description": "A selection of our amazing desserts",
"itemPosIds": [
"chocolate-cake-item-id"
]
},
{
"name": "Drinks",
"posId": "drinks-category-id",
"sortOrder": 4,
"description": null,
"itemPosIds": [
"assorted-sodas-item-id"
]
}
],
"items": [
{
"name": "Margherita Pizza",
"posId": "margherita-pizza-item-id",
"channels": ["MARKETPLACE"],
"imageUrl": "https://your-domain.com/menu-item-images/margherita-pizza.jpg",
"selections": [
{
"price": 16.75,
"posId": "12-inch-pizza-item-selection-id",
"size": "12\" Pizza",
"serves": 2,
"minCalories": 512,
"maxCalories": 1024,
"sortOrder": 1
},
{
"price": 24.75,
"posId": "16-inch-pizza-item-selection-id",
"size": "16\" Pizza",
"serves": 4,
"minCalories": 512,
"maxCalories": 1024,
"sortOrder": 1
},
{
"price": 32.75,
"posId": "20-inch-pizza-item-selection-id",
"size": "20\" Pizza",
"serves": 8,
"minCalories": 512,
"maxCalories": 1024,
"sortOrder": 1
}
],
"description": "Thin crust margherita pizza",
"taxCategory": "PREPARED_FOOD",
"quantityUnit": "PIZZA",
"itemTypeTags": [],
"optionPosIds": [
"cheese-addon-options-id"
],
"foodLabelingTags": ["POPULAR","VEGETARIAN"],
"individualWrapStatus": "NEVER"
},
{
"name": "Chocolate Cake",
"posId": "chocolate-cake-item-id",
"channels": ["MARKETPLACE"],
"imageUrl": null,
"selections": [
{
"price": 5.75,
"posId": "chocolate-cake-item-selection-id",
"size": "1",
"serves": 5,
"sortOrder": 1
}
],
"description": "Rich and creamy flourless dark chocolate cake",
"taxCategory": "CAKES_AND_PIES",
"quantityUnit": "CAKE",
"itemTypeTags": ["DESSERT"],
"optionPosIds": [],
"foodLabelingTags": ["GLUTEN_FREE"]
},
{
"name": "Assorted Sodas",
"posId": "assorted-sodas-item-id",
"channels": ["MARKETPLACE"],
"imageUrl": null,
"selections": [
{
"price": 2.75,
"posId": "assorted-sodas-item-selection-id",
"size": "2ltr Soda",
"serves": 4,
"sortOrder": 1
}
],
"description": "Assorted 2 liter soda bottles",
"taxCategory": "SODA",
"quantityUnit": "TWO_LITER",
"itemTypeTags": ["DRINKS"],
"optionPosIds": [
"soda-options-id"
],
"foodLabelingTags": ["GLUTEN_FREE", "VEGAN", "VEGETARIAN"]
}
],
"options": [
{
"name": "Cheese Addon",
"posId": "cheese-addon-options-id",
"catererLabel": "Cheese",
"choicePosIds": [
"feta-choice-id",
"parmigiano-reggiano-choice-id",
"parmesan-choice-id"
],
"customerPrompt": "Add Additional Cheese?",
"maxChoiceSelections": null,
"minChoiceSelections": 2
},
{
"name": "Soda",
"posId": "soda-options-id",
"catererLabel": "Soda",
"choicePosIds": [
"brand-name-soda-choice-id",
"diet-brand-name-soda-choice-id"
],
"customerPrompt": "Select Soda",
"maxChoiceSelections": 1,
"minChoiceSelections": 1
}
],
"choices": [
{
"name": "Feta",
"posId": "feta-choice-id",
"selections": [
{
"price": 1.75,
"posId": "feta-choice-12-inch-selection-id",
"sortOrder": 1
},
{
"price": 3.75,
"posId": "feta-choice-16-inch-selection-id",
"sortOrder": 2
},
{
"price": 5.75,
"posId": "feta-choice-20-inch-selection-id",
"sortOrder": 3
}
],
"description": "Feta cheese",
"choiceTypeTags": [],
"foodLabelingTags": ["VEGETARIAN"],
"enableSubQuantities": false
},
{
"name": "Parmigiano Reggiano",
"posId": "parmigiano-reggiano-choice-id",
"selections": [
{
"price": 1.75,
"posId": "parmigiano-reggiano-choice-12-inch-selection-id",
"sortOrder": 1
},
{
"price": 3.75,
"posId": "parmigiano-reggiano-choice-16-inch-selection-id",
"sortOrder": 2
},
{
"price": 5.75,
"posId": "parmigiano-reggiano-choice-20-inch-selection-id",
"sortOrder": 3
}
],
"description": "Parmigiano Reggiano cheese",
"choiceTypeTags": [],
"foodLabelingTags": ["VEGETARIAN"],
"enableSubQuantities": false
},
{
"name": "Parmesan",
"posId": "parmesan-choice-id",
"selections": [
{
"price": 1.75,
"posId": "parmesan-choice-12-inch-selection-id",
"sortOrder": 1
},
{
"price": 3.75,
"posId": "parmesan-choice-16-inch-selection-id",
"sortOrder": 2
},
{
"price": 5.75,
"posId": "parmesan-choice-20-inch-selection-id",
"sortOrder": 3
}
],
"description": "Parmesan cheese",
"choiceTypeTags": [],
"foodLabelingTags": ["VEGETARIAN"],
"enableSubQuantities": false
},
{
"name": "Brand Name Soda",
"posId": "brand-name-soda-choice-id",
"selections": [
{
"price": 0.0,
"posId": "brand-name-soda-selection-id",
"sortOrder": 1
}
],
"description": "Refreshing Brand Name Soda",
"choiceTypeTags": ["DRINKS"],
"foodLabelingTags": [],
"enableSubQuantities": false
},
{
"name": "Diet Brand Name Soda",
"posId": "diet-brand-name-soda-choice-id",
"selections": [
{
"price": 0.0,
"posId": "diet-brand-name-soda-choice-selection-id",
"sortOrder": 1
}
],
"description": "Refreshing Diet Brand Name Soda",
"choiceTypeTags": ["DRINKS"],
"foodLabelingTags": [],
"enableSubQuantities": false
}
]
}
}

Variables - NULL

{
"menu": {
"name": null,
"locationId": null,
"posId": null,
"startDate": null,
"endDate": null,
"categories": [
{
"description": null,
"itemPosIds": null,
"name": null,
"posId": null,
"sortOrder": null
}
],
"items": [
{
"catererNote": null,
"channels": null,
"dayBeforeCutoffTime": null,
"description": null,
"description2": null,
"foodLabelingTags": null,
"imageUrl": null,
"individualWrapStatus": null,
"itemTypeTags": null,
"leadTime": null,
"name": null,
"optionPosIds": null,
"posId": null,
"quantityOptions": null,
"quantityUnit": null,
"selections": [
{
"maxCalories": null,
"minCalories": null,
"posId": null,
"price": null,
"serves": null,
"size": null,
"sortOrder": null
}
],
"selectionPrompt": null,
"sizeLabel": null,
"sortOrder": null,
"taxCategory": null,
"vegetarianOption": null
}
],
"options": [
{
"catererLabel": null,
"choicePosIds": null,
"customerPrompt": null,
"maxChoiceSelections": null,
"minChoiceSelections": null,
"name": null,
"posId": null
}
],
"choices": [
{
"catererNote": null,
"choiceTypeTags": null,
"defaultChoice": null,
"description": null,
"enableSubQuantities": null,
"foodLabelingTags": null,
"name": null,
"posId": null,
"selections": [
{
"posId": null,
"price": null,
"sortOrder": null
}
],
"sortOrder": null
}
]
}
}

Arguments

Argument Name

Description

menu: MenuInput!

Input object for creating a new menu.

Return Type

Success Response

When the menuCreate mutation succeeds you can expect the response payload to look like:

Response

{
"data": {
"menuCreate": {
"errors": [],
"menuCreationRequestId": "your-ezcater-menu-creation-request-id",
"success": true
}
}
}

Failure Response

Not authenticated

When an the user is unable to be authenticated.

Response

{
"errors": [
{
"message": "Not authenticated.",
"extensions": {
"code": "ERR_UNAUTHENTICATED"
}
}
]
}

400 Bad Request

When the menuCreate mutation fails due to bad user input you can expect a HTTP 400 Bad Request and the response payload to look like:

Response - Required Field

{
"errors": [
{
"message": "Variable \"$menu\" got invalid value { name: \"Your Menu Name\", locationId: \"ezcater-caterer-id\", posId: \"your-menu-version-id\", startDate: \"2025-04-16\", endDate: \"2025-04-26\", items: [[Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], ... 11 more items], options: [[Object], [Object], [Object], [Object], [Object], [Object], [Object]], choices: [[Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], ... 7 more items] }; Field \"categories\" of required type \"[CategoryInput!]!\" was not provided.",
"extensions": {
"code": "BAD_USER_INPUT"
}
}
]
}

Response - Invalid Field Value

{
"errors": [
{
"message": "Variable \"$menu\" got invalid value null at \"menu.items[1].selections[0].price\"; Expected non-nullable type \"Float!\" not to be null.",
"extensions": {
"code": "BAD_USER_INPUT"
}
}
]
}
Did this answer your question?