Recipe & Menu Engineering Import API Guide
Introduction
The Recipe & Menu Engineering (RME) Import API lets you create or update a wide range of ingredient and supplier details in Fourth.
Quick Facts
Integration type | HTTP REST with JSON and XML |
Authentication | Basic authentication |
Availability | All customers using our Fourth Inventory for Restaurants solution |
Testing | Test environment available |
More information | See the Import API Reference. For help deciding which RME API to use, see Choosing between the RME Import and Export APIs. |
Get access
To get started with this API, you will need:
- A Recipe & Menu Engineering Import API account to access this API
- The root URL for requests to the 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.
Note: Access to each POST and DELETE operation is provided only on request. If you wish to use an additional POST or DELETE operations in the future, please ask your customer to request this on your behalf. Existing and new GET operations are available without restriction to integrated partners.
Updates
You can find any updates on the Release Notes page for this API.
Understanding parent and alternate 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.
Parent and alternate ingredients have a rank order, that determines which is the preferred supplier. The rank is not editable via this API. By default:
- When creating a parent ingredient, the rank order is set to 1.
- When creating an alternate ingredient, the rank order is given the next available rank; for example, if there are 4 alternate ingredients already, the new one will have the rank 5.
For additional information about alternate ingredients, please also see Understanding alternate and parent ingredients in the Export API Guide.
Uniquely identifying each ingredient
Inside Fourth, ingredients are linked with suppliers. When an ingredient is initially entered into Fourth via a POST /ingredients request, the ingredient must include these details:
- SupplierName — Name of the supplier
- SupplierCode — A unique identifier for the ingredient, as provided by the supplier
Fourth assigns each new ingredient with a StarChefKey. This is a unique identifier that should be used when updating ingredient details using the other endpoints. Along with the SupplierName and SupplierCode, this identifier is returned in relevant ingredient-related GET requests.
Logic when updating a parent ingredient
When creating or updating ingredient records, these rules apply:
- If the request includes a StarChefKey, then we use this to identify the ingredient. If the ingredient isn’t found, then we generate an error.
The values for SupplierName and SupplierCode are not used for matching the ingredient. Instead:- If these have values, we update the record with the new values.
- If the values are null, then we keep the existing values, as these fields must always have a value.
- If the request does not include a StarChefKey, then we use the SupplierName and SupplierCode to check whether there is a matching ingredient record. If no record is found, we create a new record.
Logic when adding an alternate ingredient
You can create an alternate ingredient using the POST /ingredientsalternates method.
To add a new alternate ingredient to a parent ingredient, you must include either ParentStarChefKey OR ParentSupplierName and ParentSupplierCode:
- If the request includes a ParentStarChefKey, then we use this to identify the parent ingredient. If the ingredient isn’t found, then we generate an error. The values for ParentSupplierName and ParentSupplierCode are completely ignored.
- If the request does not include a ParentStarChefKey, then we use the ParentSupplierName and ParentSupplierCode to check whether there is a matching ingredient record. If the ingredient isn't found, then we generate an error.
- The request for the new alternate ingredient must include a SupplierName and SupplierCode for the ingredient. If the combination of these match an existing alternate ingredient, then we generate an error.
Logic when updating an alternate ingredient
You can update an alternate ingredient using the POST /ingredientsalternates method.
To update an existing alternate ingredient, do not include ParentStarChefKey OR ParentSupplierName and ParentSupplierCode.
- If the request includes a StarChefKey, then we use this to identify the alternate ingredient. If the ingredient isn’t found, then we generate an error. The values for SupplierName and SupplierCode are not used for matching the ingredient. Instead:
- If these have values, we update the record with the new values.
- If the values are null, then we keep the existing values, as these fields must always have a value.
- If the request does not include a StarChefKey, then we use the SupplierName and SupplierCode to check whether there is a matching ingredient record. If the ingredient isn't found, then we generate an error.
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:
- Category Type
- Main Category
- SubCategory
- SubCategory
- SubCategory
Category types can be either “smart” or “system”. Smart categories align with categories in Fourth Inventory. Items can have multiple system categories, but typically have only one smart category.
Sets
A Set is a container for ingredient, recipe, and menu records. Sets are used to determine whether an individual record can be used by a restaurant. There's two ways this works:
- Each Set can be put into one or more groups, with the groups limiting access to specific brands or restaurants.
- A Set may have a live, trial or archive status.
Individual ingredient, recipe or menu records can be in multiple sets; however, they cannot be in a mix of sets with different status (live, trial or archive). In the API, we return the name of the sets, for example: "All brands", "Cafe Metros", "Menu Development".
Sets can be in many groups, and groups can have many sets.
Ingredient Price Bands
Recipe & Menu Engineering supports price bands for ingredients. This enables our customers to have product-by-product or across-the-board price uplifts as necessary to support their different regions and restaurants.
In the API, we provide these endpoints for price bands:
- GET ingredientspricebands
This enables you to get the full list of price bands for all ingredients. - POST ingredientpriceband
This enables you to update the price band for one or more ingredients.
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 ingredient and recipe in Fourth has fields to hold full sub-ingredient data. This data can come from two sources: manually keyed in by our customers, or via our APIs from a partner or supplier.
As well, you can specify consumer-friendly names for each ingredient and recipe. See Adding consumer-friendly naming below for more information.
Note: our RME Export API also has endpoints related to Natasha’s Law, which are used for auditing purposes.
Managing the ingredient list for an ingredient
The ingredient list field in Fourth is designed to hold the sub-ingredients and allergens for an ingredient.
Ingredient lists are specifically designed to provide the text required for labels and displays. They do not replace any requirements you have to supply nutrient and intolerance data for an ingredient via the POST ingredientnutrient and POST ingredientintolerance endpoints.
For example, the ingredient pasta sauce would have an ingredient list of: Tomatoes, basil, butter (Cow’s MILK, salt), onion, salt, pepper. Unless otherwise advised by your customer, send the allergens in uppercase, as the label design in Fourth specifies: "For allergens, see ingredients in UPPERCASE".
Ingredient lists are owned by parent ingredients, as the ingredients and allergens should be identical between parent and alternate ingredients. The lists also include a Ready for use field. This enables both partners (via the API) and customers to confirm that an ingredient list is accurate and ready for use on automatically-generated recipe labels.
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.
The Recipe & Menu Engineering Import API provides these endpoints for managing ingredient lists for ingredients:
- POST /ingredientlist — This enables partners to add and update the full ingredient list (sub-ingredients and allergens) for an ingredient. This request replaces all values currently in the ingredient list. Therefore, you must include ALL sub-ingredients and allergens in the ingredient in any request.
- GET /ingredientlist — this retrieves the text in the ingredient list field.
Note that these endpoints are useable only when the customer has the full ingredient list functionality enabled.
Example POST request
See the API Reference for full details about this endpoint.
[ { "SupplierName": "Grocer", "SupplierCode": "1357", "StarchefKey": "0014674", "FullIngredientList": " Water, MUSTARD Flour, Spirit Vinegar, Sea Salt, MUSTARD Husk, Pimento, Turmeric", "LabelDescription": "Dijon Mustard", "ReadyForUse": "YES" } ]
Example GET request
This example shows a parent ingredient, Bulgarian Beef Sausages with two alternate ingredients. Note that the value of ParentGuid and AlternateGuid is the same for the parent ingredient.
See the API Reference for full details about this endpoint.
[ { "IngredientName": "Bulgarian Beef Sausages", "StarchefKey": "14889", "ParentGuid": "ad0e454a-cbf5-420e-9c36-8dd7e1fbc0cc", "AlternateGuid": "ad0e454a-cbf5-420e-9c36-8dd7e1fbc0cc", "FullIngredientList": "Beef, Oats (GLUTEN), Salt, Pepper, Nitrates E420", "LabelDescription": "Rich Beef Sausages", "ReadyForUse": "YES" }, { "IngredientName": "Flashy Sausages Dog", "StarchefKey": "14891", "ParentGuid": "ad0e454a-cbf5-420e-9c36-8dd7e1fbc0cc", "AlternateGuid": "35a6d7a6-3e78-4d63-9b93-9073be0e0847", "FullIngredientList": "Beef, Oats (GLUTEN), Salt, Pepper, Nitrates E420", "LabelDescription": "Rich Beef Sausages", "ReadyForUse": "YES" }, { "IngredientName": "Posh Sausages", "StarchefKey": "15861", "ParentGuid": "ad0e454a-cbf5-420e-9c36-8dd7e1fbc0cc", "AlternateGuid": "981f85d4-93e2-43ed-9b83-34f638d2f1ec", "FullIngredientList": "Beef, Oats (GLUTEN), Salt, Pepper, Nitrates E420", "LabelDescription": "Rich Beef Sausages", "ReadyForUse": "YES" } ]
Getting the ingredient lists for recipes
The GET /recipeingredientlist endpoint enables you to retrieve the full ingredient list for a recipe. However, with recipes, there are two variations of ingredient list. For each recipe, the customer can select which list is preferred for creating labels and reports.
The variations are:
- 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.
Automatically generated lists require all the ingredients in them to have ingredient lists that are "Ready for use". If an ingredient's ingredient list is not set as ready for use, then an error message is shown in the recipe's ingredient list.
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.
You can retrieve these lists using the GET /recipeingredientlist endpoint. The request body includes a PreferredFieldInTheReport value to ensure that you use the preferred list. During development, you should discuss with your customer what your system should do if the preferred field is empty.
Note that this endpoint returns data only when the customer has the full ingredient list functionality enabled.
Example GET request
See the API Reference for full details about this endpoint.
[ { "RecipeName": "Avocado and Crayfish Salad", "StarchefKey": "14675", "RecipeGuid": "986601f8-1add-410f-aa80-b6e9e910a2f4", "ManualFullIngredientList": "Crayfish Tails (CRUSTACEAN), Avocado, Curly Endive, Little Gem Lettuce, Radicchio, Balsamic Vinegar and Mustard Dressing (Olive Oil, Balsamic Vinegar, Dijon Mustard (Water, MUSTARD Flour, Spirit Vinegar, Sea Salt, MUSTARD Husk, Pimento, Turmeric))", "ManualLastModifiedDate": "Feb 1 2021 2:23PM", "AutoFullIngredientList": "Crayfish Tails (CRUSTACEAN), Avocado, Lettuce Curly Endive, Lettuce, Little Gem, Lettuce Radicchio - Per Kg, Balsamic Vinegar and Mustard Dressing (Olive Oil, Balsamic Vinegar, Dijon Mustard (Water, MUSTARD Flour, Spirit Vinegar, Sea Salt, MUSTARD Husk, Pimento, Turmeric))", "AutoLastModifiedDate": "Feb 1 2021 2:14PM", "PreferredFieldInTheReport": "Auto" } ]
Adding consumer-friendly naming for ingredients and recipes
To further support creating labels suitable for consumers, each ingredient and recipe has an optional consumer-friendly name that you can supply.
For individual ingredients, specify this name in the LabelDescription field of POST ingredientList request.
Example POST ingredientList request body
[ { "SupplierName": "Grocer", "SupplierCode": "1357", "StarchefKey": "0014674", "FullIngredientList": " Water, MUSTARD Flour, Spirit Vinegar, Sea Salt, MUSTARD Husk, Pimento, Turmeric", "LabelDescription": "Dijon Mustard" } ]
See the API Reference for full details about this endpoint.
If provided, the label description is used instead of the ingredient name in recipe ingredient lists (when auto-calculated). For example, the following image shows an ingredient with the ingredient name Flour White Soft. It has a label description of Flour. When a label is printed for a relevant recipe, the ingredient is described as Flour (WHEATflour). This is the combination of the label description with the ingredient list for the ingredient.
If there is no label description for an ingredient, then the ingredient name is used. You can retrieve the LabelDescription values for ingredients via the GET ingredientList endpoint.
For recipes, you can supply a consumer-friendly name via the POST recipenames endpoint. This endpoint allows you to update the naming for a recipe. The RecipeMenuDescription field is used on labels by default. If this does not exist, then the RecipeName is used.
Example POST recipenames request body
See the API Reference for full details about this endpoint.
[ { "RecipeStarChefKey": "0030702", "RecipeName": "Brown Cake", "RecipeShortName": "Cake", "RecipeMenuDescription": "Brownie", "RecipeDescription": "Cake with cocoa and milk", "RecipeInternalCode": "1123", "RecipeExternalCode": "2345" } ]
As with all POST endpoints for this API, your request should include the full payload; any fields left blank are set to null.
Alternatively, if you need to retrieve recipe names, use the GET recipenames endpoint.
Example GET recipenames response body
See the API Reference for full details about this endpoint.
[ { "RecipeGuid": "6BD28622-E5FE-452B-A627-E2C65584DAC2", "RecipeStarChefKey": "0030702", "RecipeName": "Brown Cake", "RecipeShortName": "Cake", "RecipeMenuDescription": "Brownie", "RecipeDescription": "Cake with cocoa and milk", "RecipeInternalCode": "1123", "RecipeExternalCode": "2345" } ]
Where to find more information about Natasha's Law
For more information about Natasha's Law:
- Visit help.fourth.com and search for "Natasha's Law" for articles published by us.
- View the Food Standards Agency's technical guidance on their website.
- View the Legislation online.
Support for carbon footprint (CO2) management
Hospitality businesses need a way to measure, manage, and ultimately reduce the CO2 footprint of their operations and offerings. To assist with this, Fourth's Recipe & Menu Engineering (RME) can:
- Hold carbon footprint data for both ingredients and recipes
- For each recipe, provide automatic CO2 impact calculations using the ingredients' footprint
- Enable Life Cycle Assessment (LCA) partners to view and update this data through our APIs
For full information on how we support this, please see our page on CO2 footprint measurement & management.
Custom Fields
The custom field endpoints enable you to manage custom fields for ingredients.
Custom fields provide customers with a wider range of options when classifying ingredients that’s specific to their needs. For example, customers could use these fields to classify whether their ingredients are organic or not.
Custom fields are created via the user interface (UI). Users must set two names:
- An API name (the Name field in the UI). In POST requests this is the CustomFieldName. Special characters or spaces are not allowed for this value.
- A UI name (the Display Name in the UI).
Example Custom Field settings in the Fourth user interface
Customers can set the value to be either one of two types:
- Free text values
- A list of preset values
For list values, users must configure a name in the Option Value field for use by the API. After an option is created, the Option Value is the value shown in parenthesis:
The next screenshot shows three custom fields in use in the UI, where:
- Acidification Potential is a free-text field.
- Water Usage and Faming Method are lists with preset options; and the options shown for Farming Method are: Organic, Intensive, and Mixed Organic and Non-Organic.
If you are making POST /ingredientcustomfields requests, then you will need to know beforehand the:
- Name of the custom field
- If it is part of a list, the accepted values for the field (Option Value)
Example POST /ingredientcustomfields request body
[ { "StarChefKey": "0030702", "SupplierName": "Dairy", "SupplierCode": "B365", "CustomFieldName": "Farming_Method", "CustomFieldValue": "Mixed_Organic_and_Non-Organic" } ]
You can find out more about custom fields in the RME Release Note for September 21st, 2022.
Unit of measure (UoM) values and codes
There a several requests where you will need to set values for a UoM or unit code. The following require a long name as their value:
- SupplyQuantityUnit
- UnitSizeUom
- AlternativeUnit1Uom
- AlternativeUnit2Uom
The UnitCode parameter must use the abbreviated name.
Lastly, there are two optional parameters SupplierOrderUom or InvoiceUom that take only these values:
- EA — each
- CS — case
- KGM — kilogram
The next table has the possible long name and abbreviated name values.
Long name | Abbreviated name (UnitCode only) | Type | Equates to |
---|---|---|---|
bakers dozen | bdz | ||
BARREL | BRL | Volume | 5376 Fl oz (US) |
bottle | btl | ||
bunch | bnch | ||
Bushel | BU | Volume | 1191.57 Fl oz (US) |
centilitre | cl | ||
clove | clv | ||
cup (UK) | cup (UK) | ||
cup (US) | cup (US) | ||
dozen | dz | ||
each | ea | ||
floz (UK) | floz (UK) | ||
floz (US) | floz (US) | ||
gallon (UK) | gal (UK) | ||
gallon (US) | gal (US) | ||
gill (UK) | gill (UK) | ||
gill (US) | gill (US) | ||
gram | g | ||
KEG (D) 1/2 | KEG (D) 1/2 | Volume | 1984 Floz (US) |
KEG (D) 1/4 | KEG (D) 1/4 | Volume | 992 Floz (US) |
KEG (D) 1/6 | KEG (D) 1/6 | Volume | 661 Floz (US) |
KEG (I) 1/2 | KEG (I) 1/2 | Volume | 1690.70 Fl oz (US) |
KEG (I) 1/3 | KEG (I) 1/3 | Volume | 1014.42 Fl oz (US) |
KEG (I) 1/4 | KEG (I) 1/4 | Volume | 845.35 Fl oz (US) |
kilogram | kg | ||
litre | l | ||
loaf | loaf | ||
milligram | mg | ||
millilitre | ml | ||
ounce | oz | ||
PACK | PK | Each | 1 Each |
Pan 1/3 4" Deep | Pan 1/3 x 4" | Volume | 4.5 Quarts (US) |
PAN 1/6 6" Deep | Pan 1/6 x 6" | Volume | 2.5 Quarts (US) |
piece | piece | ||
pint (UK) | pt (UK) | ||
pint (US) | pt (US) | ||
pound | lb | ||
quart (UK) | qt (UK) | ||
quart (US) | qt (US) | ||
Quart, Dry (US) | QT, Dry (US) | Volume | 37.2364 Fl oz (US) |
serving(s) | serving | ||
SHEET | SHT | Each | 1 Each |
single | single | ||
slice | slice | ||
stone | stone | ||
tbsp (UK) | tbsp (UK) | ||
tbsp (US) | tbsp (US) | ||
tin | tin | ||
TRAY | TRAY | Each | 1 Each |
tsp (UK) | tsp (UK) | ||
tsp (US) | tsp (US) |
Descriptor values
These descriptors use the same set of values:
- SupplyQuantityDescriptor
- UnitSizeUomDescriptor
- AlternativeUnit1Descriptor
- AlternativeUnit2Descriptor
The possible values are:
Bag Bottle Box Bucket Bunch Carton Case | Can Container Each Jar Keg Pack Portion | Punnet Roll Sheet Sleeve Tin Tub |
Resources
For the list of endpoints and methods, see the Import API Reference. Fourth will provide you with the base path for requests.
Request header
For all requests, you must provide your authentication details using Basic authentication in the header.
POST /ingredients HTTP/1.1 Host: instance.example.com Accept: text/json Authorization: Basic VXNlcm5hbWU6cGFzc3dvcmQ=
Field | Description |
---|---|
Authorization | Your Recipe & Menu Engineering Imports ID and password, separated by a colon, and then base64 encoded. Your ID and password are case-sensitive. |
Accept | The data format you are using for the request. Options are: application/json, text/json, application/xml, text/xml. |
Request body
For full details about what is required in the request body, see the reference and the examples below.
Response to requests
Successful requests
Successful POST requests receive an HTTP 202 Accepted response with an empty response body.
Unsuccessful requests
Unsuccessful requests receive an HTTP 400-599 response, with an error message in the response body. See the error messages for each of these requests:
Checking whether a request was processed
For successfully submitted POST requests, Fourth returns a status in the synchronous response body. For example:
{
"Status": "Processed;Aug 10 2020 8:32AM",
"BatchId": "2345"
}
The two possible states are Processed (with a timestamp) and Not processed.
It's not possible for every request to be processed before the synchronous response. Not processed means that the request was successfully received, but is still queued for processing. To check the processing status later, you can use the /batches endpoint:
[ROOT]/api/ingredientandaccessimport/batches
By default, the 10 most recently received requests are reported on, however you can filter the response using query parameters.
Example response:
[ { "Status": "Not processed", "BatchId": "1243" }, { "Status": "Processed;Aug 08 2020 3:45PM", "BatchId": "1255" }, { "Status": "Processed;Aug 08 2020 10:05PM", "BatchId": "1289" }, { "Status": "Not processed", "BatchId": "2108" }, { "Status": "Processed;Aug 09 2020 10:12AM", "BatchId": "2111" } ]
If a request has not been processed after an hour, please raise a case with Fourth support via your mutual customer.
Making suppliers requests
Before you can start adding ingredients, you need to make sure the ingredient supplier exists in Fourth. You can do this using the suppliers resource.
This example request adds a new supplier-distributor. The accountNumber is your unique reference for the supplier. The SupplierCurrencyCode is in standard ISO 4217 codes.
POST /suppliers HTTP/1.1 Host: instance.example.com Content-Type: application/json Authorization: Basic VXNlcm5hbWU6cGFzc3dvcmQ= [ { "SupplierId": "", "AccountNumber": "ACME12346", "SupplierName": "Chris's produce", "AlternateSupplierName": "CHRISPRO", "CountryGuid": "example", "SupplierCurrencyCode": "GBP",
"SupplierType": "Supplier and distributor" } ]
Note that CountryGuid is optional as it is not required for most use cases. The value is a Fourth ID for the country.
Making ingredient requests
Use the ingredient resource to add or update an ingredient. You need to include the ingredient sets to which the ingredient belongs, and the ingredient's supplier (and both the sets and suppliers must already exist in Fourth).
Customers can choose to review and accept or reject ingredient changes submitted by via this endpoint. Please confirm with your customer whether they plan to do this, and the workflow to follow between you.
Simple example
POST /ingredient HTTP/1.1 Host: instance.example.com Content-Type: application/xml Authorization: Basic VXNlcm5hbWU6cGFzc3dvcmQ= <ArrayOfIngredient> <Ingredient> <IngredientName>Ribs</IngredientName> <ParentIngredientProductName>Goat Ribs</ParentIngredientProductName> <SupplierName>Butcher</SupplierName> <SupplierCode>SupplierCode1</SupplierCode> <SupplyQuantity>6.0000</SupplyQuantity> <SupplyQuantityNumber>2.0000</SupplyQuantityNumber> <SupplyQuantityUnit>kilogram</SupplyQuantityUnit> <IngredientType>Food</IngredientType> <CostPrice>20.0000</CostPrice> <InternalCode>2008</InternalCode> <IngredientSets> <Set>Master Ingredients</Set> </IngredientSets> </Ingredient> </ArrayOfIngredient>
Sending supply and unit sizes
The Supply quantity fields in the request provide the pack and quantity details of the supplied product. This example shows a carton of 12 tonic waters that comes in 150 ml cans. Note that SupplyQuantity and SupplyQuantityNumber are interchangeable from Fourth's perspective; however, your customer will likely have a pattern that they always use (e.g. SupplyQuantity for the number of items).
... "IngredientName": "SugarBush Tonic", "SupplyQuantity": "12", "SupplyQuantityNumber": "150", "SupplyQuantityUnit": "millilitre", "SupplyQuantityDescriptor": "Carton", ...
The Unit fields are the details used in Fourth Inventory for stocktake purposes. For example, the same product might have the following unit fields:
... "UnitSizeNumber": "15", "UnitSizeUom": "centilitre", "UnitSizeUomDescriptor": "Can", ...
The Supply and Unit fields MUST must logically match. This means that if an ingredient's UnitSizeUom is:
- A weight, the SupplyQuantityUnit must also be a weight.
- A volume, the SupplyQuantityUnit must also be a volume.
- Other, the SupplyQuantityUnit must be the same value; e.g. each, slice or bottle.
If they do not match, you will not be able to update the ingredient.
Catch weight ingredients
Catch weight ingredients are those that have varying weight and invoice cost each time; for example, freshly caught fish.
For catch weight ingredients, the UoMs of the Invoice and Unit must match. For example:
... "UnitSizeUom": "KG", "InvoiceUom": "KGM", ...
If they do not match, you will not be able to update the ingredient.
Note that the only valid UoMs for catch weight products are KG (KGM) or LB.
Settings that restrict access to updating UoMs
There are two global settings in Fourth that can stop you from updating UoM values via the API. These are:
- Supply Quantity read-only for Live Ingredients — when enabled, you cannot update these supply fields for an ingredient: SupplyQuantityNumber, SupplyQuantity, and SupplyQuantityUnit.
- Unit Size read-only for Live Ingredients — when enabled, you cannot update the values for these fields: UnitSizeNumber, and UnitSizeUom.
To enable or disable this functionality, customers must contact the Fourth team.
Alternate ingredients
You can use the POST /ingredientsalternates resource to add alternate ingredients. Alternate ingredients are always linked to a parent ingredient, so in the request you will need to specify the parent ingredient.
Alternate ingredients can come from the same or different suppliers from the parent ingredient. When an alternate ingredient is created, its pack size (supply quantity) can be defined using the parent ingredient base Unit of Measure (UoM) or any of the parent ingredient conversion UoMs.
For more information, see Understanding alternate and parent ingredients in the Export API Guide.
Example with alternate ingredients data
</ArrayOfIngredient> <Ingredient> <IngredientName>Skim Milk</IngredientName> <SupplierName>Dairy</SupplierName> <SupplierCode>B391</SupplierCode> <SupplyQuantity>12.0000</SupplyQuantity> <SupplyQuantityUnit>gram</SupplyQuantityUnit> <CostPrice>12.5000</CostPrice> <IngredientType>Food</IngredientType> <InternalCode>1007</InternalCode> <IngredientSets> <Set>Test 1</Set> <Set>Test 2</Set> <Set>Test 3</Set> </IngredientSets> <SupplyQuantityNumber>1.0000</SupplyQuantityNumber> <ParentSupplierName>Dairy</ParentSupplierName> <ParentSupplierCode>B600</ParentSupplierCode> <ParentStarChefKey>0036858</ParentStarChefKey> </Ingredient> </ArrayOfIngredient>
AlternativeUnit values
These elements are used with Fourth Inventory:
- AlternativeUnit1Quantity, AlternativeUnit1Uom, AlternativeUnit1Descriptor
- AlternativeUnit2Quantity, AlternativeUnit2Uom, AlternativeUnit2Descriptor
They create an alternative stock count unit in the Inventory system for the ingredient. If you need to use these values please contact your Fourth Implementation Consultant.
Example with all stock compatibility values
<ArrayOfIngredient> <Ingredient> <IngredientName>Ribs</IngredientName> <SupplierName>Butcher</SupplierName> <SupplierCode>SupplierCode1</SupplierCode> <SupplyQuantity>6.0000</SupplyQuantity> <SupplyQuantityUnit>kilogram</SupplyQuantityUnit> <IngredientType>Food</IngredientType> <CostPrice>20.0000</CostPrice> <InternalCode>2008</InternalCode> <IngredientSets> <Set>Test 1</Set> <Set>Test 2</Set> <Set></Set> </IngredientSets> <SupplyQuantityNumber>2.0000</SupplyQuantityNumber> <DistributorName>Dairy</DistributorName> <DistributorCode>Dairy001</DistributorCode> <ExternalCode>EXTCODE01</ExternalCode> <SupplyQuantityDescriptor>case</SupplyQuantityDescriptor> <UnitSizeNumber>10</UnitSizeNumber> <UnitSizeUom>ounce</UnitSizeUom> <UnitSizeUomDescriptor>Case</UnitSizeUomDescriptor> <CostModel>Highest</CostModel> <IsAdjustmentItem>True</IsAdjustmentItem> <PreventUsageInRecipes>False</PreventUsageInRecipes> <TransferRequisitionStatus>False</TransferRequisitionStatus> <ExcludeFromGP>False</ExcludeFromGP> <ZeroStockCount>True</ZeroStockCount> <ItemVatable>Yes</ItemVatable> <FirstDelivery>2017-06-28</FirstDelivery> <BinNumber>12134</BinNumber> <MaxOrderQuantity>50</MaxOrderQuantity> <MinOrderQuantity>5</MinOrderQuantity> <AlternativeUnit1Quantity>5</AlternativeUnit1Quantity> <AlternativeUnit1Uom>centilitre</AlternativeUnit1Uom> <AlternativeUnit1Descriptor>Bottle</AlternativeUnit1Descriptor> <AlternativeUnit2Quantity>1000</AlternativeUnit2Quantity> <AlternativeUnit2Uom>milligram</AlternativeUnit2Uom> <AlternativeUnit2Descriptor>Box</AlternativeUnit2Descriptor> <SupplierOrderUom>CS</SupplierOrderUom> <InvoiceUom>CS</InvoiceUom> <InvoicePrice>7.55</InvoicePrice> </Ingredient> </ArrayOfIngredient>
Error messages for ingredients
Error Message | Description |
---|---|
Ingredient Name is mandatory and must be less than 150 characters. | Ingredient name missing or too long. |
Supplier Name does not exist in StarChef or Value is missing. | Supplier Name value not provided or does not exist in StarChef. |
Supplier Code is mandatory and must be less than 50 characters. | Supplier Code value missing or too long. |
Supply Quantity Number is mandatory and must be valid decimal value. | Supply Quantity Number value missing or incorrect format. |
Supply Quantity Quantity is mandatory and must be valid decimal value. | Supply Quantity Quantity value missing or incorrect format. |
Cost Price is mandatory and must be valid decimal value. | Cost Price value missing or invalid format. |
Ingredient Set(s) does not exist in StarChef or Value is missing. | Ingredient set value not provided or does not exist in StarChef. |
Multiple Records exist with same Supplier Name and Supplier Code combination. | Trying to import the same ingredient (defined by the combination of Supplier Name and Supplier Code) more than once or ingredient already exists in StarChef. |
Multiple Records exist with same Distributor Name and Distributor code combination. | Trying to import the same ingredient (defined by the combination of Distributor Name and Distributor Code) more than once or ingredient already exists in StarChef. |
Ingredient Type could be only food or non-food. | Trying to import an ingredient with type different than food or non-food. |
External Code must be less than 50 characters. | External code contains more than 50 characters. |
Supply Quantity descriptor does not exist in StarChef or Value is missing. | Supplier Quantity Descriptor value doesn't exists in StarChef. |
Unit Size number must be valid decimal value. | Unit Size number value is not a decimal value. |
Unit Size UoM does not exist in StarChef or Value is missing | Unit Size UoM value doesn't exist in the StarChef UoM table. See the Unit of measure (UoM) values and codes table for valid values. |
Unit Size UoM descriptor does not exist in StarChef or Value is missing. | Unit Size UoM Descriptor value doesn't exists in StarChef. See the Descriptor values table for valid values. |
Cost model does not exist in StarChef or Value is missing. | Cost Model value doesn't exist in StarChef. |
Flag Adjustment Item value is not Boolean. | Is Adjustment Item value is not entered as True or False. |
Flag Prevent Usage in Recipes value is not Boolean. | Prevent Usage in Recipes value is not entered as True or False. |
Transfer Requisition Status value is not Boolean. | Transfer Requisition Status value is not entered as True or False. |
Exclude from GP value is not Boolean. | Exclude From GP value is not entered as True or False. |
Zero Stock Count value is not Boolean. | Zero Stock Count value is not entered as True or False. |
Item Vatable does not exist in StarChef or Value is missing. | Item Vatable value is not entered as Yes, No or - . |
First delivery must be valid date value. | Date into Warehouse value is not entered in the correct format yyyy-mm-dd. |
Max order quantity must be valid decimal value. | Maximum Order Quantity value is not entered as a decimal value. |
Min order quantity must be valid decimal value. | Minimum Order Quantity value is not entered as a decimal value. |
Alternative Unit1 quantity must be valid decimal value. | Alternative Unit1 quantity value is not entered as a decimal value. |
Alternative Unit1 UoM does not exist in StarChef or Value is missing. | Alternative Unit1 UoM value doesn't exist in the StarChef UoM table. |
Alternative Unit1 descriptor does not exist in StarChef or Value is missing. | Alternative Unit1 descriptor value doesn't exist in StarChef. |
Alternative Unit2 quantity must be valid decimal value. | Alternative Unit2 quantity value is not entered as a decimal value. |
Alternative Unit2 UoM does not exist in StarChef or Value is missing. | Alternative Unit2 UoM value doesn't exist in the StarChef UoM table. |
Alternative Unit2 descriptor does not exist in StarChef or Value is missing. | Alternative Unit2 descriptor value doesn't exist in the StarChef descriptor table. |
Supplier Order UoM does not exist in StarChef or Value is missing. | Supplier Order UoM value is not one of the valid values: CS, EA, KGM. |
Invoice UoM does not exist in StarChef or Value is missing. | Invoice UoM value is not one of the valid values: CS, EA, KGM. |
Invoice Price must be valid decimal value | Invoice Price value is not entered as a decimal value. |
Parent Supplier Name does not exist in StarChef or Value is missing. | Parent Supplier Name value is not provided or does not exist in StarChef. |
Parent Supplier Name and Parent Supplier Code combination is not full | Either Parent Supplier Name value is not provided or does not exist in StarChef or the Supplier Code value is not provided. |
Parent Supplier StarChef Key does not exist or Value is missing. | StarChef Key value is not provided or is not valid. |
Parent Supplier Name must be less than 150 characters. | Parent Supplier Name value should not exceed 150 characters. |
Parent Supplier Code must be less than 50 characters. | Parent Supplier Code value should not exceed 50 characters. |
Rank Order is not valid number. | Rank Order should be a valid number. |
Multiple Records exist with the same rank order. | Two or more alternate ingredients that are associated with the same parent ingredient cannot be imported with the same rank order. |
Supplied Unit name is not part of the family. | Unit of measure of the alternate ingredient must correspond to the parent unit of measure. |
Making ingredientnutrient requests
Use ingredientnutrient to add nutrition details for an ingredient.
If you need to remove a nutrient from an ingredient's information, send in the nutrient with no value (or null) for NutrientValue.
In this example, the request adds two nutrients (Energy_KJ and Cal_Carb_Pct), and removes one (Caffeine) from the ingredient CHRI332.
POST /ingredientnutrient HTTP/1.1 Host: instance.example.com Content-Type: application/xml Authorization: Basic VXNlcm5hbWU6cGFzc3dvcmQ= <ArrayOfIngredientNutrient> <IngredientNutrient> <SupplierName>Chris's produce</SupplierName> <SupplierCode>CHRI332</SupplierCode> <NutrientName>Energy_KJ</NutrientName> <NutrientValue>10.235</NutrientValue> </IngredientNutrient> <IngredientNutrient> <SupplierName>Chris's produce</SupplierName> <SupplierCode>CHRI332</SupplierCode> <NutrientName>Cal_Carb_Pct</NutrientName> <NutrientValue>6.115</NutrientValue> </IngredientNutrient> <IngredientNutrient> <SupplierName>Chris's produce</SupplierName> <SupplierCode>CHRI332</SupplierCode> <NutrientName>Caffeine</NutrientName> <NutrientValue></NutrientValue> </IngredientNutrient> </ArrayOfIngredientNutrient>
Nutrient values table
NutrientName | Display Description on Starchef Screen |
---|---|
Cal_Carb_Pct | % Calories from Carbohydrate |
Cal_Fat_Pct | % Calories from Fat |
Cal_MUFA_Pct | % Calories from Monounsaturated Fatty Acid (MUFA) |
Cal_PUFA_Pct | % Calories from Polyunsaturated Fatty Acid (PUFA) |
Cal_Prot_Pct | % Calories from Protein |
Cal_SatFat_Pct | % Calories from Saturated Fat (SFA) |
Alpha_Tocopherol | Alpha Tocopherol (mg) |
Biotin | Biotin (μg) |
Caffeine | Caffeine (mg) |
Calcium | Calcium (mg) |
Cal_Details | Calorie Breakdown |
Cal_Fat | Calories from Fat |
Cal_SatFat | Calories from Saturated Fat |
Carb | Carbohydrate |
Carotene | Carotene (μg) |
Carotene_alpha | Carotene, alpha (μg) |
Carotene_beta | Carotene, beta (μg) |
Chloride | Chloride (mg) |
Fat_Chol_mg | Cholesterol (mg) |
Choline | Choline (mg) |
Chromium | Chromium (μg) |
Copper | Copper (mg) |
Cryptoxanthins | Cryptoxanthins (μg) |
Energy_kCal | Energy (kcal) |
Energy_KJ | Energy (kJ) |
Fat_sol | Fat soluble vitamins |
Fibre_AOAC | Fibre (AOAC) |
Fibre_NSP | Fibre (NSP) |
Fluoride | Fluoride (mg) |
Folate | Folate, food (μg) |
Folic_Acid | Folic Acid (Folate) (μg) |
Fructose | Fructose |
Glucose | Glucose |
Iodine | Iodine (μg) |
Iron | Iron (mg) |
Lactose | Lactose |
Lutein_zeaxanthin | Lutein + zeaxanthin (μg) |
Lycopene | Lycopene (μg) |
Magnesium | Magnesium (mg) |
Maltose | Maltose |
Manganese | Manganese (mg) |
Mineral | Minerals |
Molybdenum | Molybdenum (μg) |
Fat_Mono | mono-unsaturates |
Niacin | Niacin (mg) |
NMES | NMES |
Pantothenic_Acid | Pantothenic acid (mg) |
Phosphorus | Phosphorus (mg) |
Fat_Poly | poly-unsaturates |
Potassium | Potassium (mg) |
Protein | Protein |
Retinol | Retinol (μg) |
Riboflavin | Riboflavin (mg) |
Fat_Sat | saturates |
Selenium | Selenium (μg) |
Sodium | Sodium (mg) |
Carb_Starch | starch |
Sucrose | Sucrose |
Thiamin | Thiamin (mg) |
Fat | Total Fat |
Carb_Sugars | total sugars |
Vitamin_A_μg | Vitamin A (μg) |
Vitamin_A | Vitamin A (IU) |
Vitamin_A_RE | Vitamin A (RE) |
Vitamin_B12 | Vitamin B12 (μg) |
Vitamin_B6 | Vitamin B6 (mg) |
Vitamin_C | Vitamin C (mg) |
Vitamin_D | Vitamin D (μg) |
Vitamin_D_IU | Vitamin D (IU) |
Vitamin_E | Vitamin E (mg) |
Vitamin_K1 | Vitamin K1 (μg) |
Water | Water |
Water_sol | Water soluble vitamins |
Zinc | Zinc (mg) |
Error messages for ingredientnutrient
Error Message | Description |
---|---|
Supplier Name does not exist in StarChef or Value is missing. | Supplier Name value is missing or does not exist in StarChef. |
Supplier Code is mandatory and must be less than 50 characters. | Supplier Code value missing or too long. |
No ingredient exists for this Supplier Name and Supplier Code combination. | Such ingredient does not exist. |
Invalid nutrient name. | Incorrect nutrient name. |
Invalid nutrient value. | Nutrient value is not in the correct format. |
Duplicate nutrient_name. | Trying to update the same nutrient value twice. |
Making ingredientintolerance requests
Use ingredientintolerance to add intolerance details for an ingredient.
If you need to remove an intolerance from an ingredient's information, send in the intolerance with IntoleranceValue set to null.
Please note that customers can choose to manually review and approve any intolerance values updated via the API. This does not have any impact on the behavior of the API itself.
In this example, the request adds two intolerances and removes one from the ingredient CHRI201.
POST /ingredientintolerance HTTP/1.1 Host: instance.example.com Content-Type: application/xml Authorization: Basic VXNlcm5hbWU6cGFzc3dvcmQ= <ArrayOfIngredientIntolerance> <IngredientIntolerance> <SupplierName>Chris's produce</SupplierName> <SupplierCode>CHRI201</SupplierCode> <IntoleranceCode>AddSalt</IntoleranceCode> <IntoleranceValue>Yes</IntoleranceValue> </IngredientIntolerance> <IngredientIntolerance> <SupplierName>Chris's produce</SupplierName> <SupplierCode>CHRI201</SupplierCode> <IntoleranceCode>Nuts</IntoleranceCode> <IntoleranceValue>May</IntoleranceValue> </IngredientIntolerance> <IngredientIntolerance> <SupplierName>Chris's produce</SupplierName> <SupplierCode>CHRI201</SupplierCode> <IntoleranceCode>AddSalt</IntoleranceCode> <IntoleranceValue>null</IntoleranceValue> </IngredientIntolerance> </ArrayOfIngredientIntolerance>
Intolerance values table
IntoleranceCode - API Import | Display Description on StarChef Screen |
---|---|
Glutamates | Contains Added Glutamates |
AddSalt | Contains Added Salt |
AddedTransFats | Contains Added Trans Fats |
OtherAdditives | Contains Additives |
Alcohol | Contains Alcohol or Alcohol Based Products |
AnimalFat | Contains Animal Fat (excluding milk fat) |
AnimalProd | Contains Animal Products (excluding rennet free milk products) |
ArtCol | Contains Artificial Colours |
ArtFlav | Contains Artificial Flavours |
Preserv | Contains Artificial Preservatives |
ArtSweet | Contains Artificial Sweeteners |
Azo | Contains Azo Dyes |
Benz | Contains Benzoates (if greater than 1mg/kg or l) |
BHA_BHT | Contains BHA/BHT (if greater than 1mg/kg or l) |
Celery | Contains Celery / Celeriac Products |
Wheat | Contains Cereals that Contain Gluten |
Coconut | Contains Coconut |
Crustaceans | Contains Crustaceans |
E110_E102_E122_E124_E104_E129 | Contains E110/E102/E122/E124/E104/E129 |
E211_Sodium_Benzoate | Contains E211 Sodium Benzoate |
Egg | Contains Eggs / Egg Derivatives |
Fish | Contains Fish or Fish Products |
FlavEnhan | Contains Flavour Enhancers |
GM | Contains G.M. Material / Ingredients |
Garlic_Onions | Contains Garlic / Onion Products |
Gluten | Contains Gluten or Gluten Products |
HydrogenatedVegOils | Contains Hydrogenated Vegetable Oils >1% |
Irradiated | Contains Irradiated Food |
Lactose | Contains Lactose |
Lupin | Contains Lupin Flour / Lupin Products |
Maize | Contains Maize or Maize Derivatives |
Milk | Contains Milk or Milk Products |
ModifiedStarch | Contains Modified Starch |
Molluscs | Contains Molluscs |
MSG | Contains MSG |
Mushrooms | Contains Mushrooms or Mushroom Products |
Mustard | Contains Mustard or Mustard Products |
NatFlav | Contains Natural Flavourings |
Nuts | Contains Nuts or Nut Trace |
NatCol | Contains Only Natural Colours |
Seeds | Contains Seeds / Seed Oil |
Sesame | Contains Sesame Seed or Sesame Seed Products |
ShellFish | Contains Shellfish |
Soya | Contains Soya |
Sulph_Diox | Contains Sulphur Dioxide/Sulphites |
Organic | Organically Produced |
Coeliacs | Suitable for Coeliacs |
Halaal | Suitable for Halaal Diet |
Kosher | Suitable for Kosher Diet |
LactoseIntol | Suitable for Lactose Intolerants |
Vegan | Suitable for Vegans |
Veg | Suitable for Vegetarians |
Barley | Barley |
Chestnuts | Chestnuts |
Sulphites | Contains Sulphites |
Sulph | Contains Sulphur Dioxide (if greater than 10mg/kg) |
CottonSeed | Cotton seed |
Kamut | Kamut (Wheat) |
Oats | Oats |
OtherNuts | Other |
OtherSeeds | Other |
Peanuts | Peanuts |
PineNuts | Pine Nuts |
PoppySeed | Poppy Seed |
Rye | Rye |
SeedOils | Seed Oils |
Spelt | Spelt (Wheat) |
SunflowerSeed | Sunflower Seed |
TreeNuts | Tree Nuts |
CerealsWheat | Wheat |
Almonds | Almonds |
BrazilNuts | Brazil Nuts |
CashewNuts | Cashew Nuts |
Hazelnuts | Hazelnuts |
Macadamias | Macadamia or Queensland Nuts |
PecanNuts | Pecan Nuts |
Pistachios | Pistachios |
Walnuts | Walnuts |
Error messages for ingredientintolerance
Error Message | Description |
---|---|
Supplier Name does not exist in StarChef or Value is missing. | Supplier Name value is missing or does not exist in StarChef. |
Supplier Code is mandatory and must be less than 50 characters. | Supplier Code value missing or too long. |
No ingredient exists for this Supplier Name and Supplier Code combination. | Such ingredient does not exist. |
Intolerance value is invalid. | Intolerance value must be yes / no / may / null. |
Intolerance Code does not exist in Starchef or Value is missing | Intolerance code missing or incorrect. See the intolerance values table for possible values. |
Making ingredientcategory requests
The ingredientcategory resource lets you add categories to an ingredient.
Our Fourth Inventory for Restaurants solution has a hierarchy of user-defined categories. You can include the top three levels in this request, which are:
- Category Type
- Main Category
- SubCategory
Before you can add an ingredient to ingredient categories, the categories must already exist in Fourth. You can use the Recipe & Menu Engineering Export API to retrieve a list of existing categories.
An ingredient may have more than one category applied to it. In which case, one of the categories must become the default category for the ingredient.
<ArrayOfIngredientCategory> <IngredientCategory> <SupplierName>Chris's produce</SupplierName> <SupplierCode>CHRI103</SupplierCode> <CategoryTypeName>Cost Center</CategoryTypeName> <MainCategoryName>Food</MainCategoryName> <SubCategoryName>Vegetables</SubCategoryName> <IsDefault>yes</IsDefault> </IngredientCategory> </ArrayOfIngredientCategory>
Error messages for ingredientcategory
Error Message | Description |
---|---|
Supplier Name does not exist in StarChef or Value is missing. | Supplier Name value not provided or does not exist in StarChef. |
Supplier Code is mandatory and must be less than 50 characters. | Supplier Code value is missing or too long. |
Category type does not exist in Starchef or Value is missing. | Missing Category Type value or Category Type does not exist in StarChef. |
Required Ingredient Category Type not found. | Mandatory Category Type not provided for the ingredient. |
Invalid category tree structure provided. | All provided categories exist but structure is incorrect. |
is_default value is invalid | Incorrect is_default value. |
Invalid category for alternate ingredients | Category provided is applicable only for parent ingredients. |
Categories cannot be set for alternate ingredients inherited from parent ingredients | Alternates with "Inherit Parent Values" cannot have category value updated. |
Making ingredientconversion requests
This request adds or updates conversion information for an ingredient.
Conversions let you take the unit of measure for purchasing (the "supply quantity") and provide a more recipe-friendly unit of measure elsewhere in Fourth.
In the screenshot:
- quantity is the left column (values 1, 1, and 1)
- number is the middle (values: 800, 1 and 12)
To remove a conversion for a unit of measure, leave the quantity and number values empty. You can only delete conversions that are not in use.
For a list of unit of measures for UnitCode, see the Unit of measure (UoM) values and codes table.
The following example shows the same ingredient having two new conversions added (for piece and cup (UK)), and one removed (for btl).
POST /ingredientconversion HTTP/1.1 Host: instance.example.com Content-Type: application/xml Authorization: Basic VXNlcm5hbWU6cGFzc3dvcmQ= <ArrayOfIngredientConversion> <IngredientConversion> <SupplierName>Chris's produce</SupplierName> <SupplierCode>CHRIS201</SupplierCode> <UnitCode>piece</UnitCode> <Quantity>8</Quantity> <Number>1</Number> </IngredientConversion> <IngredientConversion> <SupplierName>Chris's produce</SupplierName> <SupplierCode>CHRIS201</SupplierCode> <UnitCode>cup (UK)</UnitCode> <Quantity>4</Quantity> <Number>1.5</Number> </IngredientConversion> <IngredientConversion> <SupplierName>Chris's produce</SupplierName> <SupplierCode>CHRIS201</SupplierCode> <UnitCode>btl</UnitCode> <Quantity></Quantity> <Number></Number> </IngredientConversion> </ArrayOfIngredientConversion>
Error messages for ingredientconversion
Error Message | Description |
---|---|
Invalid product. | The combination of Supplier Name value and Supplier Code value does not exist in StarChef. |
Supplier Name does not exist in StarChef or Value is missing. | Supplier Name value not provided or does not exist in StarChef. |
Supplier Code is mandatory and must be less than 50 characters. | Supplier Code value missing or too long. |
Invalid UoM name | UoM UnitCode missing or incorrect. See the Unit of measure (UoM) values and codes table for a list of possible values. |
Invalid UoM quantity value. | UoM Quantity value incorrect. |
Missing UoM quantity value. | UoM Quantity value is missing. |
Invalid UoM number value. | UoM Number value is incorrect. |
Missing UoM number value. | UoM Number value is missing. |
Duplicate UoM Conversion. | UoM conversion for this particular UoM already exists. |
Duplicate UoM Weight. Only one Weight UoM per ingredient is allowed. | Only one Weight UoM per ingredient is allowed. |
Duplicate UoM Volume. Only one Volume UoM per ingredient is allowed. | Only one Volume UoM per ingredient is allowed. |
Unable to delete non-existent UoM Conversion. | Trying to delete UoM conversion that does not exist. |
Unable to delete UoM Conversion. It is used in recipe/menu/alternates. | Trying to delete UoM conversion which is used in another item, remove the usage first. |
Making ingredientshelflife requests
Use the ingredientshelflife resource to view and manage the shelf life of ingredients:
- POST /ingredientshelflife
- GET /ingredientshelflife
You will need to talk to your customer about their Fourth settings when integrating with this resource. Customers can tailor the six shelf life fields in Fourth for their own use (normally done during the Fourth implementation stage). Therefore, the names that customers use for the fields may not match the ones in the API request. For example, ShelfLifeTwo may be named “Maximum shelf life from freezer” in the UI. Most customers only use a few of the shelf life fields.
As well, each customer can have a global setting for the minimum and maximum accepted shelf life for items. When Fourth receives a POST /ingredientshelflife request, we check that the values sent are within the customer’s limits. If one or more of the values is outside a limit, Fourth returns an error message in the format:
The value should be between [min - max] value.
The POST /ingredientshelflife endpoint lets you add or update shelf life values. Unlike most fields in the POST requests for this API, you can choose to update ONLY the shelf life fields that are relevant. Any fields you don’t include in the request retain their current value.
You cannot send through a null value. However, 0 is an accepted value — you should discuss with your customer what this value would mean for them.
Example POST /ingredientshelflife request body
This example shows all the possible shelf life fields.
[ { "ShelfLife": "12", "ShelfLifeTwo": "2", "ShelfLifeThree": "0", "ShelfLifeFour": "0", "MinShelfLifeIntoUnit": "0", "MinShelfLifeDays": "0", "SupplierName": "Dairy", "SupplierCode": "B365", "StarChefKey": "0030702" } ]
The GET /ingredientShelfLife returns the shelf life values for an ingredient. This can include empty strings, as most customers do not use all the shelf life fields.
You can filter these requests by ingredient productId, guid, and groupGuid.
Example GET /ingredientShelfLife response body
[ { "ShelfLife": "7", "ShelfLifeTwo": "3", "ShelfLifeThree": "", "ShelfLifeFour": "", "MinShelfLifeIntoUnit": "", "MinShelfLifeDays": "", "SupplierName": "The Farm", "SupplierCode": "C132", "StarChefKey": "0031291" } ]
For more information about these endpoints, see the API Reference:
Making recipeprepsteps requests
The /recipeprepsteps endpoint lets you GET and POST recipe preparation steps.
In the recipe preparations area of Fourth, there are three tabs that cover the following preparation details: Method, Mise En Place or Critical Control Points. You can update the steps in each of these tabs. When sending through an update via the POST request, you only need to include the updates. If you need to delete a step, do this by including the step's row number with no value for the text field.
Example GET response / POST body
[ { "StarChefKey": "0030702", "PrepTabName": "mep", "RowNumber": "1", "Text": "Ensure you have frozen cucumber and lime garnish." }, { "StarChefKey": "0030702", "PrepTabName": "method", "RowNumber": "1", "Text": "Fill old-fashioned glass one-quarter with crushed ice." }, { "StarChefKey": "0030702", "PrepTabName": "method", "RowNumber": "2", "Text": "Add tequila and top off with club soda." }, { "StarChefKey": "0030702", "PrepTabName": "method", "RowNumber": "3", "Text": "Add frozen cucumber and lime slices." }, { "StarChefKey": "0030702", "PrepTabName": "ccp", "RowNumber": "1", "Text": "Wash hands first." }, { "StarChefKey": "0030702", "PrepTabName": "ccp", "RowNumber": "2", "Text": "Do not refreeze." } ]
Troubleshooting
Questions
I received a response that said "Not processed" — what should I do?
It's not possible for Fourth to process every request before the synchronous response is sent back. This means that valid requests may receive a status of Not processed. When this happens, you can use the /batches endpoint to check later whether a requests was processed.
Most requests are processed within a few minutes. However, make sure there is a reasonable delay before checking the processing; for example one hour allows for plenty of time. If the request status is still Not processed then you can either:
- Retry the request
- Raise a case via your mutual customer
How do I tell whether there was an issue with my request after processing?
If there is an issue with processing a requests, then an exception report is created. When Fourth provides your API credentials, we will also ensure to ask for an email address to send exception reports so that you are aware of any request failures.