Menu Cycles API Guide

Introduction

With the Menu Cycles API, you can access the menu cycle data in Fourth for use on POS platforms and other systems.

Quick Facts

API type HTTPS REST with JSON, with webhook option
Authentication OAuth with client credentials
Availability Where customers are using menu cycles within our Inventory for Restaurants solution
Testing A test environment is available upon request
More information See the API Reference

Get access

To get started with this API, you will need:

  • A set of OAuth credentials
  • The URL for OAuth requests
  • The root URL for Menu Cycle API requests to both test and live environments

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

Updates

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

Data Hierarchy

The overall hierarchy for data in the Menu Cycles API is as follows. The items in bold can be sold. In the API, they are listed as ScheduledItems. The API endpoints show only items that have been scheduled.

  • Customer
    • Location +
      • Menu Cycle +
        • Meal Period +
          • Recipe +
            • Tariff price +
          • Menu (buffet) +
            • Recipe +
            • Tariff price +
          • Menu (à la carte) +
            • Recipe +
              • Tariff price +

Get Locations

Menu cycles are published by location in Fourth. Before you can make most Menu Cycle API requests, you will need to know the identifiers for customer locations. You can do this using a GET /Locations request. The response will include a LocationId for each location — use this in the URLs for other requests. This ID is unique and will not change for a location or be otherwise reused.

Example response

{
  "continuationToken": "175", 
  "value": [
    {
      "LocationId": 17,
      "Name": "School Canteen 1",
      "Description": "On rooftop",
      "UnitCode": "SCH01",
      "UnitName": "London Schools - Secondary",
      "TimeZone": "Europe/London",
      "CurrencyCode": "GBP"
    }
  ]
}

Note that in Fourth Inventory, the term Sites is used for Locations.

Retrieve menu, recipe and ingredient details

The Menu Cycles API provides endpoints specific to working with menu cycles. It is not intended to replace the functionality that already exists in the Recipe & Menu (RME) Export API; the RME Export API is your go-to for retrieving detailed information on menus, recipes and ingredients. You can find documentation for this here:

Note that the RME Export API uses the term GUID rather than ID to identify the Fourth unique identifier for a recipe, menu or ingredient. For example, for recipes, the Menu Cycles API returns a recipeId in the response to a GET <ROOT>/Locations/{LocationId}/Recipes request:

{
  "value": [
    {
      "recipeName": "French Crepes",
      "recipeId": "6c3fec7d-97c9-48f8-b84e-13bb179b9fa6",
      "plu": "001345",
      "costPrice": 2.80
    }
  ]
}

However, in the RME Export API, the GET <ROOT>/Recipes request returns a RecipeGuid  (example is shortened):

[
   {
      "RecipeGuid": "6c3fec7d-97c9-48f8-b84e-13bb179b9fa6",
      "PLU": "001345",
      "StarChefKey": "00123567",
      "Type": "Standard",
      ...

Note that PLUs are not necessarily unique, so cannot be used as an identifier.

Get additional Locations page results using continuationToken

Fourth may potentially respond with many records to GET /Locations requests. To ensure that we can successfully manage your requests, we provide pagination of results when this occurs.

Pages are paginated using a continuationToken value returned with the response. You will only receive a continuationToken when the available records exceeds the maximum number of records we can include in the response, and there are more available. For example:

GET /Locations HTTP/1.1 
Host: example.fourth.com 
Accept: text/json

{
  "continuationToken": "175", 
  "value": [
    {
      "LocationId": 17,
      "Name": "School Canteen 1",
      "Description": "On rooftop",
      "UnitCode": "SCH01",
      "UnitName": "London Schools - Secondary",
      "TimeZone": "Europe/London",
      "CurrencyCode": "GBP"
   },
   {
      "LocationId": 2,
      "Name": "School Canteen 2",
      "Description": "Downstairs",
      "UnitCode": "SCH02",
      "UnitName": "London Schools - secondary",
      "TimeZone": "Europe/London",
      "CurrencyCode": "GBP"
   },
   ...

To retrieve the next set of results, include the continuationToken query parameter in your request:

GET <ROOT>/Locations/{LocationId}/Menus?continuationToken=175

If there are further results that you can access, the response will have a new continuationToken number:

GET /Locations HTTP/1.1
Host: example.fourth.com
Accept: text/json

{ 
   "continuationToken": "223", 
   "value": [ 
     {
       "LocationId": 2,
       "Name": "School Canteen 73",
       "Description": "ground floor",
       "UnitCode": "SCH73",
       "UnitName": "Bradford Schools - primary",
       "TimeZone": "Europe/London",
       "CurrencyCode": "GBP"
     },
     ...

Note that continuationToken numbers are NOT sequential.

You will continue to receive a continuationToken until there are no records left to return.

Time and date formats in use

All dates and timestamps are in ISO 8601 format:

  • Date and time in location time zone: YYYY-MM-DDTHH:MM:SS
  • Date and time in UTC: YYYY-MM-DDTHH:MM:SSZ
  • Date-only in location time zone: YYYY-MM-DD

Time zone information is provided in a separate field, where needed.

All dates and times provided are in the timezone of the specified location.

How to integrate with the webhook

Please see the separate page Menu Cycles API: Webhook Guide for details on this feature.

Response from Fourth

Successful requests receive a HTTPS 200 OK response from Fourth, with the requested data in the response body. Fields with value of null will not be present in the API response.

Unsuccessful response will receive an error message, as detailed on the API Reference page for each request. An overview of the type of error responses you could receive is next.

Error messages

The API returns standard HTTP status codes.

HTTP Status Code Description

400

Bad Request.

The request had invalid data, or did not provide all the mandatory data. The response body will include a description of the error.

403

Forbidden.

The provided authorization does not have access to the requested data, or the data does not exist.

500

Server Error.

The server could not complete the request. Details of the error are sent to Fourth support.  Please retry the request after 1 minute, using a truncated backoff strategy. Please raise a request via the mutual Fourth customer if the error continues.

Troubleshooting

What should I do if I don't receive a response from Fourth?

If you do not receive a response, you should retry your request using a truncated backoff strategy. Please retry requests no more than once a minute. Get in contact with Fourth if you continue to not receive responses.