Recipe & Menu Engineering Export API Guide

Introduction

With the Recipe & Menu Engineering (RME) Export API, you can access the recipe, ingredient and supplier data in Fourth for use on POS, stock and other systems.

Quick Facts

API type HTTP REST with JSON and XML
Authentication Basic authentication
Availability All customers using our Fourth Inventory for Restaurants solution
Testing A test environment is available
More information See the Export API Reference

Get access

To get started with this API, you will need:

  • A Recipe & Menu Engineering Export API account to access this API
  • The root URL for requests to both test and live environments

Your mutual Fourth customer must request credentials on your behalf. Please ensure they do this as soon as possible. The Fourth Professional Services team member managing the integration can provide the above information and help you with any integration questions you may have.

Updates

You can find any updates on the Release Notes page for this API.

Unique identifiers 

Each item or data concept available through this API — like ingredients, intolerances, or categories — has a unique identifier (GUID). In responses, the JSON property (or XML element) with the GUID is always appended with “Guid”; for example: 

  • IngredientGuid
  • IntoleranceGuid
  • CategoryGuid

Many of the resources have an option to include the GUID as a path parameter, so that you can get the details of a specific item. 

Category types

The Fourth Inventory for Restaurants solution has a hierarchy of user-defined categories. The top level category is category type, followed by main category and sub categories:

  1. Category Type
  2. Main Category
  3. SubCategory
  4. SubCategory
  5. SubCategory

In the API responses that include category information, you will see nested SubCategories to represent the above.

For Category Type, the API will include a flag to indicate whether it is a “smart” or “system” category. Smart categories align with categories in Fourth Inventory. Items can have multiple system categories, but typically have only one smart category. 

Groups

Groups (also called admin groups) are used to silo business units and data in Fourth. Groups enable customers to restrict access to data — such as menus or recipes — to user groups. For example, if there are separate brands run independently from one another (that require separate data) then these will be groups inside a parent group.

Each customer will have one or more API user groups set up by Fourth. This defines the data areas that users can access with the API. If you find requests to the API return blank results, it is likely that the API user group does not have permission to access the data.

Resources that are relevant to groups are:

  • admingroups and groups — returns the hierarchy and details of the groups
  • ingredients/{}/groups, menus/{}/groups, and recipes/{}/groups — for each ingredient, menu or recipe, this returns the groups that have access to that item. 

Support for Natasha's Law

The Food Information (Amendment) (England) Regulations 2019, also known as Natasha’s Law, requires food businesses to label all food that is ‘pre-packaged for direct sale’ with the complete ingredient and allergen details.

To support this legislation, each recipe and ingredient in Fourth has an ingredient list field, designed to hold their sub-ingredients and allergens. For example, the ingredient list for the ingredient pasta sauce would contain: tomato, basil, butter (Cow’s MILK, salt), onion, salt, pepper.

Ingredient lists are specifically designed to provide the text required for labels and displays. They do not replace any requirements you have to retrieve or supply nutrient and intolerance data for an ingredient.

An ingredient’s ingredient list is owned by the parent ingredient, as the ingredients and allergens should be identical between parent and alternate ingredients.

Customers or partners may need to see the changes that have occurred to ingredient lists over time; so this API provides endpoints (described below) for seeing the historical changes to ingredient lists. The history shows exactly what the ingredient list field was and each update that was made, who made the change, and when the change occurred.

Note that ingredient lists can hold far more data (beyond an order of magnitude) than any possible ingredient or recipe would contain, so treat these fields as having no maximum character limit.

Note that our Recipe & Menu Engineering Import API has additional endpoints related to Natasha’s Law. Please see the Import API Guide for more information.

Auditing ingredients

You can use these endpoints to get the audit history for an ingredient’s ingredient list:

  • GET /Ingredients/fullIngredientListHistory — retrieves an array of the ingredient list history for multiple ingredients
  • GET /Ingredients/{guid}/fullIngredientListHistory — retrieves the ingredient list history for a specified ingredient

Note that these endpoints return data only when the customer has the full ingredient list functionality enabled.

The response from both endpoints has the same format. In the example response below, the ingredient Butter Salted has the following changes:

  • On February 8th, the ingredient list changes from null to MILK.
  • On February 9th, the ingredient list changes from MILK to MILK, Salt.
  • On February 10th, the ingredient list changes from MILK, Salt to a blank string.
  • On February 11th, the ingredient list changes from a blank string to Cow's MILK, Salt.

The changes are all linked to the example login name: apipartner. When a customer edits the ingredient lists using the UI, the login name of the user is returned.

Example response

See the API Reference for more details on this response.

[
   {
      "ProductId": 139,
      "FullIngredientList": "Cow's MILK, Salt",
      "FirDate": "2021-02-10T16:06:02.503",
      "ProductGuid": "f6f1630f-1dc3-4e5e-ab56-e38240433cde",
      "ProductName": "Butter Salted",
      "History": [
         {
            "HistoryLogId": 2182,
            "ProductId": 139,
            "FullIngredientListFrom": "",
            "FullIngredientListTo": "Cow's MILK, Salt",
            "LoginName": " apipartner",
            "ModifyDate": "2021-02-11T12:12:03.003"
         },  
        {
            "HistoryLogId": 2148,
            "ProductId": 139,
            "FullIngredientListFrom": "MILK, Salt",
            "FullIngredientListTo": "",
            "LoginName": " apipartner",
            "ModifyDate": "2021-02-10T16:06:02.503"
         },
         {
            "HistoryLogId": 2128,
            "ProductId": 139,
            "FullIngredientListFrom": "MILK",
            "FullIngredientListTo": "MILK, Salt",
            "LoginName": " apipartner",
            "ModifyDate": "2021-02-09T19:03:31.923"
         },
         {
            "HistoryLogId": 2103,
            "ProductId": 139,
            "FullIngredientListFrom": null,
            "FullIngredientListTo": "MILK",
            "LoginName": " apipartner",
            "ModifyDate": "2021-02-08T18:56:48.043"
         }
      ]
   }
]

Auditing recipes

You can use these endpoints to get the audit history for a recipe’s ingredient list:

  • GET /Recipes/fullIngredientListHistory — retrieves an array of the ingredient list history for multiple recipes
  • GET /Recipes/{guid}/fullIngredientListHistory — retrieves the ingredient list history for a specified recipe

For recipes, there are two variations of ingredient lists:

  • Manual — this list is keyed in by the customer. It does not auto-update in any way.
  • Automatically generated — this list is generated by Fourth. It combines the ingredient list for each ingredient in the recipe into one list. The lists for each ingredient are included in parenthesis, with the ingredients listed in weight order, in descending order by the amount within the recipe.

The automatically generated list updates when:

  •  An ingredient's ingredient list is changed.
  •  An ingredient is added or removed from a recipe.
  •  A conversion is added or removed.
  •  A recipe is part of another recipe, and the preferred field (auto-generated or manual) for the sub-recipe changes.
  • The consumer-friendly name or main name fields for an ingredient or recipe change.

Screenshot showing the Ingredient Lists tab within Fourth. There are two fields for the two list types, each showing the ingredients for an Avocado and Crab salad. The allergens of ingredients are capitalized. “Use Automatic in report” is selected.

The auditing feature in Fourth tracks the ingredient list that was marked as “use in report” at the time. Therefore, the data in the response may vary between the automatically generated field and the manual field.

For example, if a user changes the “use in report” from manual to automatic, the audit history changes to track the updates to the automatic field. The API response would provide both data from the manual field (up until the point at which the change occurs) and the automatic field.

Login name recorded when a recipe is recalculated 

the login names returned by the API may be due to the user (or system) updating either the recipe or an ingredient that's part of the recipe.

If a change to an ingredient's ingredient list causes us to recalculate a recipe, then Fourth records the user name for the person (or system) that made the change to the ingredient. For example in the below, Guest 2 made a change to an ingredient's ingredient list, and the recipe history recorded their user name beside the action Auto Calculate.

Screenshot showing that Guest2 is recorded as the user name for an auto calculation event.

Example response

See the API Reference for more details on this response.

[
   {
      "ProductId": 74855,
      "FullIngredientList": " Tofu (SOYA), cornflour, garlic, rapeseed oil, smoked paprika, salt, pepper",
      "FirDate": "2021-03-22T13:33:55.97",
      "ProductGuid": "101ef8a8-e61e-4f8a-9485-e05ff3ee488c",
      "ProductName": "Salt and Pepper Tofu",
      "History": [
         {
            "HistoryLogId": 3455,
            "ProductId": 74855,
            "FullIngredientListFrom": "",
            "FullIngredientListTo": " Tofu (SOYA), cornflour, garlic, rapeseed oil, smoked paprika, salt, pepper",
            "LoginName": "apipartner2",
            "ModifyDate": "2021-03-22T13:33:55.97"
         },
         {
            "HistoryLogId": 3454,
            "ProductId": 74855,
            "FullIngredientListFrom": "Tofu (SOYA), cornflour, garlic, SEASAME oil, salt, pepper",
            "FullIngredientListTo": "",
            "LoginName": "dave",
            "ModifyDate": "2021-03-22T13:27:41.663"
         },
         {
            "HistoryLogId": 3453
            "ProductId": 74855,
            "FullIngredientListFrom": null,
            "FullIngredientListTo": "Tofu (SOYA), cornflour, garlic, SEASAME oil, salt, pepper",
            "LoginName": "dave",
            "ModifyDate": "2021-03-22T13:12:04.397"
         }
      ]
   }
]

Where to find more information about Natasha's Law

For more information about Natasha's Law:

Understanding alternate and parent ingredients

For our customers, there is often a need to be able to purchase the same product from more than one supplier. To support this, Fourth has the concept of a parent ingredient, under which you can have multiple alternate ingredients. An alternate ingredient can have a different supplier, purchase quantity, pack size, and cost price to the parent ingredient; but it always shares the same nutritional and intolerance properties. This means that in most cases the alternate ingredients are the same brand as the parent ingredient. For example, the alternate ingredient for a 12 x 400ml case of "Acme" diced tomatoes could be a 2 x 1 litre case of "Acme" diced tomatoes, from the same or a different supplier.

In the Fourth user interface, this is represented by the Supplied Pack Size tab. Each ingredient always has one supplied pack size (which is the "parent" ingredient) with additional pack sizes being "alternates". An alternate ingredient's pack size (supply quantity) can be defined using the parent ingredient base or conversion Unit of Measures (UoMs).

To support API users, our GET endpoints return the shared data — such as process data, nutrient and intolerance information — of the parent ingredient where necessary.

Each parent and alternate ingredient has its own unique GUID, which is returned in API responses.

Getting alternate ingredients

The two ingredient endpoints:

  • GET /ingredients — get all ingredients
  • GET /ingredients/{guid} — get an ingredient

return information on both parent and alternate ingredients. Ingredients that do not have alternates are, by default, parent ingredients.

The GET /ingredients endpoint returns the parent ingredient with the details of any alternate ingredients included as elements in the SuppliedPackSizes array. This array also includes the parent ingredient’s details. For example:

  • If an ingredient has no alternates, then the ingredient will have one SuppliedPackSize element in the SuppliedPackSizes array.
  • If an ingredient has alternates, then the ingredient will have a SuppliedPackSize element for the parent ingredient, and additional SuppliedPackSize elements for each alternate ingredient.

The GET /ingredients/{guid} endpoint returns the details of a parent or alternate ingredient by its GUID.

Example response

This response shows a parent ingredient with one alternate. In this example:

  • IngredientGuid — this is the GUID of the parent ingredient
  • SuppliedProductGUID:
    • The GUID in the first SuppliedPackSize element is the same as for the parent ingredient, as it is the parent ingredient’s details.
    • The GUID in the second SuppliedPackSize element is different, as this is for an alternate ingredient.

Note that for clarity, some of the sections in this example are truncated using ellipsis (...).

<Ingredients>
<Ingredient>
    <IngredientGuid>34489c7b-8462-4db2-bcc7-a3c0981da1b9</IngredientGuid>
    <Name>Champagne, Vintage</Name>
    <ProductType>Food</ProductType>
    <Sellable>false</Sellable>
    <ScheduledExportDate>2016-05-18T00:00:00Z</ScheduledExportDate>
    <ShortName/>
    <Description/>
    <InternalCode/>
    <ExternalCode/>
    <Wastage>0</Wastage>
    <UnitSize>
        <Quantity>100</Quantity>
        <UoMGuid>d171ac4d-033c-440f-929f-c70ff9e57d45</UoMGuid>
        <UoM>millilitre</UoM>
        <PackDescriber/>
    </UnitSize>
    <SuppliedPackSizes>
        <SuppliedPackSize>
            <StarChefKey>0015639</StarChefKey>
            <InternalCode/>
            <ExternalCode/>
            <SupplierGuid>dbfb1f23-6298-4c01-9d03-863253a42759</SupplierGuid>
            <SupplierName>Ingredient_Parent</SupplierName>
            <SuppliedProductName>Champagne, Vintage</SuppliedProductName>
            <PreferredSupplier>false</PreferredSupplier>
            <SupplierRef/>
            <SupplierCode>VCHAMP</SupplierCode>
            <DistributorGuid/>
            <DistributorName/>
            <DistributorRef/>
            <DistributorCode/>
            <CostPrice>0.00</CostPrice>
            <PendingCostPrice/>
            <PendingCostPriceEffectiveDate/>
            <SupplyQty>
                <Number>1</Number>
                <Quantity>750</Quantity>
                <UoMGuid>d171ac4d-033c-440f-929f-c70ff9e57d45</UoMGuid>
                <UoM>millilitre</UoM>
                <PackDescriber/>
                <PackageTypeGuid>d8d00c97-eb25-4c76-a4fe-b2998b4a8764</PackageTypeGuid>
            </SupplyQty>
            <SupplyQtyConversions>...</SupplyQtyConversions>
            <RankOrder>0</RankOrder>
            <Categories>...</Categories>
            <SuppliedProductGUID>34489c7b-8462-4db2-bcc7-a3c0981da1b9</SuppliedProductGUID>
        </SuppliedPackSize>
        <SuppliedPackSize>
            <StarChefKey>0016020</StarChefKey>
            <InternalCode/>
            <ExternalCode/>
            <SupplierGuid>6f568764-ab22-4181-a6e0-c690238f3031</SupplierGuid>
            <SupplierName>AAA</SupplierName>
            <SuppliedProductName>Champagne, Vintage 2012</SuppliedProductName>
            <PreferredSupplier>true</PreferredSupplier>
            <SupplierRef/>
            <SupplierCode>CH1</SupplierCode>
            <DistributorGuid/>
            <DistributorName/>
            <DistributorRef/>
            <DistributorCode/>
            <CostPrice>50.00</CostPrice>
            <PendingCostPrice/>
            <PendingCostPriceEffectiveDate/>
            <SupplyQty>
                <Number>1</Number>
                <Quantity>1</Quantity>
                <UoMGuid>8c9faae0-e7ba-43c7-962f-d82314c1d267</UoMGuid>
                <UoM>litre</UoM>
                <PackDescriber/>
                <PackageTypeGuid>d8d00c97-eb25-4c76-a4fe-b2998b4a8764</PackageTypeGuid>
            </SupplyQty>
            <SupplyQtyConversions>...</SupplyQtyConversions>
            <RankOrder>1</RankOrder>
            <Categories>...</Categories>
            <SuppliedProductGUID>ec5c2d99-f07f-4413-9d65-d3770547eb22</SuppliedProductGUID>
        </SuppliedPackSize>
    </SuppliedPackSizes>
    <FlagType/>
    <FlagExpiry/>
    <FlagSetOn/>
    <DateCreated>2015-08-06T16:29:24Z</DateCreated>
    <DateLastUpdated>2020-12-15T13:24:22Z</DateLastUpdated>
    <Portions/>
</Ingredient>
</Ingredients>

Displaying alternate and add-on items in a POS

For customers using Recipe & Menu Engineering standalone, there are additional options that may be useful for showing alternate and add-on items in the POS system. They need to initially be enabled in Fourth for the customer, after which the customer can create the recipe types.

Choice recipes

These recipes are used to manage alternatives within a main recipe. For example, the customer may have three potato options (chips, mashed, and sweet) that they offer diners for no additional charge. One of the choices will be the default choice — this recipe is included in the cost, nutrition, and intolerance values for the main recipe.

For the general-detail recipe endpoints:

  • /recipes
  • /recipes/{guid}
  • /recipes/optimized
  • /recipes/optimized/{guid}

The Type value identifies if it is a Choice recipe:

"RecipeGuid": "6c3fec7d-97c9-48f8-b84e-13bb179b9fa6",
"PLU": "PLUCode",
"StarChefKey": "00123567",
"Type": "Choice",
"Name": "mashed potato",

For the main recipe, the available choice recipes are listed in the response sent back for these endpoints:

  • /recipes
  • /recipes/{guid}
  • /recipes/optimized
  • /recipes/optimized/{guid}

The choice recipes are listed in the RecipeIngredients array. The default choice recipe will have a value of true for ChoiceDefault, while alternative recipes will be false. All other recipes and ingredients will have a null value for ChoiceDefault.

   "RecipeIngredients": [
      {
         "RecipeIngredientType": "Choice Recipe",
         "RecipeIngredientGuid": "10b9d9a1-d97c-4699-be97-fa57a8a3b779",
         "RecipeIngredientName": "Dauphinoise potatoes",
         "WastageRemoved": "",
         "ChoiceDefault": "false",
         ...
      }
   ]

Option recipes

Option recipes are used to manage add-ons to a main recipe that are normally charged. For example, a main recipe may allow for charged add-ons such as avocado or cheese.

For the general-detail recipe endpoints:

  • /recipes
  • /recipes/{guid}
  • /recipes/optimized
  • /recipes/optimized/{guid}

The Type value identifies if it is an Option recipe:

"RecipeGuid": "6c3fec7d-97c9-48f8-b84e-13bb179b9fa6",
"PLU": "PLUCode",
"StarChefKey": "00123567",
"Type": "Option",
"Name": "Goats Cheese",
...

For the main recipe, the available option recipes are listed in the response sent back for these endpoints:

  • /recipes
  • /recipes/{guid}
  • /recipes/optimized
  • /recipes/optimized/{guid}

The option recipes are listed in the RecipeIngredients array:

   "RecipeIngredients": [
      {
         "RecipeIngredientType": "Option Recipe",
         "RecipeIngredientGuid": "10ab9d91-dc97-9959-e9b7-648a3b537",
         "RecipeIngredientName": "Goats Cheese",
         "WastageRemoved": "",
         "ChoiceDefault": "",
         ...
      }
   ]

Resources

For the list of endpoints and methods, see the Export API Reference. Fourth will provide you with the base path for requests.

Filtering menu, recipe and ingredient results 

You can filter results from the ingredients, menus and recipes resources using query parameters. You can find the available filters for each endpoint in the API Reference.

For example, this request will return only menus created from 2016 onwards: 

<ROOT>/Menus?createdAfter=2016-01-01

You can include multiple parameters in the request to filter results further. For example, imagine a major menu revision in April 2018 occurred to menus. You could look for menus that needed updating by comparing the previous results with the following: 

<ROOT>/Menus?createdAfter=2016-01-01&lastModifiedAfter=2018-04-01

This would provide a list of all the menus that were created after 2016, and had been revised after the start of April. You would just need to subtract these from your original list to find any menus that had not had updates in April.

scheduledExportAfter filter

In the Fourth UI, customers can set the Scheduled Export After field for menus, recipes and ingredients. This is an editable field that allows customers to add a date for their own custom use cases, and it is otherwise ignored from within Fourth. For example, it allows customers to set their own dates for filtering and reviewing records in an external reporting tool.

Specifying this parameter will return only records with a date on or after any set Scheduled Export After date. The default value for this field is the “created on” date. 

Request header

For all requests, you must provide your authentication details using Basic authentication in the header.

Example header:
GET /Recipes/12345/preparation  HTTP/1.1
Host: instance.example.com
Authorization: Basic VXNlcm5hbWU6cGFzc3dvcmQ=
Field Description
Authorization

Your Recipes & Menu Engineering Export ID and password, separated by a colon, and then base64 encoded. Your ID and password are case-sensitive. 

Content-Type The data format you are using for POST request. Options are: application/json, text/json, application/xml, text/xml.

Response 

Successful requests

Successful GET requests receive an HTTP 200 OK response with the data requested in the response body. 

Unsuccessful requests

Unsuccessful requests receive an HTTP 400-599 response, with an error message in the response body. 

Example responses

Ingredient or recipe intolerance history request

This example applies to any of the /intolerancehistory endpoints. Note that the example does not include the recipe or ingredient specific XML elements that start and end the full response.

In the example, the following events occur:

  • Add: The value for Contains Molluscs changes from null to N (no).
  • Remove: The value for Contains Milk or Milk Products changes from Y (yes) to null.
  • Modify: The value for Contains Soya changes from M (may contain) to Y
    <Name>House Dressing</Name>
    <IntoleranceItems>
      <IntoleranceItem>
        <Name>Contains Molluscs</Name>
        <Events>
          <Event>
            <To>Y</To>
            <Id>22796</Id>
            <ChangeDate>2020-06-03T09:04:59.91</ChangeDate>
            <UserId>brad</UserId>
            <Action>Add</Action>
          </Event>
        </Events>
      </IntoleranceItem>
      <IntoleranceItem>
        <Name>Contains Milk or Milk Products</Name>
        <Events>
          <Event>
            <From>Y</From>
            <Id>22823</Id>
            <ChangeDate>2020-06-03T09:20:16.673</ChangeDate>
            <UserId>brad</UserId>
            <Action>Remove</Action>
          </Event>
      </IntoleranceItem>
      <IntoleranceItem>
        <Name>Contains Soya</Name>
        <Events>
          <Event>
            <From>M</From>
            <To>Y</To> 
            <Id>22823</Id>
            <ChangeDate>2020-06-03T10:03:23.125</ChangeDate>
            <UserId>brad</UserId>
            <Action>Modify</Action>
          </Event>
      </IntoleranceItem>
    </IntoleranceItems>

Recipe preparation request

The following shows the response to a recipe preparation request. Note that, for the <image> elements, the content is truncated to make this example simpler to read.  

<?xml version="1.0" encoding="utf-8"?>
<RecipePreparations>
   <RecipePreparation>
      <RecipeGuid>eb8c2bed-f8ed-4c3b-89b0-2034b3400f9f</RecipeGuid>
      <Name>Toast</Name>
      <Method>
         <ContentType>text/plain</ContentType>
         <MethodList>
            <Step>
               <Text>Toast bread in a toaster until brown but not burnt.</Text>
               <Image />
               <Order>1</Order>
            </Step>
            <Step>
               <Text>Add avocado and drizzle with oil.</Text>
               <Image />
               <Order>2</Order>
            </Step>
            <Step>
               <Text>Top with cherry tomatoes.  Lay the toast on a service plate and arrange a salad garnish to one side.</Text>
               <Image />
               <Order>3</Order>
            </Step>
            <Step>
               <Text>Drizzle the salad garnish with the dressing and serve immediately.</Text>
               <Image />
               <Order>4</Order>
            </Step>
         </MethodList>
      </Method>
      <MiseEnPlace>
         <ContentType>text/plain</ContentType>
         <MiseEnPlaceList>
            <Step>
               <Text>Slice bread and cherry tomatoes and store.</Text>
               <Image />
               <Order>1</Order>
            </Step>
            <Step>
               <Text>Prepare salad garnishes as per recipe.</Text>
               <Image />
               <Order>2</Order>
            </Step>
         </MiseEnPlaceList>
      </MiseEnPlace>
      <Ccp>
         <ContentType>text/plain</ContentType>
         <CcpList>
            <Step>
               <Text>Wash hands first</Text>
               <Image>...</Image>
               <Order>1</Order>
            </Step>
            <Step>
               <Text>Do not freeze</Text>
               <Image>...</Image>
               <Order>2</Order>
            </Step>
            <Step>
               <Text>Salad and Fruit Chopping Board</Text>
               <Image>...</Image>
               <Order>3</Order>
            </Step>
         </CcpList>
      </Ccp>
      <Service>
         <ContentType>text/plain</ContentType>
         <Service />
         <ServiceVehicleText>10 inch white plate for toast plus small white bowl for salad garnish.</ServiceVehicleText>
      </Service>
   </RecipePreparation>
</RecipePreparations>

Recipe nutrition request

The following shows the response to a recipe nutrient request. Please note that this example does not necessarily show all nutrients that may be returned.

[
    {
        "RecipeGuid": "a672fd1e-85b5-476c-9337-833d4c76a270",
        "PLU": "0000495",
        "Name": "Caesar Salad",
        "CalculationMethod": "Auto-calculate",
        "SelectedStandard": "Reference Intake (RI) of an average adult, Adults, Adults (general)",
        "Nutrients": [
            {
                "NutrientName": "Energy_kCal",
                "NutrientDescription": "Energy (kcal)",
                "PerServingGram": "338.592",
                "Per100g": "218.446",
                "PercentageOfGDA": "16.93",
                "NutrientGuid": "99260bc8-c623-4c07-8fc2-674e1cb588b3"
            },
            {
                "NutrientName": "Energy_KJ",
                "NutrientDescription": "Energy (kJ)",
                "PerServingGram": "1411.377",
                "Per100g": "910.566",
                "PercentageOfGDA": "16.802",
                "NutrientGuid": "642cc016-c0b7-4e7f-ae4e-0aab7df6d613"
            },
            {
                "NutrientName": "Fat",
                "NutrientDescription": "Total Fat (g)",
                "PerServingGram": "25.625",
                "Per100g": "16.532",
                "PercentageOfGDA": "36.607",
                "NutrientGuid": "5e1dd7f0-3b6a-4a9e-a144-3b7333bec7d5"
            },
            {
                "NutrientName": "Fat_Sat",
                "NutrientDescription": "saturates (SFA)",
                "PerServingGram": "9.094",
                "Per100g": "5.867",
                "PercentageOfGDA": "45.472",
                "NutrientGuid": "7d566f1c-643a-49ff-a256-703176288d5e"
            },
            {
                "NutrientName": "Fat_Mono",
                "NutrientDescription": "mono-unsaturates (MUFA)",
                "PerServingGram": "7.365",
                "Per100g": "4.752",
                "PercentageOfGDA": "",
                "NutrientGuid": "ce8f91b0-6c89-409f-af95-da93e9b1dd3c"
            },
            {
                "NutrientName": "Fat_Poly",
                "NutrientDescription": "poly-unsaturates (PUFA)",
                "PerServingGram": "7.324",
                "Per100g": "4.725",
                "PercentageOfGDA": "",
                "NutrientGuid": "e4c96cfa-1e75-49d8-a1e4-4b800e44d09e"
            },
            {
                "NutrientName": "Carb",
                "NutrientDescription": "Carbohydrate (g)",
                "PerServingGram": "14.349",
                "Per100g": "9.257",
                "PercentageOfGDA": "5.519",
                "NutrientGuid": "16bbb275-cee4-48b1-875d-8f9b861880dd"
            },
            {
                "NutrientName": "Carb_Starch",
                "NutrientDescription": "starch",
                "PerServingGram": "",
                "Per100g": "",
                "PercentageOfGDA": "",
                "NutrientGuid": "648294d9-4e3e-4543-a66a-35e75baa2a44"
            },
            {
                "NutrientName": "Carb_Sugars",
                "NutrientDescription": "total sugars",
                "PerServingGram": "1.626",
                "Per100g": "1.049",
                "PercentageOfGDA": "1.807",
                "NutrientGuid": "72b18874-630f-4c92-801a-b12180920606"
            },
            {
                "NutrientName": "Protein",
                "NutrientDescription": "Protein (g)",
                "PerServingGram": "13.677",
                "Per100g": "8.824",
                "PercentageOfGDA": "27.353",
                "NutrientGuid": "9d57b6b6-dda7-4bc3-b8e0-d36358406fb7"
            },
            {
                "NutrientName": "Fibre_NSP",
                "NutrientDescription": "Fibre",
                "PerServingGram": "",
                "Per100g": "",
                "PercentageOfGDA": "",
                "NutrientGuid": "2c706cc1-35e3-4689-b151-0d083edf8664"
            },
            {
                "NutrientName": "Sodium",
                "NutrientDescription": "Sodium (g)",
                "PerServingGram": "0.549",
                "Per100g": "0.354",
                "PercentageOfGDA": "22.879",
                "NutrientGuid": "887d699b-4c2e-4f2d-90df-6afdf801e5bc"
            },
            {
                "NutrientName": "Salt(g)",
                "NutrientDescription": "Salt(g)",
                "PerServingGram": "1.373",
                "Per100g": "0.886",
                "PercentageOfGDA": "22.879",
                "NutrientGuid": "887d699b-4c2e-4f2d-90df-6afdf801e5bc"
            }
        ]
    }
]

Troubleshooting

I've made a request to the /Ingredients/{guid}/supplierspec endpoint but the response had blank / empty values. Why am I not receiving any data in the response when the request is fine?

Most likely this is because the API User Group does not have permission to view supplier information. Please ask your customer to give the API User Group permission to ‘view’ the Supplier Spec tab.

If this doesn't work, get your customer to contact Fourth to resolve the issue.