lobby-gateway API

Overview

The lobby-gateway provides endpoints for lobby systems (digital shelves) to communicate with the Xpand Cloud. This API enables lobby systems to:

  • Synchronize product catalog data incrementally
  • Get updated stock level of products
  • Submit new orders from customer interactions
  • Implement payment and age verification flows

Initialization

Initialization of the Digital Shelf communication with the cloud

Digital Shelf handshake

Initial handshake endpoint for Digital Shelves to start their workflow with the cloud. A successful handshake requires the Digital Shelf's serial number to be known by the cloud. Otherwise the handshake fails and the digital shelf won't be able to make any API calls to the lobby-gateway.

A successful handshake effectively exchanges the Digital Shelf's serial number with a cloud digitalShelfId and siteId. All other API calls require this digitalShelfId.

The Digital Shelf should continue attempting the handshake using some reasonable retry interval until successful if the handshake call fails. During this phase it should display some appropriate message to the user (e.g. "Initializing" or "Init error" etc).

Request Body schema: application/json
required
serialNumber
required
string

Digital Shelf serial number

Responses

Request samples

Content type
application/json
{
  • "serialNumber": "a12d1913af81434f"
}

Response samples

Content type
application/json
{
  • "digitalShelfId": 83,
  • "siteId": 1
}

Products

Synchronize product catalog

Get product updates

Retrieve product updates for incremental synchronization.

This is an incremental sync endpoint based on "index" - an atomic increasing only integer that is updated for each create or update operation.

The client should maintain the last currentIndex number it consumed successfully, and use it for the next API call. The server would then filter out and return only records with a higher index number, meaning those that were created or modified since the last call.

The lobby-gateway should return products in all states. The reason for this is that even though some states mean for the Digital Shelf not to display the product, if products in this state are omitted from the response, the Digital Shelf won't be able to detect a product that enters one of these states.

The siteId path parameter is necessary for determining site-dependant properties such as price, ageLimit, etc.

path Parameters
siteId
required
integer
Example: 1

Site ID to get products for

query Parameters
fromIndex
integer >= 0
Default: 0

Get products starting from this index. Use 0 or omit for initial sync. After the initial sync the currentIndex property returned by the server in each call should be used.

Responses

Response samples

Content type
application/json
{
  • "currentIndex": 0,
  • "products": [
    • {
      • "id": 361,
      • "name": {
        • "en_US": "Nature Valley Crunchy",
        • "de_DE": "Nature Valley Knusprig"
        },
      • "description": {
        • "en_US": "Crunchy granola bars made with whole grain oats, peanuts, and honey",
        • "de_DE": "Knusprige Müsliriegel aus Vollkornhafer, Erdnüssen und Honig"
        },
      • "brand": {
        • "en_US": "Nature Valley",
        • "de_DE": "Nature Valley"
        },
      • "type": "regular",
      • "status": "pending",
      • "categoryId": 37,
      • "labelIds": [
        • 45,
        • 58
        ],
      • "images": [],
      • "identifiers": [
        • {
          • "type": "SKU",
          • "value": "NV-CRUNCHY-6PK"
          },
        • {
          • "type": "EAN",
          • "value": "016000275775"
          }
        ],
      • "price": 5.37,
      • "priceSublines": [
        • {
          • "description": {
            • "en_US": "Inc %10 Tax",
            • "de_DE": "inkl. 10 % Steuern"
            },
          • "amount": 0.53
          },
        • {
          • "description": {
            • "en_US": "Deposit",
            • "de_DE": "Pfand"
            },
          • "amount": 0.3
          }
        ],
      • "modifiers": [
        • {
          • "key": "strength",
          • "name": {
            • "en_US": "Coffee Strength",
            • "de_DE": "Kaffee Stärke"
            },
          • "values": [
            • {
              • "value": "regular",
              • "name": {
                • "en_US": "Regular",
                • "de_DE": "Normal"
                }
              },
            • {
              • "value": "strong",
              • "name": {
                • "en_US": "Strong",
                • "de_DE": "Stark"
                }
              }
            ]
          },
        • {
          • "key": "milk",
          • "name": {
            • "en_US": "Milk Option",
            • "de_DE": "Milch Option"
            },
          • "values": [
            • {
              • "value": "with_milk",
              • "name": {
                • "en_US": "With milk",
                • "de_DE": "Mit Milch"
                }
              },
            • {
              • "value": "no_milk",
              • "name": {
                • "en_US": "No milk",
                • "de_DE": "Ohne Milch"
                }
              }
            ]
          }
        ],
      • "recommendedProductIds": [
        • 123,
        • 456,
        • 789
        ],
      • "imageSize": 3,
      • "netContents": {
        • "value": 500,
        • "unit": "ml"
        },
      • "ageLimit": 21
      }
    ]
}

Get categories

Retrieve all product categories for display organization.

Returns a flat list of all categories with hierarchical relationships indicated by the parentId field.

Responses

Response samples

Content type
application/json
[]

Get labels

Retrieve all product labels for filtering and display purposes.

Responses

Response samples

Content type
application/json
[
  • {
    • "id": 27,
    • "name": {
      • "en_US": "Organic",
      • "de_DE": "Bio"
      }
    },
  • {
    • "id": 32,
    • "name": {
      • "en_US": "Gluten Free",
      • "de_DE": "Glutenfrei"
      }
    }
]

Stock

Synchronize stock data

Get stock level

Retrieve stock level for all products with incremental synchronization support.

This is an incremental sync endpoint based on "index" - an atomic increasing only integer that is updated for each stock level change.

The client should maintain the last currentIndex number it consumed successfully, and use it for the next API call. The server would then filter out and return only records with a higher index number, meaning those that were created or updated since the last call.

path Parameters
siteId
integer

Site ID in which the digital shelf is placed (obtained during handshake call)

query Parameters
fromIndex
integer >= 0
Default: 0

Get stock updates starting from this index. Use 0 or omit for initial sync. After the initial sync the currentIndex property returned by the server in each call should be used.

Responses

Response samples

Content type
application/json
{
  • "currentIndex": 1083,
  • "stock": [
    • {
      • "productId": 27,
      • "quantity": 3
      },
    • {
      • "productId": 45,
      • "quantity": 12
      }
    ]
}

Create a stock reservation

Reserve stock for products that the user wants to order. This ensures availability before proceeding with order review and payment.

Request Body schema: application/json
required
digitalShelfId
required
integer

ID of the digital shelf making the reservation

required
Array of objects (LobbyOrderProductsList)

The products the user intends to order (in the cart)

Responses

Request samples

Content type
application/json
{
  • "digitalShelfId": 83,
  • "products": [
    • {
      • "productId": 287,
      • "quantity": 2,
      • "modifiers": {
        • "strength": "strong",
        • "milk": "with_milk"
        }
      }
    ]
}

Response samples

Content type
application/json
{
  • "reservationId": 18736,
  • "expiresAt": "2023-11-22T17:00:00Z"
}

Delete a stock reservation

Deletes a stock reservation previous acquired through the POST /stock/reservations API.

This endpoint should be used by the digital shelf in case a user enters the "review order" stage of the flow, but does not go through with placing the order.

While the reservation will eventually expire anyway, by letting it expire on its own rather than explicitly deleting it, it leaves a time window in which the stock is reserved needlessly and potentially preventing other users from ordering desired products if stock is low.

Responses

Response samples

Content type
application/json
{
  • "error": "string",
  • "message": {
    • "en_US": "Payment failed",
    • "de_DE": "Zahlung fehlgeschlagen"
    },
  • "details": { }
}

Age Verification

Age Verification flow

Start age verification

Start age verification process for orders containing age-restricted products. This maps to the age verification integrator callback.

Request Body schema: application/json
required
digitalShelfId
required
integer

ID of the digital shelf

required
Array of objects (LobbyOrderProductsList)

The products the user intends to order (in the cart)

object (LobbyOrderUser)

User information (if known)

Responses

Request samples

Content type
application/json
{
  • "digitalShelfId": 83,
  • "products": [
    • {
      • "productId": 287,
      • "quantity": 2,
      • "modifiers": {
        • "strength": "strong",
        • "milk": "with_milk"
        }
      }
    ],
  • "user": {
    • "name": "John Doe",
    • "address": "1 Street St., City",
    • "phoneNumber": "050-111-1111",
    • "locale": "en_US"
    }
}

Response samples

Content type
application/json
{
  • "ageVerificationId": 749
}

Get age verification status

Poll for age verification status by digital shelf ID.

path Parameters
ageVerificationId
required
integer
Example: 749

Age verification ID

Responses

Response samples

Content type
application/json
Example
{
  • "ageVerificationId": 749,
  • "status": "in_progress"
}

Promo Codes

Promo Codes flows

Check promo code

Check a promo code manually typed in by the user.

This is a real-time endpoint (i.e. not a human interaction flow - returns immediately with a result).

Request Body schema: application/json
required
digitalShelfId
required
integer

ID of the digital shelf

promoCode
required
string

Promo code as typed in by the user

object (LobbyOrderUser)

User information (if known)

Responses

Request samples

Content type
application/json
{
  • "digitalShelfId": 83,
  • "promoCode": "Summer2025",
  • "user": {
    • "name": "John Doe",
    • "address": "1 Street St., City",
    • "phoneNumber": "050-111-1111",
    • "locale": "en_US"
    }
}

Response samples

Content type
application/json
Example
{
  • "valid": true,
  • "promoCode": "Summer2025.9460cdd3627c4ed"
}

Start promo code scan

Start promo code scan process to allow user to scan a promo code. This maps to the scan promo code integrator callback.

Request Body schema: application/json
required
digitalShelfId
required
integer

ID of the digital shelf

object (LobbyOrderUser)

User information (if known)

Responses

Request samples

Content type
application/json
{
  • "digitalShelfId": 673,
  • "user": {
    • "name": "John Doe",
    • "address": "1 Street St., City",
    • "phoneNumber": "050-111-1111",
    • "locale": "en_US"
    }
}

Response samples

Content type
application/json
{
  • "promoCodeScanId": 673
}

Get promo code scan status

Poll for promo code scan status by digital shelf ID.

path Parameters
promoCodeScanId
required
integer
Example: 928

Promo code scan ID

Responses

Response samples

Content type
application/json
Example
{
  • "promoCodeScanId": 673,
  • "status": "in_progress"
}

Orders

Order operations

Review order

Review order details including price calculation and age verification requirements. This maps to the calculate shopping cart integrator callback and checks for age restrictions.

This API call does not result in an order being generated yet.

Request Body schema: application/json
required
digitalShelfId
integer

ID of the digital shelf

required
Array of objects (LobbyOrderProductsList)

The products the user intends to order (in the cart)

promoCode
string

Promo code to use with this order

object (LobbyOrderUser)

User information (if known)

Responses

Request samples

Content type
application/json
{
  • "digitalShelfId": 83,
  • "products": [
    • {
      • "productId": 287,
      • "quantity": 2,
      • "modifiers": {
        • "strength": "strong",
        • "milk": "with_milk"
        }
      }
    ],
  • "promoCode": "Summer2025.9460cdd3627c4ed",
  • "user": {
    • "name": "John Doe",
    • "address": "1 Street St., City",
    • "phoneNumber": "050-111-1111",
    • "locale": "en_US"
    }
}

Response samples

Content type
application/json
{
  • "invoiceLines": [
    • {
      • "productId": 1234,
      • "amount": 4.99,
      • "sublines": [
        • {
          • "description": {
            • "en_US": "Sales Tax",
            • "de_DE": "Umsatzsteuer"
            },
          • "amount": 0.4
          }
        ]
      },
    • {
      • "productId": 5678,
      • "amount": 12.99,
      • "sublines": [
        • {
          • "description": {
            • "en_US": "Sales Tax",
            • "de_DE": "Umsatzsteuer"
            },
          • "amount": 1.04
          },
        • {
          • "description": {
            • "en_US": "Member Discount",
            • "de_DE": "Mitgliederrabatt"
            },
          • "amount": -2
          }
        ]
      },
    • {
      • "description": {
        • "en_US": "Delivery Fee",
        • "de_DE": "Liefergebühr"
        },
      • "amount": 2.99,
      • "sublines": [
        • {
          • "description": {
            • "en_US": "Sales Tax",
            • "de_DE": "Umsatzsteuer"
            },
          • "amount": 0.24
          }
        ]
      }
    ],
  • "total": 22.36,
  • "ageVerificationRequired": true
}

Create order

Submit a new order from the lobby system after successful stock reservation, order review, and age verification (if required). The order will be created and may require payment processing.

Request Body schema: application/json
required
digitalShelfId
required
integer

ID of the digital shelf

reservationId
required
integer or null

Stock reservation ID from previous step

ageVerificationId
integer or null

Age verification ID (if age verification was required)

required
Array of objects (LobbyOrderProductsList)

The products the user intends to order (in the cart)

promoCode
string

Promo code to use with this order

object (LobbyOrderUser)

User information (if known)

Responses

Request samples

Content type
application/json
{
  • "digitalShelfId": 83,
  • "reservationId": 987,
  • "ageVerificationId": 749,
  • "products": [
    • {
      • "productId": 287,
      • "quantity": 2,
      • "modifiers": {
        • "strength": "strong",
        • "milk": "with_milk"
        }
      }
    ],
  • "promoCode": "Summer2025.9460cdd3627c4ed",
  • "user": {
    • "name": "John Doe",
    • "address": "1 Street St., City",
    • "phoneNumber": "050-111-1111",
    • "locale": "en_US"
    }
}

Response samples

Content type
application/json
Example
{
  • "id": 3458,
  • "displayCode": 7465,
  • "pinCode": 7465,
  • "status": "in_progress"
}

Get order status

Get order status and details. Used by the UI to poll order status, especially when waiting for payment processing to complete.

path Parameters
id
required
string

Order ID

Responses

Response samples

Content type
application/json
Example
{
  • "id": 3458,
  • "displayCode": 7465,
  • "pinCode": 7465,
  • "status": "in_progress"
}