Integrate Menus

Flyt supports integrated menu retrieval (either by Flyt requesting updated menus, or you posting menus to Flyt). Flyt also supports updating the stock of menu items.

Getting your menus to Flyt

To get your menus to Flyt, you can either create an endpoint that Flyt will call to retrieve the menus, or you can send us the menu in a POST request whenever it changes.

Flyt retrieves menus from your integration

The first option to get menus to Flyt would be to implement an endpoint that Flyt will call to retrieve menus.

Flyt will make a POST request to this endpoint with the following body, expecting to be able to get any menus that exist for that location.

POST /your/menus/endpoint

Headers
"Content-Type": "application/json"

Body
{
  "type" : "GetMenu",
  "posLocationId" : "...",
}

Flyt will expect a JSON response that matches Flyt's baseline menu structure. Expected structure

Response: 200 OK

Headers
"Content-Type": "application/json"

Body
{
  "baseline_menus": [ ... ]
}

Sending your menus to Flyt directly (in Flyt's format)

The second option to get menus to Flyt would be to send a POST request to Flyt when your menus have been updated.

This requires some setup from our team in order to enable the functionality. In particular, you will need a posBusinessName given to you in order to have an endpoint you can send the menus to. You will also be given an API Key you need to pass to the request with the header X-Flyt-API-Key.

When your menus have been updated, make a POST request to Flyt with your menus in Flyt's baseline menu structure as the request body. Expected structure

POST {host}/ingest/menu/{posBusinessName}/locations/{locationReference}

Headers
"Content-Type": "application/json"
"X-Flyt-API-Key": "4rIrG7hbY6QEUW9ewoB3bnLeYIIaxLbi"

Body
{
  "baseline_menus": [ ... ]
}

If the menu is in the correct format, Flyt will respond with:

SUCCESS: 202 Accepted
{
  "success": true
}

and then the menu will be created, asynchronously. A webhook will be sent to inform you the new menu is available. Look at this section to find out what you'll need to set up one

In case of failure, the response will be:

400 Bad Request
{
  "success": false,
  "errorMessage": "Baseline menus not valid.",
  "validationErrors": [
    {
      "dataPath": "",
      "message": "should have required property 'baseline_menus'"
    }
  ]
}

or

500 Internal server error
{
  "success": false,
  "errorMessage": "gRPC failure"
}

Sending your menus to Flyt directly (in your format)

If Flyt has built an integration for your POS, you can post your menu to Flyt in the format native to your POS.

The structure of this call is:

POST {host}/pos/{posName}/business/{businessName}/menus

Headers
"X-Flyt-Api-Key" : "..."

Body
{
  "... Your menu structure here"
}

Menu terms and structure

Menus sent to Flyt should match our internal menu structure, which is based on a set of TypeScript interfaces.

Glossary of menu terms used by Flyt

We consistently use these terms to refer to properties of menus within Flyt. Ideally, your menu should match this structure.

Expand
  • Availability: Days and times that the specific menu is available, e.g. if you have a breakfast menu that's only available from 7am - 11am on weekdays.
  • Categories: A menu can have many categories which describe a logical subset of the menu, e.g. Starters, Mains or Drinks.
  • Items: Menu categories can contain many items. An item appears on the menu and represents a thing on the menu that a user may be interested in ordering, eg. Chicken Burger and Chips.
  • Modifiers: Modifiers allow the customisation of an ingredient, e.g. cooking preference or a constituent part of an item such as Cheese, Mayo or Well Done.
  • Options: Contains common modifier options that can be included or removed from the menu. These have the same structure as items.
  • Default: It's a boolean attribute an specify an a default option.
  • Includes: These options are ingredients that come with the item by default and the user can choose to remove them if they contain a PLU.
  • Swap: Swap is used on an item that has no PLU and the options within the swap are presented as a required choice.
  • Portions: For when different sizes of the same item are available. For example, we may want to sell a beer in bottles or pints, so an item San Miguel may contain the potions 330ml and 1 Pint.
  • Pick: Number of options that can be picked by the user when ordering. There are three different kinds of pick - Pick Exactly (customer can choose exactly that many options), Pick Range (customer can choose between the "to" and "from" values of options), and Pick Unlimited (customer can choose as many as they want, typically for options that are not free). See What is Pick? for info on how to structure Pick

For the whole menu structure available, please refer to our API swagger documentation

Example
{
  "baseline_menus": [
    {
      "name": "Lunch/Dinner menu",
      "reference": "2",
      "type": "DELIVERY", // Can be ANY, COLLECTION, EAT_IN or DELIVERY
      "availability": {
        "monday": ["00:01 - 23:51"],
        "tuesday": ["00:02 - 23:52"],
        "wednesday": ["00:03 - 23:53"],
        "thursday": ["00:04 - 23:54"],
        "friday": ["00:05 - 23:55"],
        "saturday": ["00:06 - 23:56"],
        "sunday": ["00:07 - 23:57"]
      },
      "categories": [
        {
          "name": "Burger Meals",
          "description": "Will delight burger lovers",
          "items": [
            {
              "name": "Cheeseburger",
              "description": "Will make you cry with joy",
              "plu": "3", // must be unique
              "price": 1099, // amount in cents
              "modifiers": [
                {
                  "name": "Extra for Cheeseburger",
                  "description": "Choose your extras",
                  "pick": {
                    // see FAQ below for information on how to structure pick
                    "range": {
                      "from": 0,
                      "to": 9
                    },
                    "pick_same_option": false
                  },
                  "options": [
                    {
                      "name": "Extra Cheese [45.0 Cals]",
                      "description": "",
                      "plu": "11231", // must be unique
                      "price": 50,
                      "modifiers": [],
                      "includes": [],
                      "ingredients": []
                    }
                  ]
                }
              ],
              "includes": [
                {
                  "name": "Tomato",
                  "plu": "52413", // PLU To remove this item
                  "description": "Juicy",
                  "modifiers": [
                    {
                      // AS ABOVE
                    }
                  ]
                }
              ],
              "ingredients": [
                {
                  "name": "Tomato"
                }
              ],
              "swap": {
                //Swaps are required modifiers that will override the base plu and price
                "name": "Cheese choice",
                "options": [
                  {
                    "name": "Cheddar",
                    "plu": "12",
                    "price": 1199,
                    "reference": "id-12"
                  },
                  {
                    "name": "Bufala Mozzarella",
                    "plu": "13",
                    "price": 1299,
                    "reference": "id-13"
                  }
                ]
              }
            }
          ]
        }
      ]
    }
  ]
}

Updating Item Stock

The following endpoint is still in development and the spec may change

You can call this endpoint when you need to update whether an item is in-stock or out-of-stock.

An example request:

POST {host}/stock/{posName}/businesses/{flytBusinessId}/locations/{locationReference}/stock-update

Headers
"X-Flyt-Api-Key" : "..."

Body
{
    "event": "IN_STOCK|OUT_OF_STOCK", // Required
    "itemReference": "1234-3324332-23423-234", // Required (POS's item ID)
    "happenedAt": "2018-10-11T14:56:18.234284+01:00", // Required
    "menuReference": "345345", // Optional
}

If successful, Flyt will respond:

SUCCESS: 202 Accepted
{
  "success": true
}

and if failed:

400 Bad Request
{
  "success": false,
  "errorMessage": "Payload not valid",
  "validationErrors": [
    {
      "dataPath": ".event",
      "message": "should be equal to one of the allowed values"
    }
  ]
}

or

500 Internal server error
{
  "success": false,
  "errorMessage": "gRPC failure"
}

FAQ

What is "Pick"?

Pick is the number of options that can be picked by the user when ordering. There are three types of pick which will be determined by the structure of the Pick object.

  • PickExactly – Customer can choose an exact amount of modifier options for an item. E.g. Customer orders a coffee and its modifier is size – customer can pick exactly one size and cannot pick same option multiple times.
{
  exactly: Integer;
  pick_same_option: Boolean;
}
  • PickRange – Customer can choose a number of modifier options between a range of two integers. E.g. Customer orders toast and one of the modifiers is extras, with a pick range from 0 to 3 and pick_same_option: true – the customer can order toast with extra cheese and tomato, or just bacon strips 3 times.
{
  range: {
    from: Integer;
    to: Integer;
  }
  pick_same_option: Boolean;
}
  • PickUnlimited – Customer can choose as many modifier options as they'd like, with no limit. The only limitation might be picking same option more than once.
{
  pick_same_option: Boolean;
}

Will I be notified when the menu reflects an update?

You can ask our team to setup a webhook to the services providers that are going to use the menu to receive updates when the new (updated) menu will be available.

Read this page for more information about this functionality.

What is "locationReference"?

Location reference is the value the POS uses to reference itself, that needs to be setup on the location page on Flyt portal.

What is "itemReference"?

In 99% of cases this will be your PLU, but there are some cases where this isn't unique enough and then you can send us other data.

What is "posBusinessName"

Is an unique string that defines your POS and your business. Our team needs to set up this for you, so get in contact with them if you don't have one already.