Editing menus using the menus edit API

You can use the menus edit API to automate menu data updates.

Currently, the menus edit API has the following endpoints:

  • /price-levels/search: Send a POST request to this endpoint to search for and retrieve identifiers for price level versions.

  • /price-levels/{versionId}: Send a PATCH request to this endpoint to update prices for price level versions. You can only update price level versions that use the base price pricing strategy (also known as the DEFAULT pricing strategy).

Note

This section assumes you are familiar with the concepts of multi-location management, including versions, targets, and location group hierarchy (formerly known as restaurant group hierarchy). It also assumes you are familiar with price levels.

Required scopes for menus edit API

Scopes control access to Toast APIs. The /price-levels/search endpoint requires the menus.saved:read scope. The /price-levels/{versionId} endpoint requires the menus:write scope.

Publishing menus edit API updates through Toast Web

When you use the menus edit API to update menu data, the updates you make are applied to the saved database. To make the data in the saved database visible to guests and employees, you must publish it from Toast Web. Use the instructions in Publishing changes for multiple locations to publish your menu data updates.

Updating price levels using the menus edit API

The menus edit API is designed to work with the multi-location module, meaning you can use the API to edit objects that have been versioned. Price levels are one of the Toast data objects that can be versioned. For example, you can have a price level named Bottled Sodas with two versions, one targeted at the Corporate group whose price is $5 and another targeted at the Boston location whose price is $6.

To update price levels, you retrieve identifiers for the price level versions you want to update, and then you use those identifiers when submitting the update request.

Retrieving identifiers for price level versions

When using the /price-levels/search endpoint to search for price level versions, you can provide a price level name, an array of targets, neither, or both in the JSON request body.

  • Providing a name value only

    The menus edit API returns all price level versions whose name contains the string you provided in the name value.

    The JSON body for a request of this type looks like this:

    {   "name": "Sodas"
    }

    Note

    If you do not want to provide a name to search for, you can omit the name value in the JSON body or you can set name to null. You cannot use an empty string.

  • Providing a targets array only

    The targets array contains an object for each target. Within each target object, use the id value to specify the GUID of a location or a location group.

    The menus edit API returns price level versions whose targets match the IDs you specify in the targets array. It also returns price level versions for the ancestors of the targets you specify in the targets array.

    The JSON body for a request of this type looks like this:

    {   "targets": [
            {
                "id": "8851dd21-4919-1928-ab78-d19b27d7b43c"
            },
            {
                "id": "3aef1d87-4c74-44ca-90bd-5ed1dfe4c956"
            }
        ]
    }
  • Providing a name value and a targets array

    The name value contains the string to search for.

    The targets array contains a Target object for each target. Within each Target object, use the id value to specify the GUID of a location or a location group.

    The menus edit API returns price level versions whose targets match the IDs you specify in the targets array and whose names contain the string specified in the name value. It also returns price level versions for the ancestors of the targets you specify in the targets array and that have names that contain the name value.

    The JSON body for a request of this type looks like this:

    {   "name": "Sodas",
        "targets": [
            {
                "id": "8851dd21-4919-1928-ab78-d19b27d7b43c"
            },
            {
                "id": "3aef1d87-4c74-44ca-90bd-5ed1dfe4c956"
            }
        ]
    }
  • Providing neither a name value nor a targets array

    The API returns all price level versions for the session restaurant and any of its ancestors in the location group hierarchy.

    The JSON body for a request of this type looks like this:

    {   
    }

The response to a /price-levels/search request contains a paginated PriceLevelVersions object. This object looks similar to the following example, which shows the response for a request to return all price level versions targeted at the Boston location and its ancestors (Northeast and Corporate):

{
    "nextPageToken": "cDoyLHM6MQ==",
    "data": [
        {
            "versionId": "c0abdfdf-4f38-05ce-8c7c-84c406114551",
            "multiLocationId": "100000037266862802",
            "target": {
                "id": "ce2bf7ae-4f30-fefc-aefb-9a3562a3530b"
            },
            "owner": {
                "id": "ce2bf7ae-4f30-fefc-aefb-9a3562a3530b"
            },
            "name": "Bottled Sodas - Northeast",
            "basePrice": "5.00",
            "pricingStrategy": "DEFAULT",
            "minPrice": null,
            "maxPrice": null
        },
        {
            "versionId": "96749932-46a6-8c8c-bacd-7a5ccc3a6b91",
            "multiLocationId": "100000037266862802",
            "target": {
                "id": "8851dd21-4919-1928-ab78-d19b27d7b43c"
            },
            "owner": {
                "id": "8851dd21-4919-1928-ab78-d19b27d7b43c"
            },
            "name": "Bottled Sodas - Boston",
            "basePrice": "6.00",
            "pricingStrategy": "DEFAULT",
            "minPrice": null,
            "maxPrice": null
        },
        {
            "versionId": "7ecf8a13-4b96-3955-912a-72cf0daef269",
            "multiLocationId": "100000037266862804",
            "target": {
                "id": "5116fba9-4c19-1fd1-b9e4-97d1a3193d5a"
            },
            "owner": {
                "id": "5116fba9-4c19-1fd1-b9e4-97d1a3193d5a"
            },
            "name": "Fountain Sodas - Corporate",
            "basePrice": "4.00",
            "pricingStrategy": "DEFAULT",
            "minPrice": null,
            "maxPrice": null
        },
        {
            "versionId": "c8e2cd32-4c44-a410-9f0e-30351ba2c31c",
            "multiLocationId": "100000037266862802",
            "target": {
                "id": "5116fba9-4c19-1fd1-b9e4-97d1a3193d5a"
            },
            "owner": {
                "id": "5116fba9-4c19-1fd1-b9e4-97d1a3193d5a"
            },
            "name": "Bottled Sodas - Corporate",
            "basePrice": "5.00",
            "pricingStrategy": "DEFAULT",
            "minPrice": null,
            "maxPrice": null
        },

        [Contents omitted]
    ]
}

This paginated PriceLevelVersions response object contains a nextPageToken value and a data array:

  • For searches with less than 500 results, the nextPageToken is null, indicating there are no more results to page through. For searches with more than 500 results, the nextPageToken contains a string that identifies the following page of response data. You can use this string in subsequent searches to retrieve the next set of results, for example:

    {   "name": "Sodas",
        "targets": [
            {
                "id": "8851dd21-4919-1928-ab78-d19b27d7b43c"
            },
            {
                "id": "3aef1d87-4c74-44ca-90bd-5ed1dfe4c956"
            }
        ],
        "nextPageToken": "cDoyLHM6MQ=="
    }

    If you omit the nextPageToken or set it to null in the JSON body of the /price-levels/search request, then the first page of results is returned.

  • The data array contains a PriceLevelVersion object for each price level version that matches the search criteria:

            {
                "versionId": "c0abdfdf-4f38-05ce-8c7c-84c406114551",
                "multiLocationId": "100000037266862802",
                "target": {
                    "id": "ce2bf7ae-4f30-fefc-aefb-9a3562a3530b"
                },
                "owner": {
                    "id": "ce2bf7ae-4f30-fefc-aefb-9a3562a3530b"
                },
                "name": "Bottled Sodas - Northeast",
                "basePrice": "5.00",
                "pricingStrategy": "DEFAULT",
                "minPrice": null,
                "maxPrice": null
            },

    Each PriceLevelVersion object has a versionID value that contains a GUID that uniquely identifies this specific version of the price level. You use the versionID value when submitting update requests to the /price-levels/{versionId} endpoint.

    Each PriceLevelVersion object also contains a pricingStrategy value. You can only use the /price-levels/{versionId} endpoint to edit price level versions that use the DEFAULT pricing strategy (DEFAULT corresponds to base price).

Updating a price level version

You can update the price of price level versions that use the DEFAULT pricing strategy. To update the price of a price level version, submit a PATCH request to the /price-levels/{versionId} endpoint, replacing {versionID} with the GUID of the price level version you want to edit. In the JSON body of the request, provide a PriceLevelVersion object containing the basePrice value that replaces the existing base price. Do not include any value other than basePrice.

The JSON body for an update request looks similar to the following:

{
    "basePrice": "5.75"
}

The response to a /price-levels/{versionId} request is an object that contains the price level version's properties, including the new price you set. It looks similar to the following:

{
    "versionId": "96749932-46a6-8c8c-bacd-7a5ccc3a6b91",
    "multiLocationId": "100000037266862802",
    "target": {
        "id": "8851dd21-4919-1928-ab78-d19b27d7b43c"
    },
    "owner": {
        "id": "8851dd21-4919-1928-ab78-d19b27d7b43c"
    },
    "name": "Bottled Sodas - Boston",
    "basePrice": "5.75",
    "pricingStrategy": "DEFAULT",
    "minPrice": null,
    "maxPrice": null
}