NAV
shell

Overview

Introduction

Your integration is going to be linked with an Organization, and that Organization has a list of Locations. Each location can have more than one brand (Sushi, Poke, Burgers, ...). And each brand has a catalog with a different set of products.

When you create a new Order, it has to be linked to a specific brand (brand ids are unique, the same brand in different locations has a different id). Then we will route the order to the right location under the right brand name.

Please contact with our support team at hola@last.app to receive a token.

Authentication

For both the Rest API and the webhooks we use the same authentication method. We will share with you a secret token, and in all the requests it has to be included as a header.

Authorization: Bearer \${token}

Rest API

GET Location List

[
  {
    "id": "f2779a96-578f-4649-89f6-a0972183efea",
    "name": "Pl Catalunya",
    "address": "Plaça de Catalunya, 08002 Barcelona",
    "email": "notifications@restBarcelona.com",
    "postalCode": "08002",
    "phoneNumber": "666666666",
    "latitude": 41.441969,
    "longitude": 2.203933,
    "region": "Barcelona",
    "city": "Barcelona",
    "externalId": "2345",
    "defaultPosCatalogId": "f2779a96-578f-4649-89f6-a0972183efea",
    "brands": [
      {
        "id": "23cdda27-2f82-46e4-a366-deecd5d420d0",
        "name": "My Sushi Brand",
        "catalogs": {
          "default": "03406b61-0dfc-40a9-a07b-408960d8cc1c",
          "glovo": "3c085f01-140f-47dc-80d9-5225bb67774d",
          "deliveroo": "9a408ddc-8438-4549-95e6-5cee67a2d648",
          "uber": "13a2c877-3856-4dcc-b071-645a26de938e",
          "shop": "3c085f01-140f-47dc-80d9-5225bb67774d"
        }
      },
      {
        "id": "f2779a96-578f-4649-89f6-a0972183efea",
        "name": "My Poke Brand",
        "catalogs": {
          "default": "03406b61-0dfc-40a9-a07b-408960d8cc1c",
          "glovo": "3c085f01-140f-47dc-80d9-5225bb67774d",
          "deliveroo": "9a408ddc-8438-4549-95e6-5cee67a2d648",
          "uber": "13a2c877-3856-4dcc-b071-645a26de938e",
          "shop": "3c085f01-140f-47dc-80d9-5225bb67774d"
        }
      }
    ],
    "postalCodes": [
      {
        "postalCode": "08002",
        "comments": ""
      },
      {
        "postalCode": "08013",
        "comments": ""
      }
    ],
    "preparationMinutes": 15,
    "polygons": [
      [
        { "lat": 41.13361190470618, "lng": 1.2731949865977343 },
        { "lat": 41.14027007942357, "lng": 1.2880436957041796 },
        { "lat": 41.14123966013921, "lng": 1.3035790503184375 },
        { "lat": 41.13238362388618, "lng": 1.3143937170664843 },
        { "lat": 41.124172945711976, "lng": 1.2845246374766406 }
      ],
      [
        { "lat": 41.13361190470618, "lng": 1.2731949865977343 },
        { "lat": 41.14027007942357, "lng": 1.2880436957041796 },
        { "lat": 41.14123966013921, "lng": 1.3035790503184375 },
        { "lat": 41.13238362388618, "lng": 1.3143937170664843 },
        { "lat": 41.124172945711976, "lng": 1.2845246374766406 }
      ]
    ],
    "shopAreas": [
      {
        "id": "a830f995-0234-446f-ac42-c3e2492881bb",
        "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
        "name": "Sicilia",
        "deliveryFee": 1200,
        "deliveryExtraMinutes": 11,
        "minimumBasket": 1000,
        "polygon": [
          { "lat": 41.411206735924424, "lng": 2.170459031494123 },
          { "lat": 41.39781609535299, "lng": 2.1618759626464668 },
          { "lat": 41.39408167471969, "lng": 2.1728622907714668 },
          { "lat": 41.40039143284847, "lng": 2.191058396728498 },
          { "lat": 41.41107799290444, "lng": 2.190886735351545 }
        ],
        "enabled": false,
        "estimatedDeliveryMinutes": 26
      },
      {
        "id": "4123e3a2-2b2b-4c28-a733-50e87735b352",
        "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
        "name": "maracaibo",
        "deliveryFee": 190,
        "deliveryExtraMinutes": 30,
        "minimumBasket": 1000,
        "polygon": [
          { "lat": 41.44968945529636, "lng": 2.1989548200683418 },
          { "lat": 41.441582953121106, "lng": 2.1914017194824043 },
          { "lat": 41.431287522523725, "lng": 2.2140610212402168 },
          { "lat": 41.44261240636137, "lng": 2.2152626508788886 }
        ],
        "enabled": false,
        "estimatedDeliveryMinutes": 45
      },
      {
        "id": "8fd4a673-ef0c-4730-9e00-95e2c31b7982",
        "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
        "name": null,
        "deliveryFee": 0,
        "deliveryExtraMinutes": null,
        "minimumBasket": null,
        "polygon": [
          { "lat": 41.39196569037639, "lng": 2.1377135546310333 },
          { "lat": 41.38882630455909, "lng": 2.1463767238319598 },
          { "lat": 41.38410500329319, "lng": 2.1495199068802373 },
          { "lat": 41.38307532428261, "lng": 2.150013351287412 },
          { "lat": 41.37685162391421, "lng": 2.146658155003527 },
          { "lat": 41.37404910631808, "lng": 2.1377883369850625 },
          { "lat": 41.37480752561103, "lng": 2.1328979464657216 },
          { "lat": 41.37646762430614, "lng": 2.1288658628311463 },
          { "lat": 41.38069737451375, "lng": 2.1261875712639 },
          { "lat": 41.38357578862208, "lng": 2.125515120724928 },
          { "lat": 41.38885148878816, "lng": 2.128108690495516 }
        ],
        "enabled": true,
        "estimatedDeliveryMinutes": 15
      },
      {
        "id": "da32a7e9-a541-40f7-9626-f9e53d59661f",
        "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
        "name": null,
        "deliveryFee": 0,
        "deliveryExtraMinutes": null,
        "minimumBasket": null,
        "polygon": [
          { "lat": 41.380224370506724, "lng": 2.194976676493545 },
          { "lat": 41.34775919146317, "lng": 2.1757673426458446 },
          { "lat": 41.33641777131268, "lng": 2.130792061884126 },
          { "lat": 41.35549084543963, "lng": 2.089936654169282 },
          { "lat": 41.38331719623883, "lng": 2.074830452997407 },
          { "lat": 41.396324507960216, "lng": 2.082726876337251 },
          { "lat": 41.411389130337874, "lng": 2.092683236200532 },
          { "lat": 41.425034405220025, "lng": 2.1369718714544383 },
          { "lat": 41.41422140427475, "lng": 2.176453988153657 }
        ],
        "enabled": true,
        "estimatedDeliveryMinutes": 15
      },
      {
        "id": "e359f624-2d2d-4691-a304-065fbc0c7bc6",
        "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
        "name": null,
        "deliveryFee": 0,
        "deliveryExtraMinutes": null,
        "minimumBasket": null,
        "polygon": [
          { "lat": 41.41011215450934, "lng": 2.136979783830233 },
          { "lat": 41.40173217584032, "lng": 2.162002071890834 },
          { "lat": 41.383048038305674, "lng": 2.17191815877956 },
          { "lat": 41.362030226927445, "lng": 2.160765392134474 },
          { "lat": 41.355954211595176, "lng": 2.135193069825325 },
          { "lat": 41.36536498320847, "lng": 2.111060385131056 },
          { "lat": 41.38198763769528, "lng": 2.1013472561008895 },
          { "lat": 41.39975954721055, "lng": 2.112853868690081 },
          { "lat": 41.40774235345601, "lng": 2.131570259111344 }
        ],
        "enabled": true,
        "estimatedDeliveryMinutes": 15
      },
      {
        "id": "e5f9db87-9b79-433f-b38e-85c47313bc21",
        "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
        "name": null,
        "deliveryFee": 0,
        "deliveryExtraMinutes": null,
        "minimumBasket": null,
        "polygon": [
          { "lat": 41.41775997724526, "lng": 2.137298453837295 },
          { "lat": 41.409520740821016, "lng": 2.16613756516542 },
          { "lat": 41.40874825882698, "lng": 2.169914115458389 },
          { "lat": 41.38093279015199, "lng": 2.1829603801068265 },
          { "lat": 41.35387856255594, "lng": 2.1668242106732327 },
          { "lat": 41.34563122807394, "lng": 2.132835258036514 },
          { "lat": 41.35903261605653, "lng": 2.1009062419232327 },
          { "lat": 41.38170560278213, "lng": 2.0882033000287015 },
          { "lat": 41.40643075773568, "lng": 2.1036528239544827 }
        ],
        "enabled": true,
        "estimatedDeliveryMinutes": 15
      }
    ],
    "workingTimes": {
      "default": {
        "thursday": [
          {
            "id": "6939ef89-9179-4ab8-97ff-d394999b5370",
            "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
            "day": "thursday",
            "start": "08:00",
            "end": "00:00"
          }
        ],
        "monday": [
          {
            "id": "6c2d8783-b299-4a44-9a9b-fae4f0b92874",
            "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
            "day": "monday",
            "start": "08:00",
            "end": "00:00"
          }
        ],
        "wednesday": [
          {
            "id": "991070eb-9561-460f-ad61-177affdc1b7b",
            "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
            "day": "wednesday",
            "start": "08:00",
            "end": "00:00"
          }
        ],
        "tuesday": [
          {
            "id": "aa1f3526-209c-4471-8a0c-090a10c0c975",
            "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
            "day": "tuesday",
            "start": "08:00",
            "end": "00:00"
          }
        ],
        "friday": [
          {
            "id": "df2c5ea5-ac9b-49a1-aff2-507cec1f528c",
            "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
            "day": "friday",
            "start": "08:00",
            "end": "00:00"
          }
        ]
      },
      "f2779a96-578f-4649-89f6-a0972183efea": {
        "friday": [
          {
            "id": "01e85701-1f9e-424c-a925-24749145cfd9",
            "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
            "day": "friday",
            "start": "08:00",
            "end": "20:00",
            "locationVirtualBrandId": "f2779a96-578f-4649-89f6-a0972183efea"
          }
        ],
        "saturday": [
          {
            "id": "9ebbec16-c4de-4ff0-9c95-400414f51d60",
            "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
            "day": "saturday",
            "start": "08:00",
            "end": "20:00",
            "locationVirtualBrandId": "f2779a96-578f-4649-89f6-a0972183efea"
          }
        ],
        "monday": [
          {
            "id": "b609a2d5-c528-42ac-bd19-4b29ba85aa59",
            "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
            "day": "monday",
            "start": "08:00",
            "end": "20:00",
            "locationVirtualBrandId": "f2779a96-578f-4649-89f6-a0972183efea"
          }
        ],
        "wednesday": [
          {
            "id": "c4ac6828-afc5-4777-864b-8df55c7af067",
            "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
            "day": "wednesday",
            "start": "08:00",
            "end": "20:00",
            "locationVirtualBrandId": "f2779a96-578f-4649-89f6-a0972183efea"
          }
        ],
        "thursday": [
          {
            "id": "d8def688-b17f-48ed-a680-0fe8acc9cf7e",
            "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
            "day": "thursday",
            "start": "08:00",
            "end": "20:00",
            "locationVirtualBrandId": "f2779a96-578f-4649-89f6-a0972183efea"
          }
        ],
        "tuesday": [
          {
            "id": "ebd13e06-dbea-40d3-b66c-05ccec1465dc",
            "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
            "day": "tuesday",
            "start": "08:00",
            "end": "20:00",
            "locationVirtualBrandId": "f2779a96-578f-4649-89f6-a0972183efea"
          }
        ]
      }
    }
  },
  {
    "id": "6df10f06-b232-4e8c-8599-d202d50f18d0",
    "name": "Prado",
    "address": "Calle del Prado, 2, 28014 Madrid",
    "email": "notifications@restMadrid.com",
    "postalCode": "28014",
    "phoneNumber": "666666666",
    "latitude": 41.441969,
    "longitude": 2.203933,
    "region": "Madrid",
    "city": "Madrid",
    "externalId": "1234",
    "defaultPosCatalogId": "f2779a96-578f-4649-89f6-a0972183efea",
    "brands": [
      {
        "id": "58ec0ff0-99ce-4ebe-b315-dd9458331209",
        "name": "My Sushi Brand",
        "catalogs": {
          "default": "03406b61-0dfc-40a9-a07b-408960d8cc1c",
          "glovo": "3c085f01-140f-47dc-80d9-5225bb67774d",
          "deliveroo": "9a408ddc-8438-4549-95e6-5cee67a2d648",
          "uber": "13a2c877-3856-4dcc-b071-645a26de938e",
          "shop": "3c085f01-140f-47dc-80d9-5225bb67774d"
        }
      }
    ],
    "postalCodes": [
      {
        "postalCode": "28001",
        "comments": ""
      },
      {
        "postalCode": "28005",
        "comments": ""
      }
    ],
    "preparationMinutes": 20,
    "polygons": [
      [
        { "lat": 41.13361190470618, "lng": 1.2731949865977343 },
        { "lat": 41.14027007942357, "lng": 1.2880436957041796 },
        { "lat": 41.14123966013921, "lng": 1.3035790503184375 },
        { "lat": 41.13238362388618, "lng": 1.3143937170664843 },
        { "lat": 41.124172945711976, "lng": 1.2845246374766406 }
      ],
      [
        { "lat": 41.13361190470618, "lng": 1.2731949865977343 },
        { "lat": 41.14027007942357, "lng": 1.2880436957041796 },
        { "lat": 41.14123966013921, "lng": 1.3035790503184375 },
        { "lat": 41.13238362388618, "lng": 1.3143937170664843 },
        { "lat": 41.124172945711976, "lng": 1.2845246374766406 }
      ]
    ],
    "shopAreas": [
      {
        "id": "a830f995-0234-446f-ac42-c3e2492881ba",
        "locationId": "f2779a96-578f-4649-89f6-a0972183efef",
        "name": "Testing Shop",
        "deliveryFee": 1200,
        "deliveryExtraMinutes": 11,
        "minimumBasket": 1000,
        "polygon": [
          { "lat": 41.411206735924424, "lng": 2.170459031494123 },
          { "lat": 41.39781609535299, "lng": 2.1618759626464668 },
          { "lat": 41.39408167471969, "lng": 2.1728622907714668 },
          { "lat": 41.40039143284847, "lng": 2.191058396728498 },
          { "lat": 41.41107799290444, "lng": 2.190886735351545 }
        ],
        "enabled": false,
        "estimatedDeliveryMinutes": 26
      }
    ],
    "workingTimes": {
      "default": {
        "thursday": [
          {
            "id": "6939ef89-9179-4ab8-97ff-d394999b5370",
            "locationId": "6df10f06-b232-4e8c-8599-d202d50f18d0",
            "day": "thursday",
            "start": "08:00",
            "end": "00:00"
          }
        ],
        "monday": [
          {
            "id": "6c2d8783-b299-4a44-9a9b-fae4f0b92874",
            "locationId": "6df10f06-b232-4e8c-8599-d202d50f18d0",
            "day": "monday",
            "start": "08:00",
            "end": "00:00"
          }
        ],
        "wednesday": [
          {
            "id": "991070eb-9561-460f-ad61-177affdc1b7b",
            "locationId": "6df10f06-b232-4e8c-8599-d202d50f18d0",
            "day": "wednesday",
            "start": "08:00",
            "end": "00:00"
          }
        ],
        "tuesday": [
          {
            "id": "aa1f3526-209c-4471-8a0c-090a10c0c975",
            "locationId": "6df10f06-b232-4e8c-8599-d202d50f18d0",
            "day": "tuesday",
            "start": "08:00",
            "end": "00:00"
          }
        ],
        "friday": [
          {
            "id": "df2c5ea5-ac9b-49a1-aff2-507cec1f528c",
            "locationId": "6df10f06-b232-4e8c-8599-d202d50f18d0",
            "day": "friday",
            "start": "08:00",
            "end": "00:00"
          }
        ]
      },
      "58ec0ff0-99ce-4ebe-b315-dd9458331209": {
        "friday": [
          {
            "id": "01e85701-1f9e-424c-a925-24749145cfd9",
            "locationId": "6df10f06-b232-4e8c-8599-d202d50f18d0",
            "day": "friday",
            "start": "08:00",
            "end": "20:00",
            "locationVirtualBrandId": "58ec0ff0-99ce-4ebe-b315-dd9458331209"
          }
        ],
        "saturday": [
          {
            "id": "9ebbec16-c4de-4ff0-9c95-400414f51d60",
            "locationId": "6df10f06-b232-4e8c-8599-d202d50f18d0",
            "day": "saturday",
            "start": "08:00",
            "end": "20:00",
            "locationVirtualBrandId": "58ec0ff0-99ce-4ebe-b315-dd9458331209"
          }
        ]
      }
    }
  }
]

HTTP Request

GET https://api.last.app/v1/locations

Location

Field name Description
id (String) Unique identifier for the location
externalId (String) Unique identifier for the location in your system
name (String) Name of the location
address (String) Address of the location
email (String) Email of the location
phoneNumber (String) Contact phone number
latitude (Float) Latitude of the location
longitude (Float) Longitude of the location
region (String) Region of the location
city (String) City of the location
defaultPosCatalogId (String) Default POS catalog unique identifier
brands (Array) List of location brands
postalCodes (Array) List of postalCodes delimiting the delivery area
preparationMinutes (Integer) Default preparationMinutes for this location
polygons (Array) Array of polygons of the areas of service (DEPRECATED: Find polygons inside shopAreas!)
shopAreas (Array) Array of areas of service, their cost and ETA
workingTimes (Array) Array of location (default) and brands schedules

Brand

Field name Description
id (String) Unique identifier for the location brand
name (String) Brand name
catalogs (Object) Object containing catalog ids used by the brand

GET Location Floorplans

[
  {
    "id": "d482a7b0-377e-4a56-8c43-7d847738f044",
    "name": "Main",
    "tables": [
      {
        "id": "03d96ebb-b36c-43b1-874a-24eecec1abc2",
        "name": "A1",
        "seats": 2
      },
      {
        "id": "398bcf26-141f-42c5-80a2-391270d7f92a",
        "name": "B2",
        "seats": 2
      },
      {
        "id": "11b005ee-d7e3-4aea-b545-9d1d659b0396",
        "name": "Barra",
        "seats": 4
      }
    ]
  },
  {
    "id": "75b87c37-6ca2-4815-9e07-3f05b0185a66",
    "name": "Outside",
    "tables": [
      {
        "id": "cb38cb1c-9052-4637-a499-50d4fd8fc86c",
        "name": "T2",
        "seats": 2
      }
    ]
  }
]

HTTP Request

GET https://api.last.app/v1/locations/:locationId/floorplans

Floorplan

Field name Description
id (String) Unique identifier for the floorplan
name (String) Name of the floorplan
tables (Array) List of tables on this floorplan

Table

Field name Description
id (String) Unique identifier for the table
name (String) Name of the table
seats (Integer) Default number of seats for this table

GET Location Catalog

{
  "name": "Weekend catalog",
  "modifierGroups": [
    {
      "allowRepeat": false,
      "id": "c033799d-0448-4166-8f21-a3f86c115849",
      "min": 1,
      "max": 1,
      "name": "Point",
      "modifiers": [
        {
          "name": "Rare",
          "id": "120ae8bc-05e2-4e17-8dc4-4d33ae76e023",
          "organizationModifierId": "c064032c-885a-4e61-9bee-293ee030aa76",
          "priceImpact": 0,
          "externalId": "1234"
        },
        {
          "name": "Medium",
          "id": "8ddc4e32-195d-49cd-9b0e-96e3dc0945b5",
          "organizationModifierId": "b671220a-fe3a-4dff-8aef-c2a228a57e56",
          "priceImpact": 0
        },
        {
          "name": "Well done",
          "id": "12881d29-efa5-4522-a3b0-0f790b1d1e93",
          "organizationModifierId": "77a42a6f-3af3-495a-8767-2fe0816d792c",
          "priceImpact": 0
        }
      ]
    }
  ],
  "categories": [
    {
      "name": "Example category",
      "id": "d8486f43-04c6-4d94-b683-654e053957f0",
      "products": [
        {
          "name": "Burger",
          "type": "PRODUCT",
          "price": 750,
          "vatPercentage": 10,
          "allergens": ["EGG", "GLUTEN"],
          "specifications": ["glutenfree", "hot", "vegan"],
          "id": "1a2cfa61-0d75-43d1-a839-3b5ba5c3bf10",
          "externalId": "3567",
          "description": "A nice burger",
          "imageUrl": "https://res.cloudinary.com/lastpos/image/upload/someImageId",
          "modifierGroups": ["c033799d-0448-4166-8f21-a3f86c115849"],
          "organizationProductId": "e98f45e0-d614-4a44-9ab1-616489fc38f1"
        }
      ]
    },
    {
      "name": "Combos",
      "id": "combos-category-id",
      "products": [
        {
          "name": "Menu",
          "type": "COMBO",
          "price": 1000,
          "vatPercentage": 10,
          "id": "7452516e-5884-4495-b953-7997cb0d3039",
          "categories": [
            {
              "id": "a289a696-f39a-434d-af3e-421b35ed3cb6",
              "name": "First",
              "max": 1,
              "products": [
                {
                  "id": "a21192ec-5e7e-414c-8c86-df9110238ad1",
                  "name": "Edamame",
                  "priceImpact": 150,
                  "modifierGroups": []
                }
              ]
            }
          ],
          "organizationComboId": "e4a4ace0-fda5-45e7-9b77-f03d4161019c",
          "imageUrl": "https://res.cloudinary.com/lastpos/image/upload/comboImage",
          "description": "Explanation of the combo"
        }
      ]
    }
  ]
}

HTTP Request

GET https://api.last.app/v1/location/${locationId}/catalog/${catalogId}

Query params

Field name Description
showDisabled (Boolean) Send as 'true' to show disabled items also

Modifier Group

Field name Description
id (String) Identifier of the modifier group in Last
name (String) Name of the group
min (Integer) Minimum number of modifiers to be selected
max (Integer) Maximum number of modifiers to be selected
allowRepeat (boolean) If enabled a modifier can be selected multiple times
modifiers (Array) Array containing the modifiers

Product

Field name Description
id (String) Unique identifier of the product in Last
name (String) Name of the product
type (String) PRODUCT
description (String) Description of the product
imageUrl (String) Image url of the product
price (Integer) Price per unit of the product (without modifiers included)
vatPercentage (Integer) Percentage of VAT
modifierGroups (Array) Array containing the modifiers of the product
allergens (Array) Array containing the allergens of the product
specifications (Array) Array containing the specifications of the product. All possible values: ["vegetarian", "vegan", "glutenfree", "mild", "medium", "hot"]
organizationProductId (String) Unique identifier of the parent product in the organization
externalId (String) Identifier of the product in the external system

Combo

Field name Description
id (String) Unique identifier of the product in Last
name (String) Name of the product
type (String) COMBO
description (String) Description of the product
imageUrl (String) Image url of the product
price (Integer) Price per unit of the product (without modifiers included)
vatPercentage (Integer) Percentage of VAT
categories (Array) Array containing the categories of the combo
organizationComboId (String) Unique identifier of the parent combo in the organization

ComboCategory

Field name Description
id (String) Unique identifier of the category in Last
name (String) Name of the category
max (Integer) Maximum number of products to select
products (Array) Array containing the products of the category (only of type PRODUCT)

ComboProduct

Field name Description
id (String) Unique identifier of the combo in Last
name (String) Name of the product
priceImpact (Integer) Price to be added to the combo total price
modifiers (Array) Array containing the modifiers of the product

Modifier

Field name Description
id (String) Unique identifier of the modifier in Last
name (String) Name of the modifier
priceImpact (Integer) Price per unit of the modifier
externalId (String) Identifier of the modifier in the external system
organizationModifierId (String) Unique identifier of the modifier in the organization

Category

Field name Description
id (String) Unique identifier of the category in Last
name (String) Name of the category
products (Array) Array containing the products and combos of the category

GET Tab List

Allows to list tabs given a set of parameters.

{
  "tabs": [
    {
      "id": "bbcfabf5-d660-4c21-9751-4e8f197439e2",
      "name": null,
      "creationTime": "2020-07-31T15:48:22.000Z",
      "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
      "source": "Shop",
      "allergyInfo": null,
      "customerNote": null,
      "kitchenNote": null,
      "tableName": null,
      "closeTime": "2020-08-06T15:32:04.000Z",
      "cancelTime": "2020-08-06T15:32:04.000Z",
      "locationBrandId": "23cdda27-2f82-46e4-a366-deecd5d420d0",
      "customerId": "998a26bd-04a0-11ea-8884-0242ac110002",
      "code": "S002",
      "pickupType": "takeAway",
      "schedulingTime": "2020-08-02T22:30:00.000Z",
      "activationTime": "2020-08-06T15:32:04.000Z",
      "tabTables": [],
      "products": [
        {
          "id": "f3cf29da-b5c9-408f-b6e9-ba14732b0bc8",
          "catalogProductId": "7d2b8e27-e0bf-4732-8044-223943b7fd05",
          "organizationProductId": "3cbeaeca-49f6-4dda-be87-5f7cb96d12db",
          "organizationComboId": null,
          "externalId": "0534073e-3eec-4ecc-83a4-ab446a30ca2a",
          "name": "Burger",
          "price": 1400,
          "quantity": 1,
          "course": "Main",
          "comments": null,
          "fullPrice": 1400,
          "pointsExpense": 100,
          "finalPrice": 1400,
          "type": "PRODUCT",
          "promotionId": null,
          "modifiers": [
            {
              "id": "348ca8b3-28cd-4adf-a5ce-951f0158d704",
              "name": "Cheese",
              "priceImpact": 0,
              "quantity": 1,
              "catalogModifierId": "65254ec3-3ec8-4279-a5b9-118dd4391832"
            }
          ],
          "comboProducts": []
        }
      ],
      "seats": 1,
      "language": "ES",
      "bills": [
        {
          "id": "866ed6ee-f325-434b-9c8a-e5d0fc07b53f",
          "number": 859,
          "rectifiedBillNumber": 934,
          "creationTime": "2020-07-31T15:48:23.000Z",
          "finalizingTime": "2020-07-31T15:48:23.000Z",
          "company": {
            "name": "LastPOS",
            "taxId": "1234",
            "address": "Maracaibo 8, Nave 2, 08041, Barcelona"
          },
          "customerCompanyName": "Acme Inc.",
          "customerCompanyTaxId": "B12345678",
          "total": 1400,
          "tax": 127,
          "taxableBase": 1273,
          "discountTotal": 0,
          "deliveryFee": 0,
          "minimumBasketSurcharge": 0,
          "terraceSurcharge": 0,
          "terraceSurchargePercentage": 0,
          "preferredPaymentMethod": "card",
          "payments": [],
          "products": [
            {
              "id": "7a740ff2-d326-42ea-a239-c9b9125d3fc3",
              "catalogProductId": "7d2b8e27-e0bf-4732-8044-223943b7fd05",
              "tabProductId": "f3cf29da-b5c9-408f-b6e9-ba14732b0bc8",
              "name": "Burger",
              "price": 1400,
              "originalPrice": 1400,
              "quantity": 1,
              "modifiers": [
                {
                  "id": "be75642e-7f74-42e8-bd3d-de575caa1847",
                  "name": "Cheese",
                  "priceImpact": 0,
                  "quantity": 1,
                  "catalogModifierId": "54393d6e-5780-45da-a96f-8de45eac10cc"
                }
              ],
              "comboProducts": []
            }
          ]
        }
      ],
      "customerInfo": {
        "name": "Bruce",
        "surname": "Wayne",
        "phoneNumber": "+34666666666",
        "email": "batman@wayneindustries.com"
      },
      "delivery": {
        "address": "Gran Via de les Corts Catalanes, 620",
        "details": "First door to the left",
        "latitude": 41.3876734,
        "longitude": 2.1647098,
        "statuses": [
          {
            "creationTime": "2020-08-03T09:10:11.000Z",
            "status": "KITCHEN"
          },
          {
            "creationTime": "2020-08-05T14:06:09.000Z",
            "status": "CLOSED"
          }
        ],
        "courier": {
          "id": "be75642e-7f74-42e8-bd3d-de575caa1847",
          "name": "Jose"
        },
        "cutlery": false
      }
    }
  ],
  "page": 0,
  "lastPage": 0
}

HTTP Request

GET https://api.last.app/v1/tabs

Query parameters

Field name Description
locationId (String) Only retrieve tabs from this location
startDate* (DateTime) Retrieve tabs with activation time after startDate (in ISO 8601)
endDate* (DateTime) Retrieve tabs with activation time after endDate (in ISO 8601)
withDeletedBills (Boolean) Include each tab deleted bills
page (Integer) This request is paginated, you can select the page with this parameter
tableId (String) Only retrieve tabs from a specific table
tableName (String) Only retrieve tabs from tables with a specific name
open (Boolean) Only retrieve tabs which are open/closed
customerId (String) Only retrieve tabs from a specific customer

GET Tab by ID

Allows to retrieve a specific tab by its ID.

{
  "id": "bbcfabf5-d660-4c21-9751-4e8f197439e2",
  "name": null,
  "creationTime": "2020-07-31T15:48:22.000Z",
  "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
  "source": "Shop",
  "allergyInfo": null,
  "customerNote": null,
  "kitchenNote": null,
  "tableName": null,
  "closeTime": "2020-08-06T15:32:04.000Z",
  "locationBrandId": "23cdda27-2f82-46e4-a366-deecd5d420d0",
  "customerId": "998a26bd-04a0-11ea-8884-0242ac110002",
  "code": "S002",
  "pickupType": "takeAway",
  "schedulingTime": "2020-08-02T22:30:00.000Z",
  "activationTime": "2020-08-06T15:32:04.000Z",
  "tabTables": [],
  "products": [
    {
      "id": "f3cf29da-b5c9-408f-b6e9-ba14732b0bc8",
      "catalogProductId": "7d2b8e27-e0bf-4732-8044-223943b7fd05",
      "organizationProductId": "3cbeaeca-49f6-4dda-be87-5f7cb96d12db",
      "organizationComboId": null,
      "externalId": "0534073e-3eec-4ecc-83a4-ab446a30ca2a",
      "name": "Burger",
      "price": 1400,
      "quantity": 1,
      "course": "Main",
      "comments": null,
      "fullPrice": 1400,
      "finalPrice": 1400,
      "type": "PRODUCT",
      "promotionId": null,
      "modifiers": [
        {
          "id": "348ca8b3-28cd-4adf-a5ce-951f0158d704",
          "name": "Cheese",
          "priceImpact": 0,
          "quantity": 1,
          "catalogModifierId": "65254ec3-3ec8-4279-a5b9-118dd4391832"
        }
      ],
      "comboProducts": []
    }
  ],
  "seats": 1,
  "language": "ES",
  "waiters": [
    {
      "name": "Elon"
    }
  ],
  "bills": [
    {
      "id": "866ed6ee-f325-434b-9c8a-e5d0fc07b53f",
      "number": 859,
      "creationTime": "2020-07-31T15:48:23.000Z",
      "finalizingTime": "2020-07-31T15:48:23.000Z",
      "company": {
        "name": "LastPOS",
        "taxId": "1234",
        "address": "Maracaibo 8, Nave 2, 08041, Barcelona"
      },
      "total": 1400,
      "tax": 127,
      "taxableBase": 1273,
      "discountTotal": 0,
      "deliveryFee": 0,
      "minimumBasketSurcharge": 0,
      "terraceSurcharge": 0,
      "terraceSurchargePercentage": 0,
      "preferredPaymentMethod": "card",
      "payments": [],
      "products": [
        {
          "id": "7a740ff2-d326-42ea-a239-c9b9125d3fc3",
          "catalogProductId": "7d2b8e27-e0bf-4732-8044-223943b7fd05",
          "tabProductId": "f3cf29da-b5c9-408f-b6e9-ba14732b0bc8",
          "name": "Burger",
          "price": 1400,
          "originalPrice": 1400,
          "quantity": 1,
          "modifiers": [
            {
              "id": "be75642e-7f74-42e8-bd3d-de575caa1847",
              "name": "Cheese",
              "priceImpact": 0,
              "quantity": 1,
              "catalogModifierId": "54393d6e-5780-45da-a96f-8de45eac10cc"
            }
          ],
          "comboProducts": []
        }
      ]
    }
  ],
  "customerInfo": {
    "name": "Bruce",
    "surname": "Wayne",
    "phoneNumber": "+34666666666",
    "email": "batman@wayneindustries.com"
  },
  "delivery": {
    "address": "Gran Via de les Corts Catalanes, 620",
    "details": "First door to the left",
    "latitude": 41.3876734,
    "longitude": 2.1647098,
    "statuses": [
      {
        "creationTime": "2020-08-03T09:10:11.000Z",
        "status": "KITCHEN"
      },
      {
        "creationTime": "2020-08-05T14:06:09.000Z",
        "status": "CLOSED"
      }
    ],
    "courier": {
      "id": "be75642e-7f74-42e8-bd3d-de575caa1847",
      "name": "Jose"
    },
    "cutlery": false
  }
}

HTTP Request

GET https://api.last.app/v1/tabs/${tabId}

POST Add Bill to Tab

Allows to create a bill with all the pending products & fees pending to be paid.

HTTP Request

POST https://api.last.app/v1/tabs/${tabId}/bill

Field name Description
discount (Object) Optional discount object

Response

{
  "id": "7036ecd9-7464-4023-b7f2-f293209455bf",
  "tabId": "690d47b2-82ef-421b-88b9-686cc7bb606d",
  "creationTime": "2021-11-22T11:05:47.704Z",
  "number": 1379,
  "payments": [],
  "type": "products",
  "title": "Products",
  "products": [
    {
      "tabProductId": "be928187-e2d1-4115-a87c-be5b8fbc1f25",
      "id": "ec1deb57-aebe-46f6-994f-396d9b38e7c4",
      "name": "Arroz Natural",
      "quantity": 1,
      "price": 280,
      "originalPrice": 280,
      "discountType": null,
      "discountAmount": null,
      "discountConcept": null,
      "promotionId": null,
      "modifiers": [],
      "comboProducts": [],
      "comments": null
    },
    {
      "tabProductId": "3dff1236-ad7f-4f38-a825-4d606c96f718",
      "id": "eb0944d5-84af-4883-87d2-576bedaa838b",
      "name": "Vegetal Vegetal",
      "quantity": 1,
      "price": 690,
      "originalPrice": 690,
      "discountType": null,
      "discountAmount": null,
      "discountConcept": null,
      "promotionId": null,
      "modifiers": [],
      "comboProducts": [],
      "comments": null
    }
  ],
  "total": 1067,
  "tax": 97,
  "taxPercentage": 10,
  "taxableBase": 970,
  "taxLabel": "IVA",
  "discountPreTax": 0,
  "subTotal": 970,
  "originalTotal": 970,
  "discountTotal": 0,
  "deliveryFee": 0,
  "minimumBasketSurcharge": 0,
  "terraceSurcharge": 97,
  "terraceSurchargePercentage": 10,
  "company": {},
  "diners": 2,
  "customerCompany": null,
  "allergyInfo": null,
  "customerNote": null,
  "kitchenNote": null,
  "tableName": "A1",
  "source": "Restaurant",
  "virtualBrandId": "23cdda27-2f82-46e4-a366-deecd5d420d0",
  "code": "R004",
  "note": null,
  "pickupType": null,
  "schedulingTime": null,
  "activationTime": "2021-11-22T11:05:31.000Z",
  "locationBrandId": "23cdda27-2f82-46e4-a366-deecd5d420d0"

POST Bill Payment

Adds a payment to an existing bill from an open tab. It is possible for a bill to have multiple partial payments. Once all the tab bills are paid fully, the tab will be closed automatically. If the sum of all the payments is greater than the bill total, the difference will be considered as tip for that bill.

{
  "amount": 2500,
  "tip": 10,
  "method": "card",
  "externalId": "1111-8888-5555-4444-7777"
}

HTTP Request

POST https://api.last.app/v1/bills/${billId}/payment

Response

{
  "id": "1111111-2222-3333-4444-555555555",
  "closed": true
}

Response

Field name Description
id (String) Unique identifier of the payment in Last
closed (Boolean) Whether the tab was automatically closed after submitting the payment

Tab Payment object

Field name Description
amount (Integer) Amount of the payment
tip (Integer) Amount of the payment paid as tip
method (String) Method used for the payment
externalId (String) Optional unique identifier of the payment

DELETE Bill Payment

Deletes a payment from an existing bill.

HTTP Request

DELETE https://api.last.app/v1/bills/${billId}/payments/${paymentId}

POST Create Order

{
  "brandId": "f2779a96-578f-4649-89f6-a0972183efea",
  "products": [
    {
      "type": "PRODUCT",
      "id": "86eda7fe-e59f-4ca3-89a8-3a179ee8e0f2",
      "name": "Burger",
      "quantity": 2,
      "price": 1000,
      "modifiers": [
        {
          "priceImpact": 300,
          "id": "63ac4b67-c39b-42bb-8d44-36e57e586152",
          "name": "Extra meat",
          "quantity": 2
        },
        {
          "priceImpact": 0,
          "id": "cf7805aa-4fb9-4a97-b975-924b48898a97",
          "name": "Water (33 cl)",
          "quantity": 1
        }
      ]
    },
    {
      "type": "PRODUCT",
      "externalId": "07fc40ab-0e6b-4cb7-ac6b-3442c7c77ade",
      "name": "Ice cream",
      "quantity": 1,
      "price": 480,
      "modifiers": [
        {
          "quantity": 1,
          "name": "Vanilla flavour",
          "priceImpact": 0,
          "id": "614338bc-b017-4cc4-9528-375a5d42d0ea"
        },
        {
          "priceImpact": 0,
          "id": "e127cc65-5281-4433-8389-1ed8286f7074",
          "name": "Small size",
          "quantity": 1
        }
      ]
    },
    {
      "type": "COMBO",
      "name": "Combo",
      "price": 480,
      "id": "348951a7-dea5-409e-a365-21f51045da67",
      "quantity": 1,
      "products": [
        {
          "id": "4b5dd754-e4b2-478c-9bf7-df1f476d0763",
          "quantity": 1,
          "name": "Combo option",
          "priceImpact": 0
        }
      ]
    }
  ],
  "id": "ba115841-275e-4cf3-a07b-755fae8299b5",
  "notes": "I am allergic to tomato",
  "code": "B1234567",
  "operationalCode": "B123",
  "pickupTime": "2019-09-10T13:17:00.000Z",
  "preferredPaymentMethod": "cash",
  "customer": {
    "name": "Bruce",
    "surname": "Wayne",
    "phoneNumber": "+34666666666",
    "email": "hello@test.com"
  },
  "company": {
    "name": "Monsters, Inc",
    "address": "Gran Via de les Corts Catalanes, 620",
    "taxId": "B66249567"
  },
  "schedulingTime": "2019-09-10T13:17:00.000Z",
  "delivery": {
    "address": "Gran Via de les Corts Catalanes, 620",
    "details": "First door to the left",
    "latitude": 41.3876734,
    "longitude": 2.1647098,
    "fee": 190
  },
  "payments": [
    {
      "method": "card",
      "paidAmount": 7000
    }
  ]
}

HTTP Request

POST https://api.last.app/v1/orders

Order

Field name Description
brandId (String) Unique identifier for a location brand.
externalId (String) Identifier of the order on your system
code (String) Code shown to the user in your system
operationalCode (String) Operational code you want us to show on the ticket. Max 4 chars.
pickupTime (DateTime) Estimated pickupTime time in ISO 8601
customer (Object) Object containing name, phone number(with prefix)
delivery (Object) Object details of the delivery. If it is present, the order is considered as a delivery. Otherwise the order is a take away.
products (Array) Array containing the products
tableId (String) Id of the table to link with this order. Ignored in case of delivery
discount (Object) Optional discount object
schedulingTime (DateTime) Time selected by the user as the scheduled time in ISO 8601
payments (Array) Optional payment object containing method and paid amount.
company (Object) Optional company details for invoicing.
notes (String) Optional order notes or comments.
preferredPaymentMethod (String) Optional In case of not having any payments, you can set the preferred payment method of the customer for delivery orders
withoutBills (Boolean) Optional Flag to not generate a bill for this order yet

Product

Field name Description
id (String) Unique identifier of the product in Last
name (String) Name of the product
quantity (Integer) Quantity of the product
course (String) Course of the product
price (Integer) Price per unit of the product (without modifiers included). Represented as an integer in the smallest denomination of the currency
comments (String) comments of the product
type (String) Type of the product. Must be PRODUCT or COMBO.
modifiers (Array) Array containing the modifiers of the product. Only if product type is PRODUCT.
products (Array) Array containing the combo products of the combo. Only if product type is COMBO.
discount (Object) Optional discount object

Modifier

Field name Description
id (String) Unique identifier of the modifier in Last
quantity (Integer) Quantity of the modifier
name (String) Name of the modifier
priceImpact (Integer) Price per unit of the modifier. Represented as an integer in the smallest denomination of the currency

Delivery

Field name Description
address (String) Delivery address of the order
details (String) Details of the delivery, such as floor, stairs, etc
latitude (Float) Latitude
longitude (Float) Longitude
fee (Integer) Delivery fee in cents
comments (String) Delivery related comments
external (Boolean) Optional flag to mark order as external
cutlery (Boolean) Optional flag to ask for cutlery

Payment

Field name Description
method (String) Payment method of the order.
amount (Integer) Amount that's already paid. If it's more than the total we consider there is a tip.

Company

Field name Description
name (String) Company name.
address (String) Company address.
taxId (String) Company tax ID.

Discount

Field name Description
promotionId (String) Unique identifier of the promotion.
type (String) Type of the promotion. 'percentage' or 'currency'
amount (Integer) Amount to be discounted by the promotion, can be a percentage or currency amount depending on the type
concept (String) Description of the discount

Response

{ "id": "67f0c646-47da-4684-b70e-1d369e6a566e", "code": "D001" }

Response

Field name Description
id (String) Unique identifier of the order in Last
code (String) Short code assigned to the order

POST Add Products to Tab

{
  "products": [
    {
      "type": "PRODUCT",
      "id": "86eda7fe-e59f-4ca3-89a8-3a179ee8e0f2",
      "name": "Burger",
      "quantity": 2,
      "course": "Starters",
      "price": 1000,
      "modifiers": [
        {
          "priceImpact": 300,
          "id": "63ac4b67-c39b-42bb-8d44-36e57e586152",
          "name": "Extra meat",
          "quantity": 2
        },
        {
          "priceImpact": 0,
          "id": "cf7805aa-4fb9-4a97-b975-924b48898a97",
          "name": "Water (33 cl)",
          "quantity": 1
        }
      ]
    },
    {
      "type": "PRODUCT",
      "externalId": "07fc40ab-0e6b-4cb7-ac6b-3442c7c77ade",
      "name": "Ice cream",
      "course": "Desserts",
      "quantity": 1,
      "price": 480,
      "modifiers": [
        {
          "quantity": 1,
          "name": "Vanilla flavour",
          "priceImpact": 0,
          "id": "614338bc-b017-4cc4-9528-375a5d42d0ea"
        },
        {
          "priceImpact": 0,
          "id": "e127cc65-5281-4433-8389-1ed8286f7074",
          "name": "Small size",
          "quantity": 1
        }
      ]
    },
    {
      "type": "COMBO",
      "name": "Combo",
      "price": 480,
      "course": "Main",
      "id": "348951a7-dea5-409e-a365-21f51045da67",
      "quantity": 1,
      "products": [
        {
          "id": "4b5dd754-e4b2-478c-9bf7-df1f476d0763",
          "quantity": 1,
          "name": "Combo option",
          "priceImpact": 0
        }
      ]
    }
  ]
}

HTTP Request

POST https://api.last.app/v1/tabs/:tabId/add-products

Product

Field name Description
id (String) Unique identifier of the product in Last
name (String) Name of the product
quantity (Integer) Quantity of the product
course (String) Course of the product
price (Integer) Price per unit of the product (without modifiers included). Represented as a positive integer in the smallest denomination of the currency
comments (String) comments of the product
modifiers (Array) Array containing the modifiers of the product
discount (Object) Optional discount object

Modifier

Field name Description
id (String) Unique identifier of the modifier in Last
quantity (Integer) Quantity of the modifier
name (String) Name of the modifier
priceImpact (Integer) Price per unit of the modifier. Represented as an integer in the smallest denomination of the currency

POST Order Cancellation

{
  "cancelReason": "User cancelled manually"
}

HTTP Request

POST https://api.last.app/v1/orders/${orderId}/cancel

Order cancellation object

Field name Description
cancelReason (String) String detailing the reason for the cancellation

GET Order Status

{
  "status": "KITCHEN"
}

HTTP Request

GET https://api.last.app/v1/orders/${orderId}/status

Order status object

Field name Description
status (String) Status of the order. One of: [CREATED, KITCHEN, READY_TO_PICKUP, ON_DELIVERY, DELIVERED, CLOSED, CANCELLED]

POST Order Status

{
  "newStatus": "READY_TO_PICKUP"
}

HTTP Request

POST https://api.last.app/v1/orders/${orderId}/status

Order status object

Field name Description
newStatus (String) New status of the order. One of: [KITCHEN, READY_TO_PICKUP, ON_DELIVERY, DELIVERED, CLOSED]

GET Promotion List

{
  "promotions": [
    {
      "id": "28afe959-6204-4169-b5ba-fc90f15aad43",
      "organizationId": "90724ad8-334b-40d8-a07b-45d4b5e563d4",
      "name": "El tenedor",
      "description": "el tenedor",
      "pointsExpense": null,
      "discountType": "percentage",
      "discountAmount": 10,
      "allowRepeat": true,
      "accumulated": true,
      "categories": ["d8486f43-04c6-4d94-b683-654e053957f0"]
    },
    {
      "id": "39bfaca0-9920-4224-9762-0cbc8d61dbcf",
      "name": "2x1",
      "description": "2x1",
      "pointsExpense": null,
      "discountType": "2x1",
      "discountAmount": null,
      "allowRepeat": true,
      "accumulated": false,
      "code": "GETTWO",
      "products": [
        "00828e09-6f83-4f0e-8ea7-1dca77f465ba",
        "02379925-554e-41cf-9bb8-c5d8cc84759b"
      ]
    },
    {
      "id": "d1e90fb6-c3af-4317-84aa-05215920b6b0",
      "organizationId": "90724ad8-334b-40d8-a07b-45d4b5e563d4",
      "name": "Point products",
      "description": "Get one of this products for 10 points",
      "pointsExpense": 10,
      "discountType": "products",
      "discountAmount": null,
      "allowRepeat": false,
      "accumulated": false,
      "products": [
        "63b42746-e800-43d6-a853-d09a4a69d162",
        "6e964602-d42a-4848-b987-311772c522aa",
        "78723506-2c6f-43fe-9232-6c588fa9c42d"
      ]
    }
  ]
}

HTTP Request

GET https://api.last.app/v1/promotions

Query parameter Description
offset (Integer) Optional. The number of promotions to skip.
limit (Integer) Optional. The maximum number of promotions to be returned.

GET Promotion

{
  "id": "28afe959-6204-4169-b5ba-fc90f15aad43",
  "organizationId": "90724ad8-334b-40d8-a07b-45d4b5e563d4",
  "name": "El tenedor",
  "description": "el tenedor",
  "pointsExpense": null,
  "discountType": "percentage",
  "discountAmount": 10,
  "allowRepeat": true,
  "accumulated": true,
  "categories": ["d8486f43-04c6-4d94-b683-654e053957f0"],
  "products": ["18be645c-84e5-4172-8b51-3bd619362aa3"],
  "customerIds": ["57b5ba5c-996d-412a-a5ab-283e8e347f91"]
}

HTTP Request

GET https://api.last.app/v1/promotions/${promotionId}

Promotion

Field name Description
id (String) Unique identifier of the promotion in Last
organizationId (String) Unique identifier of the organization where the promotion applies
name (String) Name of the promotion
description (String) Description of the promotion
pointsExpense (Integer) Amount of points that are needed and will be consumed when the promotion is used
discountType (String) Type of the promotion. One of products, 2x1, percentage, currency
discountAmount (Integer) Amount to be discounted by the promotion, can be a percentage or currency amount depending on the type
enabled (Boolean) Current status of the promotion
allowRepeat (Boolean) If enabled this promotion can be applied multiple times in the same order
accumulated (Boolean) If enabled this promotion can be applied alongside other promotions
availableInShop (Boolean) Promotion can be used in Last Shop
code (String) Code that can be used by the customer in the shop to apply the promotion
maxRedemptions (Integer) Maximum number of usages of this promotion
minExpense (Integer) Minimum expense amount to use this promotion
startTime (DateTime) Start time of the promotion if it's not permanent
endTime (DateTime) End time of the promotion if it's not permanent
oncePerPerson (Boolean) If enabled this promotion can be only used once per person
internalDescription (Boolean) Internal description of the promotion
showPopup (Boolean) If enabled this promotion will show a popup when applied on LastShop
deleted (Boolean) Permanent status of the promotion
availableInPos (Boolean) Promotion can be used in Last POS
availableInAdmin (Boolean) Promotion can be seen in Last Admin
pickupType (String) Kind of orders where this promotion can be applied
freeDelivery (Boolean) If enabled this promotion specifies delivery of the order is free
products (Array) Array containing the products of the promotion where the promotion applies
categories (Array) Array containing the categories where the promotion applies

POST Create/Update Promotion

{
  "accumulated": true,
  "allowRepeat": false,
  "availableInShop": true,
  "availableInPos": true,
  "availableInAdmin": true,
  "code": "KONAMICODE",
  "description": "el tenedor desc",
  "discountAmount": 1000,
  "discountType": "currency",
  "enabled": true,
  "endTime": "2021-02-03T23:00:00.000Z",
  "id": "28afe959-6204-4169-b5ba-fc90f15aad43",
  "locations": ["f2779a96-578f-4649-89f6-a0972183efea"],
  "maxRedemptions": 3,
  "minExpense": 1290,
  "name": "El tenedor",
  "organizationId": "90724ad8-334b-40d8-a07b-45d4b5e563d4",
  "pointsExpense": 10,
  "products": ["07ec300a-31cb-42c6-9519-0bd25191d74d"],
  "startTime": "2021-01-14T23:00:00.000Z",
  "weekdays": ["monday"],
  "customerIds": ["0ae6e3fb-c340-4b26-80ed-3bbe49f54db7"]
}

HTTP Request

POST https://api.last.app/v1/promotions/create-or-update

Promotion

Field name Description
id (String) Optional. Unique identifier for a promotion. If it is not provided the promo will be created instead of updated.
locations (Array) Optional. Location IDs where the promotion will take effect.
maxRedemptions (Integer) Optional. The amount after which the promotion will expire.
minExpense (Integer) Optional. Minimum expense in cents for which the promotion will take effect
products (Array) Optional. One of products array or categories array. Product IDs in which the promotion will take effect. This IDs are the organizationProductId or the organizationComboId of the catalog products.
categories (Array) Optional. One of products array or categories array. Category IDs in which the promotion will take effect.
weekdays (Array) Optional. Weekdays when the promotion will take effect
code (String) Optional. Code to get the promotion applied
startTime (DateTime) Optional. Promotion availability starting time in ISO 8601
endTime (Datetime) Optional. Promotion availability ending time in ISO 8601
pointsExpense (Integer) Amount of points that are needed and will be consumed when the promotion is used
accumulated (Boolean) If enabled the promotion could be accumulated with others
allowRepeat (Boolean) If enabled this promotion can be applied multiple times in the same order
availableInShop (Boolean) If enabled this promotion can be applied in LastShop
availableInPos (Boolean) If enabled this promotion can be applied in LastPOS
availableInAdmin (Boolean) If enabled this promotion will be shown in LastAdmin
name (String) Name of the promotion
description (String) Description of the promotion
discountType (String) Type of the promotion. One of: ['percentage', 'currency']
discountAmount (Integer) Amount to be discounted by the promotion, can be a percentage or currency amount in cents depending on the type
enabled (Boolean) Availability of the promotion
customerIds (Array) Array of customer identifiers which will be eligible to use the promotion

GET Customer

Response

{
  "name": "Bruce",
  "surname": "Wayne",
  "phoneNumber": "+34666666666",
  "creationTime": "2020-07-31T15:48:22.000Z",
  "email": "hello@test.com",
  "source": "Shop",
  "marketingCommunication": true,
  "internalNote": "General purpose field",
  "hasUser": true,
  "points": 30,
  "addresses": [
    {
      "address": "Gran Via de les Corts Catalanes, 620",
      "details": "First door to the left",
      "postalCode": "08007",
      "latitude": 41.3876734,
      "longitude": 2.1647098
    }
  ]
}

HTTP Request

GET https://api.last.app/v1/customers/${customerId}

Query parameter Description
customerId (String) Unique identifier of the customer in Last

GET Customer list

Response

{
  "customers": [
    { /* customer object */ },
    { /* customer object */ },
    ...
  ],
  "page": 0,
  "lastPage": 0
}

HTTP Request

GET https://api.last.app/v1/customers

Query parameter Description
page (Integer) Result page to show
phoneNumber (String) Full phone number with country code

* This request is paginated in groups of 100

POST Create Customer

HTTP Request

POST https://api.last.app/v1/customers

Customer Object

Field name Description
name (String) Name of the customer
surname (String) Surname of the customer
creationTime (String) Creation time (in ISO 8601).
phoneNumber (String) Full phone number with country code
internalNote (String) Internal note
source (String) Source of the customer
email (String) Email

Request

{
  "name": "Bruce",
  "surname": "Wayne",
  "phoneNumber": "+34666666666",
  "internalNote": "This is a note",
  "email": "hello@test.com",
  "source": "MyWebsite",
  "marketingCommunication": true
}

Response

{
  "id": "4b292bf3-97e8-4f02-bb6e-d8c4247ab4c5",
  "name": "Bruce",
  "surname": "Wayne",
  "phoneNumber": "+34666666666",
  "internalNote": "This is a note",
  "email": "hello@test.com",
  "source": "MyWebsite",
  "marketingCommunication": true
}

POST Update Customer

There's no need to include all fields, just those that have changed.

HTTP Request

POST https://api.last.app/v1/customers/${customerId}

Query parameter Description
customerId (String) Unique identifier of the customer in Last

Request

{
  "name": "Matt"
}

Response

{
  "id": "4b292bf3-97e8-4f02-bb6e-d8c4247ab4c5",
  "name": "Matt",
  "surname": "Wayne",
  "phoneNumber": "+34666666666",
  "internalNote": "This is a note",
  "email": "hello@test.com",
  "points": 36,
  "marketingCommunication": true
}

PUT Add Points to Customer

HTTP Request

PUT https://api.last.app/v1/customers/${customerId}/add-points

Request

{
  "addedPoints": 10
}

POST Create reservation

HTTP Request

POST https://api.last.app/v1/reservations

Reservation

Field name Description
name (String) Name of the diner.
locationId (String) Location which receives the reservation.
diners (Integer) Number of the diners of the reservation.
phoneNumber (String) Full phone number with country code
source (String) Name of the integrated platform sending the reservation.
dateTime (DateTime) Date and time of the reservation in ISO 8601.
surname (String) OPTIONAL Surname of the diner.
customerComments (String) OPTIONAL Message of the reservation to be showed to the restaurant.
externalId (String) OPTIONAL ID of the reservation on the integrated platform.

Request

{
  "name": "Juanito",
  "surname": "Jones",
  "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
  "externalId": null,
  "phoneNumber": "+34666111444",
  "diners": 2,
  "customerComments": null,
  "source": "ReservationPlatform",
  "dateTime": "2024-02-05T14:00:00.000Z"
}

PUT Update reservation

HTTP Request

PUT https://api.last.app/v1/reservations/${reservationId}

Request

{
  "name": "Juanito",
  "surname": "Jones",
  "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
  "externalId": null,
  "phoneNumber": "+34666111444",
  "diners": 2,
  "customerComments": null,
  "source": "ReservationPlatform",
  "dateTime": "2024-02-05T14:00:00.000Z"
}

DELETE Cancel reservation

HTTP Request

DELETE https://api.last.app/v1/reservations/${reservationId}

Webhooks

Whenever there is a content change in our side that may be relevant for an integration we trigger webhook updates.

The request will be made via POST to your chosen webhook enpoint, which on success should return an empty response with status 200.

The update will come in json format in the body of the request, wrapped in an event object, with a corresponding payload (data) with the relevant resource or information.

Field name Description
id (String) Unique identifier of the event
type (String) Type of event
created (DateTime) The time the event was created at (ISO-8601 UTC)
data (Object) The data associated with the particular event

Customer

{
  "id": "33f9dc36-5e99-4044-8e2e-9b22c403c5f7",
  "type": "customer:created",
  "created": "2020-10-06T18:32:04.000Z",
  "data": {
    "id": "072c8bc3-4601-47d1-8a11-26935d57222f",
    "name": "Bruce",
    "surname": "Wayne",
    "phoneNumber": "+34666666666",
    "email": "hello@test.com",
    "source": "Shop",
    "marketingCommunication": true,
    "hasUser": true,
    "addresses": [
      {
        "address": "Gran Via de les Corts Catalanes, 620",
        "details": "First door to the left",
        "postalCode": "08007",
        "latitude": 41.3876734,
        "longitude": 2.1647098
      }
    ]
  }
}

Types

Points

{
  "id": "33f9dc36-5e99-4044-8e2e-9b22c403c5f7",
  "type": "customer_points:updated",
  "created": "2020-10-06T18:32:04.000Z",
  "data": {
    "customerId": "072c8bc3-4601-47d1-8a11-26935d57222f",
    "tabId": "1b0e7a24-ad88-4825-93e4-18dc7865db07",
    "amount": 200,
    "totalEarned": 200
  }
}

Types

Promotions

We'll sent this webhook when a promotion is created, updated or deleted.

{
  "id": "28afe959-6204-4169-b5ba-fc90f15aad43",
  "organizationId": "90724ad8-334b-40d8-a07b-45d4b5e563d4",
  "name": "El tenedor",
  "description": "el tenedor",
  "pointsExpense": null,
  "discountType": "percentage",
  "discountAmount": 10,
  "enabled": true,
  "allowRepeat": true,
  "accumulated": true,
  "availableInShop": true,
  "code": "10TENEDOR",
  "maxRedemptions": null,
  "minExpense": 200,
  "startTime": null,
  "endTime": null,
  "oncePerPerson": true,
  "internalDescription": "",
  "showPopup": true,
  "availableInPos": false,
  "availableInAdmin": true,
  "freeDelivery": false,
  "categories": ["d8486f43-04c6-4d94-b683-654e053957f0"],
  "products": ["18be645c-84e5-4172-8b51-3bd619362aa3"],
  "customerIds": ["57b5ba5c-996d-412a-a5ab-283e8e347f91"],
  "deleted": false
}

Types

Tab

{
  "id": "bbcfabf5-d660-4c21-9751-4e8f197439e2",
  "name": null,
  "creationTime": "2020-07-31T15:48:22.000Z",
  "locationId": "f2779a96-578f-4649-89f6-a0972183efea",
  "source": "Shop",
  "allergyInfo": null,
  "customerNote": null,
  "kitchenNote": null,
  "tableName": null,
  "closeTime": "2020-08-06T15:32:04.000Z",
  "locationBrandId": "23cdda27-2f82-46e4-a366-deecd5d420d0",
  "customerId": "998a26bd-04a0-11ea-8884-0242ac110002",
  "code": "S002",
  "pickupType": "takeAway",
  "schedulingTime": "2020-08-02T22:30:00.000Z",
  "activationTime": "2020-08-06T15:32:04.000Z",
  "tabTables": [],
  "products": [
    {
      "id": "f3cf29da-b5c9-408f-b6e9-ba14732b0bc8",
      "catalogProductId": "7d2b8e27-e0bf-4732-8044-223943b7fd05",
      "organizationProductId": "3cbeaeca-49f6-4dda-be87-5f7cb96d12db",
      "organizationComboId": null,
      "externalId": "0534073e-3eec-4ecc-83a4-ab446a30ca2a",
      "name": "Burger",
      "price": 1400,
      "quantity": 1,
      "course": "Main",
      "comments": null,
      "fullPrice": 1400,
      "finalPrice": 1400,
      "type": "PRODUCT",
      "promotionId": null,
      "modifiers": [
        {
          "id": "348ca8b3-28cd-4adf-a5ce-951f0158d704",
          "name": "Cheese",
          "priceImpact": 0,
          "quantity": 1,
          "catalogModifierId": "65254ec3-3ec8-4279-a5b9-118dd4391832"
        }
      ],
      "comboProducts": []
    }
  ],
  "seats": 1,
  "language": "ES",
  "bills": [
    {
      "id": "866ed6ee-f325-434b-9c8a-e5d0fc07b53f",
      "number": 859,
      "rectifiedBillNumber": 934,
      "creationTime": "2020-07-31T15:48:23.000Z",
      "finalizingTime": "2020-07-31T15:48:23.000Z",
      "company": {
        "name": "LastPOS",
        "taxId": "1234",
        "address": "Maracaibo 8, Nave 2, 08041, Barcelona"
      },
      "total": 1400,
      "tax": 127,
      "taxableBase": 1273,
      "discountTotal": 0,
      "deliveryFee": 0,
      "minimumBasketSurcharge": 0,
      "terraceSurcharge": 0,
      "terraceSurchargePercentage": 0,
      "preferredPaymentMethod": "card",
      "payments": [],
      "products": [
        {
          "id": "7a740ff2-d326-42ea-a239-c9b9125d3fc3",
          "catalogProductId": "7d2b8e27-e0bf-4732-8044-223943b7fd05",
          "tabProductId": "f3cf29da-b5c9-408f-b6e9-ba14732b0bc8",
          "name": "Burger",
          "price": 1400,
          "quantity": 1,
          "modifiers": [
            {
              "id": "be75642e-7f74-42e8-bd3d-de575caa1847",
              "name": "Cheese",
              "priceImpact": 0,
              "quantity": 1,
              "catalogModifierId": "54393d6e-5780-45da-a96f-8de45eac10cc"
            }
          ],
          "comboProducts": []
        }
      ]
    }
  ],
  "delivery": {
    "address": "Gran Via de les Corts Catalanes, 620",
    "details": "First door to the left",
    "latitude": 41.3876734,
    "longitude": 2.1647098,
    "statuses": [
      {
        "creationTime": "2020-08-03T09:10:11.000Z",
        "status": "KITCHEN"
      },
      {
        "creationTime": "2020-08-05T14:06:09.000Z",
        "status": "CLOSED"
      }
    ],
    "courier": {
      "id": "be75642e-7f74-42e8-bd3d-de575caa1847",
      "name": "Jose"
    },
    "cutlery": false
  }
}

Types

Tab Status

Field name Description
tabId (string) Id of the tab
externalId (string) Id of the tab in the system that created it
status (String) Status of the order. One of: [CREATED, KITCHEN, READY_TO_PICKUP, ON_DELIVERY, DELIVERED, CLOSED]
{
  "id": "33f9dc36-5e99-4044-8e2e-9b22c403c5f7",
  "type": "tab:delivery-status-updated",
  "created": "2020-10-06T18:32:04.000Z",
  "data": {
    "tabId": "1f153b1f-e0ba-4cae-a2f0-ce96496b7cac",
    "externalId": "some-id",
    "status": "READY_TO_PICKUP"
  }
}

Types

Catalog

Field name Description
catalogIds (Array) Array containing the ids of the updated catalogs.
locationId (String) Optional. If present, indicates that the catalog updates only affects that location.
{
  "id": "33f9dc36-5e99-4044-8e2e-9b22c403c5f7",
  "type": "catalog:updated",
  "created": "2020-10-06T18:32:04.000Z",
  "data": {
    "catalogIds": [
      "ccb436b2-039e-47b3-bf59-3269e56f3567",
      "2f8fb8b8-b961-402e-8c59-81afb4ef8b9a"
    ],
    "locationId": "bdd59445-db01-438b-bdd5-f9f21c9e489b"
  }
}

Types

Shipment

{
  "id": "33f9dc36-5e99-4044-8e2e-9b22c403c5f7",
  "type": "shipment:sent",
  "created": "2020-10-06T18:32:04.000Z",
  "data": {
    "shipmentId": "2f8fb8b8-b961-402e-8c59-81afb4ef8b9a",
    "pickupTime": "2020-10-06T18:32:04.000Z",
    "pickup": {
      "address": "Gran Via de les Corts Catalanes, 620",
      "contact": {
        "phone": "+34666111222",
        "firstname": "MacDonalds Gran Via"
      }
    },
    "dropoffs": [
      {
        "address": "Calle rey agapito, 17",
        "addressDetails": "Piso 3r1a",
        "latitude": 41.3876734,
        "longitude": 2.1647098,
        "code": "R067",
        "tabId": "324e07ed-d557-47bc-8ccd-0f1d3fe0fb67",
        "source": "Restaurant",
        "schedulingTime": "2020-10-06T19:32:04.000Z",
        "comment": "Porfavor, picar al timbre al llegar",
        "contact": {
          "firstname": "Juan",
          "phone": "+34666777888",
          "email": "test@test.com",
          "phoneNumberCode": "833 16 243"
        },
        "preferredPaymentMethod": "cash"
      }
    ]
  }
}
Field name Description
shipmentId (String) Unique identifier of the shipment
pickupTime (DateTime) Estimated pickupTime time in ISO 8601.
pickup (Object) Contains pickup details.
dropoffs (Array) Array of delivery points.

Pickup

Field name Description
address (String) Address of the location.
contact (Object) Contains pickup contact details.

Dropoff

Field name Description
address (String) Delivery address.
addressDetails (String) Delivery address details.
code (Array) Delivery order code.
tabId (String) Delivery order tab id.
source (String) Delivery order source.
comments (String) Delivery order comments and instructions.
contact (Object) Contains delivery contact info.
preferredPaymentMethod (String) Preferred payment method.

Types

Kitchen Order

Field name Description
id (String) Unique identifier of the kitchen order.
locationId (String) Identifier of the location owner of kitchen order.
creationTime (String) Creation time (in ISO 8601).
versions (Array) List of kitchen order versions with the products.
tabId (String) Tab id associated to the Kitchen order.
allergyInfo (String) Optional allergy information of the diner.
code (String) Order code.
pickupTime (String) Order Pickup time (in ISO 8601).
waiterName (String) Optional name of the waiter.
note (String) Optional order note.
printerId (String) Identifier of the printer for this kitchen order.
{
  "id": "5ea5aefd-23b1-45ec-8250-6504817fc351",
  "type": "kitchen-order:created",
  "creationTime": "2023-02-13T08:45:08.310Z",
  "locationId": "f109347c-3cf4-40c4-8a7d-e8d095192667",
  "versions": [
    {
      "id": "2618114d-4fa0-41d2-8d3a-df794937e0ef",
      "sentTime": "2023-02-13T08:45:08.310Z",
      "products": [
        {
          "id": "6fd9af6b-6ed3-4aee-a067-1127da4d186a",
          "name": "Test Product 2",
          "comments": "",
          "quantity": 1,
          "modifiers": [
            {
              "id": "e93ad05e-f4fb-494b-a6dd-7d2d0fbb50b0",
              "name": "Spicy Mayo",
              "quantity": 1
            }
          ]
        },
        {
          "id": "bc73d17b-ed9e-4814-9d67-b3fbf07cf569",
          "name": "Gofre premium",
          "comments": "",
          "quantity": 1,
          "modifiers": [
            {
              "id": "76abb12f-8c3d-4958-9659-78de71375089",
              "name": "Topping plátano canario",
              "quantity": 1
            },
            {
              "id": "2293f6f8-846b-43e0-b7f3-11928a91621e",
              "name": "Topping salmón flambeado",
              "quantity": 1
            }
          ]
        }
      ]
    }
  ],
  "tabId": "f109347c-3cf4-40c4-8a7d-e8d095192661",
  "allergyInfo": null,
  "code": "S032",
  "pickupTime": "2023-02-13T09:35:08.122Z",
  "waiterName": null,
  "note": null,
  "printerId": "f109347c-3cf4-40c4-8a7d-e8d095192259",
}

Types

Kitchen Note

We'll sent this webhook when a waiter ask for a course of some kitchen orders.

Field name Description
course (String) Course to be asked to serve (p.e: starters).
locationId (String) Identifier of location owner of kitchen orders.
kitchenOrderIds (Array) List of kitchenOrder IDs.
{
  "type": "kitchen_note:created",
  "course": "desserts",
  "locationId": "f109347c-3cf4-40c4-8a7d-e8d095192667",
  "kitchenOrderIds": [
    "2618114d-4fa0-41d2-8d3a-df794937e0ef",
    "6fd9af6b-6ed3-4aee-a067-1127da4d186a",
    "e93ad05e-f4fb-494b-a6dd-7d2d0fbb50b0"
  ]     
}

Types

Floorplan

Field name Description
id (String) Unique identifier of the floorplan.
name (String) Name of the floorplan.
tables (Array) List of tables of the floorplan products.
{
  "id": "d482a7b0-377e-4a56-8c43-7d847738f044",
  "type": "floorplan:updated",
  "name": "Main",
  "tables": [
    {
      "id": "03d96ebb-b36c-43b1-874a-24eecec1abc2",
      "name": "A1",
      "seats": 2
    },
    {
      "id": "398bcf26-141f-42c5-80a2-391270d7f92a",
      "name": "B2",
      "seats": 2
    },
    {
      "id": "11b005ee-d7e3-4aea-b545-9d1d659b0396",
      "name": "Barra",
      "seats": 4
    }
  ]
},
{
  "id": "75b87c37-6ca2-4815-9e07-3f05b0185a66",
  "name": "Outside",
  "tables": [
    {
      "id": "cb38cb1c-9052-4637-a499-50d4fd8fc86c",
      "name": "T2",
      "seats": 2
    }
  ]
}

Types

Reservations

Field name Description
id (String) Unique identifier of the floorplan.
name (String) Name of the floorplan.
tables (Array) List of tables of the floorplan products.
{
  "id": "54e9f57d-1aea-418e-b2d2-70a89f997143",
  "type": "reservation:created",
  "created": "2024-02-05T10:25:39.581Z",
  "data": {
    "id": "32c477b5-b5c1-460a-9c57-c2440796d6e5",
    "externalId": null,
    "name": "Juanito",
    "surname": "Jones",
    "phoneNumber": "+34666111444",
    "diners": 2,
    "customerComments": null,
    "source": "ReservationPlatform",
    "dateTime": "2024-02-05T14:00:00.000Z",
    "cancelled": false,
    "locationId": "f2779a96-578f-4649-89f6-a0972183efea"
  }
}

Types

FAQ

How can I get a testing account and a testing auth token?

At the moment, you'll need to send an email to our support team at hola@last.app.

We're currently working on adding the possibility to obtain testing credentials directly through API.

Once I have finished the integration with a testing account, how can I obtain the restaurants production token?

The restaurant manager should send an email to our support team at hola@last.app asking for the token. If you are a third party, you can also ask for the token, only if you have the permission from the restaurant.

How can I get the ID of each location?

You can get all the locations related info making a request to GET Location List.

Which is the difference between Location and brand?

In our system, a Location is a Restaurant, in simple words. Each location maybe want to appear with different brands in their online sales channels. For example, a location named as Rick Restaurant can have multiple brands appearing at JustEat and UberEats, for example Rick Chickens, Rick Pizza, and Rick Sushi.

Which catalogs is my location using currently?

In the response from GET Location List you will find a list of brands for each location, and each of this brands contains at the same time a list of catalogs.

How can I add a webhook URL or suscribe to a webhook event?

At the moment, you'll need to send an email to our support team at hola@last.app.

We're currently working on adding the possibility to handle webhook management directly through API.

It is posible to update products pricing or catalogs through API?

This is not possible at the moment, currently you need to access Last.app admin panel to do this.

How many tokens I need for all my integrated restaurants?

You'll need one token for each Organization that you are managing. In our system, an Organization is a set of locations from the same franchise. For example, if you are managing three restaurants from the same franchise, you only need one token.

Which is the difference between tab, order, and bill?

In fact, there is no differente between a tab and an order. For internal requirements, we name a restaurant customer request as tab, but for the API, we preferred to name it as order, as it is more industry standard.

A bill is an invoice, and it belongs to a tab. It contains payments and invoice details.

I have an API question, who can I ask about it?

You can send an email to integrations@last.app, where we will be pleased to help you as mush as we can.