The lobby-gateway provides endpoints for lobby systems (digital shelves) to communicate with the Xpand Cloud. This API enables lobby systems to:
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).
| serialNumber required | string Digital Shelf serial number |
{- "serialNumber": "a12d1913af81434f"
}{- "digitalShelfId": 83,
- "siteId": 1
}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.
| siteId required | integer Example: 1 Site ID to get products for |
| fromIndex | integer >= 0 Default: 0 Get products starting from this index. Use 0 or omit for initial sync. After
the initial sync the |
{- "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": [
- {
- "id": "img_001",
- "primary": true
}
], - "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
}
]
}Retrieve all product categories for display organization.
Returns a flat list of all categories with hierarchical relationships
indicated by the parentId field.
[- {
- "id": 42,
- "name": {
- "en_US": "Snacks & Bars",
- "de_DE": "Snacks & Riegel"
}, - "parentId": null
}, - {
- "id": 87,
- "name": {
- "en_US": "Drinks",
- "de_DE": "Getränke"
}, - "parentId": 2
}
]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.
| siteId | integer Site ID in which the digital shelf is placed (obtained during handshake call) |
| 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": 1083,
- "stock": [
- {
- "productId": 27,
- "quantity": 3
}, - {
- "productId": 45,
- "quantity": 12
}
]
}Reserve stock for products that the user wants to order. This ensures availability before proceeding with order review and payment.
| 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) |
{- "digitalShelfId": 83,
- "products": [
- {
- "productId": 287,
- "quantity": 2,
- "modifiers": {
- "strength": "strong",
- "milk": "with_milk"
}
}
]
}{- "reservationId": 18736,
- "expiresAt": "2023-11-22T17:00:00Z"
}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.
{- "error": "string",
- "message": {
- "en_US": "Payment failed",
- "de_DE": "Zahlung fehlgeschlagen"
}, - "details": { }
}Start age verification process for orders containing age-restricted products. This maps to the age verification integrator callback.
| 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) |
{- "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"
}
}{- "ageVerificationId": 749
}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).
| 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) |
{- "digitalShelfId": 83,
- "promoCode": "Summer2025",
- "user": {
- "name": "John Doe",
- "address": "1 Street St., City",
- "phoneNumber": "050-111-1111",
- "locale": "en_US"
}
}{- "valid": true,
- "promoCode": "Summer2025.9460cdd3627c4ed"
}Start promo code scan process to allow user to scan a promo code. This maps to the scan promo code integrator callback.
| digitalShelfId required | integer ID of the digital shelf |
object (LobbyOrderUser) User information (if known) |
{- "digitalShelfId": 673,
- "user": {
- "name": "John Doe",
- "address": "1 Street St., City",
- "phoneNumber": "050-111-1111",
- "locale": "en_US"
}
}{- "promoCodeScanId": 673
}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.
| 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) |
{- "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"
}
}{- "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
}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.
| 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) |
{- "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"
}
}{- "id": 3458,
- "displayCode": 7465,
- "pinCode": 7465,
- "status": "in_progress"
}Get order status and details. Used by the UI to poll order status, especially when waiting for payment processing to complete.
| id required | string Order ID |
{- "id": 3458,
- "displayCode": 7465,
- "pinCode": 7465,
- "status": "in_progress"
}