Download OpenAPI specification:
Programmatic access to Livello's autonomous retail infrastructure.
Production Endpoint: https://my.livello.com/api/v1
The future of autonomous retail. Livello's intelligent smart kiosks make fresh meals, snacks, beverages, and daily essentials available around the clock — anywhere people live, work, and stay.
With automatic product recognition, real-time inventory tracking, and a 10-second average checkout time, each compact unit — just 1m² — operates autonomously without on-site staff. Our clients manage all their units digitally and stay connected to their units and users 24/7.
Our solutions are deployed across Europe in canteens, offices, hotels, healthcare facilities, and educational institutions. Built and engineered in Germany, Livello's patented technology provides a reliable foundation for autonomous retail operations.
The Open Platform API gives your systems direct, programmatic access to this infrastructure — so you can build integrations that keep your data in sync and your operations running automatically.
The Open Platform API gives machine-to-machine (M2M) clients access to:
All data is automatically scoped to your organization and its sub-organizations.
POST /auth/token (see Authentication)Authorization: Bearer <token>Example — request a token and list your kiosks:
# 1. Get a token
TOKEN=$(curl -s -X POST https://my.livello.com/auth/token \
-H "Content-Type: application/json" \
-d '{"client_id":"lv_m2m_abc123","client_secret":"sk_live_xxx","grant_type":"client_credentials"}' \
| jq -r .access_token)
# 2. List kiosks
curl -s https://my.livello.com/kiosks \
-H "Authorization: Bearer $TOKEN" | jq
Tokens are valid for 24 hours and are cached server-side — repeated requests with the same credentials return the same token until it expires. See Authentication for scopes, rate limits, and error handling.
To access the API, you need M2M (machine-to-machine) client credentials. These are provisioned by Livello upon request — contact the Livello Service Team via Service@livello.com or +49 211 63556321.
Each client receives:
| Credential | Format | Description |
|---|---|---|
| Client ID | lv_m2m_<hex> |
Public identifier for your integration |
| Client Secret | sk_live_<hex> |
Private key — used to request access tokens |
| Scopes | e.g. kiosks:read inventory:read |
Controls which endpoints your client can access (see Scopes) |
Store your secret securely. The client secret is delivered once and cannot be recovered. If lost, a new one must be issued.
Optional but recommended for production. Restrict token issuance to specific
IP addresses or CIDR ranges. When enabled, token requests from unlisted IPs are
rejected with 403 Forbidden.
Configured during registration or on request — contact Livello to set up or modify.
Defaults to 24 hours, configurable per client. See Token Lifecycle for caching, renewal, and revocation details.
The following terms appear throughout the API and reflect how Livello models its autonomous retail operations.
| Term | Description |
|---|---|
| Organization | The root entity for data ownership. Every kiosk, product, user, and transaction belongs to an organization. Organizations can be nested (parent -> child) for multi-level structures. All API data is automatically scoped to your organization and its descendants. |
| Kiosk | A physical smart vending unit identified by a unique serialNumber (e.g., LIV-0042). Each kiosk contains multiple load cells, and each load cell holds a different product. |
| Load Cell | A physical compartment inside a kiosk equipped with a weight sensor. Each load cell is assigned one product line and tracks inventory by measuring weight changes. Identified by a planogramPosition (e.g., A11, B21) and a hardware cellId. |
| Product Meta | The abstract definition of a sellable product — a catalog template shared across all kiosks in an organization. Contains name, manufacturer, category, nutrition, images, and default pricing. This is what the /products endpoints return. |
| Product Line | The binding between a product meta and a load cell. Defines how that product is sold on that particular scale: pricing, tax rules, and capacity. Each load cell is assigned one product line. Visible in the /kiosks/:serialNumber/inventory response. |
| Product | An individual physical item sitting inside the kiosk. Each product belongs to a product line and tracks its own EAN, expiration date, and state (availableForPurchase, sold, removed). The inventory count on a load cell equals the number of products in availableForPurchase state. |
| Transaction | A purchase session representing the full customer lifecycle: payment authorization → door opens → customer takes items → door closes → inventory reconciled → receipt generated. Listed via /transactions. |
| Refill | A restocking session initiated by an operator entering a PIN code on the kiosk. The unit unlocks, the operator adds or removes products, and inventory is recalculated when the door closes. Listed via /refills. |
The OpenAPI specification is available as a downloadable JSON file. You can import it into Postman or any OpenAPI-compatible tool.
Postman import steps:
openapi.json using the Download button at the top of this pageBearer Token and paste your access tokenTip: Tags in the OpenAPI spec map directly to Postman collection folders, making it easy to navigate endpoints by resource type.
Official client libraries for the Livello Open Platform API. Each SDK is generated from the OpenAPI specification, so method signatures and models always match the live API.
| Language | Package | Runtime |
|---|---|---|
| Python | livello-api |
Python 3.8+ (Pydantic models, urllib3) |
| TypeScript | @livello/open-platform-sdk |
Node.js / Browser (Fetch API, full type definitions) |
SDK download links are provided as part of your M2M client onboarding. Contact your Livello account manager if you haven't received them.
Python — install directly from URL with pip:
# Latest version
pip install https://my.livello.com/developer/sdks/livello-python-sdk-latest.zip
# Specific version
pip install https://my.livello.com/developer/sdks/1.0.0/livello-python-sdk-1.0.0.zip
TypeScript — download, extract, and install as a local package:
# Latest version
curl -O https://my.livello.com/developer/sdks/livello-typescript-sdk-latest.zip
unzip livello-typescript-sdk-latest.zip -d livello-sdk
npm install ./livello-sdk
# Specific version
curl -O https://my.livello.com/developer/sdks/1.0.0/livello-typescript-sdk-1.0.0.zip
unzip livello-typescript-sdk-1.0.0.zip -d livello-sdk
npm install ./livello-sdk
Both examples authenticate with client credentials, then list all kiosks — the same flow shown in the Quick Start using curl.
Python:
from livello_api import ApiClient, Configuration, AuthenticationApi, KiosksApi
from livello_api.models import TokenRequestDto
# 1. Get a token
auth_api = AuthenticationApi()
token_response = auth_api.get_token(
TokenRequestDto(
client_id="lv_m2m_abc123",
client_secret="sk_live_xxx",
grant_type="client_credentials",
)
)
# 2. Configure the client with the token
config = Configuration(access_token=token_response.access_token)
client = ApiClient(config)
# 3. List kiosks
kiosks_api = KiosksApi(client)
response = kiosks_api.get_kiosks()
for kiosk in response.data:
print(f"{kiosk.serial_number}: {kiosk.name}")
TypeScript:
import {
AuthenticationApi,
KiosksApi,
Configuration,
} from "@livello/open-platform-sdk";
// 1. Get a token
const authApi = new AuthenticationApi();
const { accessToken } = await authApi.getToken({
tokenRequestDto: {
clientId: "lv_m2m_abc123",
clientSecret: "sk_live_xxx",
grantType: "client_credentials",
},
});
// 2. Configure the client with the token
const config = new Configuration({ accessToken });
const kiosksApi = new KiosksApi(config);
// 3. List kiosks
const { data } = await kiosksApi.getKiosks();
for (const kiosk of data) {
console.log(`${kiosk.serialNumber}: ${kiosk.name}`);
}
Obtain and manage API access tokens. You need M2M client credentials before using the API. See Client Registration for how to obtain your client ID, client secret, and scopes.
Exchange your client_id and client_secret for a JWT access token.
The token is included as a Bearer token in the Authorization header of all subsequent requests.
POST /auth/token
Content-Type: application/json
{
"client_id": "lv_m2m_abc123",
"client_secret": "sk_live_xxxxxxxxxxxxxxxx",
"grant_type": "client_credentials"
}
{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 86400,
"scope": "kiosks:read inventory:read"
}
GET /kiosks
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
| Aspect | Details |
|---|---|
| Expiration | 24 hours (default, configurable per client) |
| Caching | Tokens are cached server-side. Repeated requests with the same credentials return the same JWT until it expires. |
| Renewal | Request a new token after expiry using the same credentials. |
| Revocation | Immediate. Cached tokens are invalidated on the next API call. New token requests are rejected. |
Your client is granted specific scopes that determine which endpoints are accessible.
Requesting an endpoint without the required scope returns 403 Forbidden.
| Scope | Description |
|---|---|
kiosks:read |
List kiosks, get kiosk details, capacity, and current session |
inventory:read |
Get kiosk inventory (load cells, product quantities, pricing) and low-stock reports |
products:read |
Browse product catalog, get product detail and images |
products:write |
Create, update, and delete product catalog entries; update product line prices |
transactions:read |
List and retrieve purchase transactions |
refills:read |
List and retrieve refill/restocking sessions |
organizations:read |
List organizations, get organization detail |
users:read |
List users, get user detail |
users:write |
Create and update users |
alerts:read |
List alerts and retrieve alert type definitions |
reports:read |
Access all analytics endpoints (sales, transactions, refills, inventory, temperature) |
promocodes:read |
Retrieve promo code details and eligibility |
promocodes:write |
Create promo codes and manage product line eligibility |
Optional. When configured, only token requests from allowed IP addresses or CIDR
ranges are accepted — requests from unlisted IPs receive 403 Forbidden.
IP restrictions are enforced at token issuance, not on individual API calls. Contact Livello to configure (see Client Registration).
| Scope | Limit |
|---|---|
| All API endpoints | 1,000 requests per hour per client |
POST /auth/token |
10 requests per minute per client |
All API responses include standard rate limit headers:
| Header | Description |
|---|---|
RateLimit-Limit |
Maximum requests allowed in the current window |
RateLimit-Remaining |
Requests remaining in the current window |
RateLimit-Reset |
Seconds until the window resets |
Retry-After |
Seconds to wait (only present on 429 responses) |
Exceeding either limit returns 429 Too Many Requests.
All errors follow the RFC 7807 Problem Details standard:
{
"type": "https://api.livello.com/errors/forbidden",
"title": "Forbidden",
"status": 403,
"detail": "Insufficient scope. Required: kiosks:read",
"instance": "/api/v1/kiosks"
}
Exchange M2M client credentials for a JWT access token. Tokens are cached server-side — repeated requests return the same token until expiry.
| client_id required | string The public client ID assigned to the M2M client |
| client_secret required | string The client secret for authentication |
| grant_type required | string Must be "client_credentials" (OAuth2 grant type) |
{- "client_id": "lv_m2m_abc123",
- "client_secret": "your_client_secret",
- "grant_type": "client_credentials"
}{- "access_token": "eyJhbGciOiJIUzI1NiIs...",
- "token_type": "Bearer",
- "expires_in": 86400,
- "scope": "kiosks:read inventory:read"
}A kiosk is a physical smart vending unit identified by a unique serial number
(e.g., LIV-0042). Each kiosk contains multiple load cells, and each load cell
holds one product.
Query your kiosk fleet — list units, get details, check real-time inventory, and view the current or most recent session.
See also: Products · Product Lines · Alerts
| sort | number 1 = ASC, -1 = DESC |
| sortColumn | string Sort by: name, serialNumber, networkLastOnline, organizationName, latestTemperature, todaySalesTotal |
| name | string Filter by name (partial match) |
| limit | number Example: limit=25 Page size |
| page | number Example: page=1 Page number (1-based) |
{- "total": 42,
- "data": [
- {
- "id": 1,
- "name": "Lobby Fridge",
- "serialNumber": "LIV-0042",
- "networkLastOnline": "2025-06-15T10:30:00.000Z",
- "online": true,
- "doorStatus": "closed",
- "latestTemperature": 4.5,
- "organizationName": "SuperMarkt GmbH",
- "organizationCurrency": "EUR",
- "todaySalesTotal": 127.5
}
]
}| serialNumber required | string Kiosk serial number (e.g., LIV-0042) |
{- "_id": "LIV-0042",
- "name": "Lobby Fridge",
- "orgId": "123",
- "serialNumber": "LIV-0042",
- "inventory": {
- "loadCells": [
- {
- "cellId": "lc-456",
- "maxQty": 12,
- "occupancy": 8,
- "planogramPosition": "A1",
- "surfaceSize": "100",
- "products": [
- {
- "_id": "pl-789"
}
], - "priceTag": "3.50",
- "productLine": {
- "_id": "789",
- "name": "Coca-Cola 0.33L",
- "articleNumber": "ART-001",
- "packagingOptions": {
- "ean": "4005808262106",
- "grossWeightGrams": 200,
- "tolerancePercentage": 5,
- "packageWeightGrams": 50
}, - "energy": "200 kcal",
- "fat": "5g",
- "fatSaturated": "2g",
- "carbo": "30g",
- "carboSugar": "15g"
}
}
]
}, - "controller": {
- "preAuth": 40,
- "tabletLang": "de",
- "tabletFont": "Arial",
- "paymentType": "CreditOrDebitCard",
- "minimumAge": 18,
- "serviceCheck": {
- "enabled": true
}
}, - "ownerOrganization": {
- "_id": "123",
- "name": "SuperMarkt GmbH",
- "currency": "EUR",
- "support": {
- "email": "support@org.com",
- "hotline": "+49123456789"
}, - "contact": {
- "supportEmail": "support@org.com",
- "supportPhoneNumber": "+49123456789"
}, - "kioskInitScreen": {
- "headerTextColor": "#000000",
- "bgColor": "#FFFFFF",
- "bodyTextColor": "#000000"
}
}
}| serialNumber required | string Kiosk serial number (e.g., LIV-0042) |
[- {
- "loadCellId": 1,
- "planogramPosition": "A1",
- "surfaceSize": 100,
- "cellId": 456,
- "productLineData": {
- "maxCapacity": 12,
- "availableCount": 8,
- "productInfo": {
- "name": "Coca-Cola 0.33L",
- "images": [
- "string"
], - "price": 3.5,
- "defaultPrice": 3.5,
- "productLineId": 0,
- "productLineMetaId": 0,
- "description": "Refreshing carbonated drink",
- "category": "Beverages",
- "manufacturer": "The Coca-Cola Company",
- "articleNumber": "ART-001",
- "organizationName": "SuperMarkt GmbH",
- "nutrition": {
- "energy": "200 kcal",
- "fat": "5g",
- "fatSaturated": "2g",
- "carbo": "30g",
- "carboSugar": "15g",
- "fiber": "2g",
- "protein": "3g",
- "salt": "0.5g"
}, - "dietaryInfo": {
- "glutenFree": false,
- "vegetarian": true,
- "vegan": false,
- "allergens": "Nuts, Milk",
- "ingredientsList": "Sugar, Water, Cocoa Butter..."
}, - "packaging": {
- "ean": "4005808262106",
- "description": "100g box",
- "unitCount": 10,
- "shelfLifeDays": 180,
- "netWeightGrams": 100,
- "grossWeightGrams": 150,
- "packageWeightGrams": 50,
- "netWeightGramsUnit": "g",
- "tolerancePercentage": 5,
- "state": "active"
}, - "capacities": [
- {
- "surfaceSize": 100,
- "units": 12
}
]
}
}
}
]| serialNumber required | string Kiosk serial number (e.g., LIV-0042) |
| maxAgeMinutes | number Example: maxAgeMinutes=30 Max age in minutes for a session to be considered recent (default: 30) |
{- "status": "CLOSED",
- "type": "purchase",
- "createdAt": "2025-10-15T09:00:00.000Z",
- "updatedAt": "2025-10-15T09:30:00.000Z",
- "isTerminal": true,
- "details": {
- "sessionClosedAt": "2025-10-15T09:30:00.000Z",
- "endedWithPurchase": true,
- "externalTransactionId": "ext-txn-abc123"
}
}A product (product meta) is the catalog definition of a sellable item — shared across all kiosks in your organization. Contains name, manufacturer, category, nutrition data, images, and default pricing.
Browse, create, update, and delete catalog entries.
See also: Product Lines · Kiosks
| name | string Filter by product name (partial match) |
| category | string Filter by category |
| manufacturer | string Filter by manufacturer |
| sort | number Enum: 1 -1 1 = ASC, -1 = DESC (default: 1) |
| sortBy | string Enum: "name" "manufacturer" "weight" "cost" "price" Column to sort by. Unknown values fall back to the default (name). |
| limit | number Example: limit=25 Page size (max 100) |
| page | number Example: page=1 Page number (1-based) |
{- "total": 156,
- "data": [
- {
- "id": 10,
- "name": "Coca-Cola 0.33L",
- "description": "Carbonated soft drink",
- "category": "Beverages",
- "manufacturer": "The Coca-Cola Company",
- "articleNumber": "ART-001",
- "organizationId": 5,
- "organizationName": "SuperMarkt GmbH",
- "organizationCurrency": "EUR",
- "netPrice": "1.50",
- "price": "1.79",
- "cost": 0.85,
- "weight": 330,
- "weightUnit": "g",
- "updatedAt": "2025-03-15T10:00:00.000Z",
- "createdAt": "2025-01-01T08:00:00.000Z",
}
]
}Required fields: name, organizationId, manufacturer, pricing (defaultPrice, defaultCost), packaging (shelfLifeDays, grossWeightGrams, netWeightGrams, netWeightGramsUnit), capacities (at least one entry).
| name required | string Product name | ||||||||||||||||||
| manufacturer required | string Manufacturer | ||||||||||||||||||
| organizationId required | number Organization ID | ||||||||||||||||||
required | object Pricing info (required for creation) | ||||||||||||||||||
| |||||||||||||||||||
required | object Packaging info (required for creation) | ||||||||||||||||||
| |||||||||||||||||||
required | Array of objects (ProductMetaCapacityInput) Load cell capacities (required for creation) | ||||||||||||||||||
Array
| |||||||||||||||||||
| description | string | ||||||||||||||||||
| category | string | ||||||||||||||||||
| articleNumber | string | ||||||||||||||||||
object (ProductMetaNutritionInput) | |||||||||||||||||||
| |||||||||||||||||||
object (ProductMetaDietaryInfoInput) | |||||||||||||||||||
| |||||||||||||||||||
Array of objects (ProductMetaImageInput) | |||||||||||||||||||
Array
| |||||||||||||||||||
| copyImagesFromMetaId | number Copy image(s) from this source meta id when no images are supplied | ||||||||||||||||||
{- "name": "Coca-Cola 0.33L",
- "organizationId": 42,
- "manufacturer": "The Coca-Cola Company",
- "pricing": {
- "defaultPrice": 1.79,
- "defaultCost": 0.85
}, - "packaging": {
- "shelfLifeDays": 180,
- "grossWeightGrams": 345,
- "netWeightGrams": 330,
- "netWeightGramsUnit": "ml"
}, - "capacities": [
- {
- "surfaceSize": 1,
- "units": 6
}
]
}{- "id": 10,
- "name": "Coca-Cola 0.33L",
- "description": "Carbonated soft drink",
- "category": "Beverages",
- "manufacturer": "The Coca-Cola Company",
- "articleNumber": "ART-001",
- "organizationId": 5,
- "organizationName": "SuperMarkt GmbH",
- "organizationCurrency": "EUR",
- "netPrice": "1.50",
- "price": "1.79",
- "cost": 0.85,
- "weight": 330,
- "weightUnit": "g",
- "updatedAt": "2025-03-15T10:00:00.000Z",
- "createdAt": "2025-01-01T08:00:00.000Z",
}| id required | number Product line meta ID |
{- "id": 10,
- "name": "Coca-Cola 0.33L",
- "description": "Carbonated soft drink",
- "category": "Beverages",
- "manufacturer": "The Coca-Cola Company",
- "articleNumber": "ART-001",
- "organizationId": 5,
- "organizationName": "SuperMarkt GmbH",
- "organizationCurrency": "EUR",
- "netPrice": "1.50",
- "price": "1.79",
- "cost": 0.85,
- "weight": 330,
- "weightUnit": "g",
- "updatedAt": "2025-03-15T10:00:00.000Z",
- "createdAt": "2025-01-01T08:00:00.000Z",
}| id required | number Product line meta ID |
| name | string Product name | ||||||||||||||||||
| description | string | ||||||||||||||||||
| category | string | ||||||||||||||||||
| manufacturer | string Manufacturer | ||||||||||||||||||
| articleNumber | string | ||||||||||||||||||
| organizationId | number Organization ID | ||||||||||||||||||
object (ProductMetaNutritionInput) | |||||||||||||||||||
| |||||||||||||||||||
object (ProductMetaDietaryInfoInput) | |||||||||||||||||||
| |||||||||||||||||||
object Pricing info (required for creation) | |||||||||||||||||||
| |||||||||||||||||||
Array of objects (ProductMetaImageInput) | |||||||||||||||||||
Array
| |||||||||||||||||||
object Packaging info (required for creation) | |||||||||||||||||||
| |||||||||||||||||||
Array of objects (ProductMetaCapacityInput) Load cell capacities (required for creation) | |||||||||||||||||||
Array
| |||||||||||||||||||
| copyImagesFromMetaId | number Copy image(s) from this source meta id when no images are supplied | ||||||||||||||||||
{- "name": "Coca-Cola Zero 0.33L"
}{- "id": 10,
- "name": "Coca-Cola 0.33L",
- "description": "Carbonated soft drink",
- "category": "Beverages",
- "manufacturer": "The Coca-Cola Company",
- "articleNumber": "ART-001",
- "organizationId": 5,
- "organizationName": "SuperMarkt GmbH",
- "organizationCurrency": "EUR",
- "netPrice": "1.50",
- "price": "1.79",
- "cost": 0.85,
- "weight": 330,
- "weightUnit": "g",
- "updatedAt": "2025-03-15T10:00:00.000Z",
- "createdAt": "2025-01-01T08:00:00.000Z",
}A product line binds a product to a specific load cell inside a kiosk. It defines how that product is sold on that particular scale: pricing, tax rate, and capacity. Each load cell has exactly one product line.
The product line ID is separate from the product (meta) ID — use the inventory endpoint under Kiosks to discover product line IDs.
See also: Products · Kiosks · Promocodes
Inserts a new price history record for a product line (the binding of a product to a load cell). The product line ID is NOT the same as the product meta ID — it identifies a specific slot in a kiosk.
| id required | number Product line ID (not product meta ID) |
| price required | number New gross price including VAT |
| productLineId | number Product line ID (overridden by URL param in REST — omit for REST calls) |
| validFrom | string Valid from (ISO 8601, defaults to now) |
| validTo | string Valid until (ISO 8601, null = indefinite) |
{- "price": 1.99
}A transaction represents a complete purchase session: payment authorization → door opens → customer takes items → door closes → inventory reconciled → receipt generated.
List and retrieve transaction history with line items and payment details.
Supports timezone conversion via the x-timezone header (default: Europe/Berlin).
See also: Kiosks · Analytics: Sales · Analytics: Transactions
| sort | number Enum: 1 -1 1 = ASC, -1 = DESC (default: -1) |
| sortBy | string Enum: "created" "total" "kioskName" "type" Column to sort by. Unknown values fall back to the default (created). |
| startDate | string Example: startDate=2025-01-01T00:00:00.000Z Start date (ISO 8601) |
| endDate | string Example: endDate=2025-12-31T23:59:59.999Z End date (ISO 8601) |
| kioskSerialNumbers | string Comma-separated kiosk serial numbers |
| limit | number Example: limit=25 Page size |
| skip | number Example: skip=0 Pagination offset (0-based) |
| x-timezone | string IANA timezone for date conversion (default: Europe/Berlin) |
{- "total": 523,
- "membercardList": [
- "MC-001",
- "MC-002"
], - "data": [
- {
- "id": 1001,
- "created": "2025-03-18T14:30:00.000Z",
- "total": 45.99,
- "discountTotal": 5,
- "session": {
- "details": {
- "promoCode": {
- "code": "SPRING25"
}
}
}, - "type": "purchase",
- "userId": 0,
- "kiosk": {
- "id": 1,
- "name": "Lobby Fridge",
- "serialNumber": "LIV-0042"
}, - "paymentMethod": {
- "isPaid": true,
- "membercardId": "MC-001",
- "paymentCardType": "Credit",
- "cardType": "Visa",
- "paymentType": "MEMBERCARD",
- "externalTransactionId": "string"
}, - "itemsPurchased": [
- {
- "price": 3.5,
- "vat": 0.56,
- "productLine": {
- "id": 789,
- "productLineMetaId": 0,
- "name": "Coca-Cola 0.33L",
- "articleNumber": "ART-001",
- "manufacturer": "The Coca-Cola Company"
}, - "kiosk": {
- "id": 1,
- "name": "Lobby Fridge",
- "serialNumber": "LIV-0042"
}, - "productPosition": "A1"
}
]
}
]
}| id required | number Transaction ID |
| x-timezone | string IANA timezone for date conversion (default: Europe/Berlin) |
{- "id": 1001,
- "created": "2025-03-18T14:30:00.000Z",
- "total": 45.99,
- "discountTotal": 5,
- "session": {
- "details": {
- "promoCode": {
- "code": "SPRING25"
}
}
}, - "type": "purchase",
- "userId": 0,
- "kiosk": {
- "id": 1,
- "name": "Lobby Fridge",
- "serialNumber": "LIV-0042"
}, - "paymentMethod": {
- "isPaid": true,
- "membercardId": "MC-001",
- "paymentCardType": "Credit",
- "cardType": "Visa",
- "paymentType": "MEMBERCARD",
- "externalTransactionId": "string"
}, - "itemsPurchased": [
- {
- "price": 3.5,
- "vat": 0.56,
- "productLine": {
- "id": 789,
- "productLineMetaId": 0,
- "name": "Coca-Cola 0.33L",
- "articleNumber": "ART-001",
- "manufacturer": "The Coca-Cola Company"
}, - "kiosk": {
- "id": 1,
- "name": "Lobby Fridge",
- "serialNumber": "LIV-0042"
}, - "productPosition": "A1"
}
]
}A refill is a restocking session initiated by an operator entering a PIN on the kiosk. The unit unlocks, the operator adds or removes products, and inventory is recalculated when the door closes.
List and retrieve refill history with item-level detail.
Supports timezone conversion via the x-timezone header (default: Europe/Berlin).
See also: Kiosks · Analytics: Refills
| sort | number 1 = ASC, -1 = DESC (default: -1) |
| startDate | string Example: startDate=2025-01-01T00:00:00.000Z Start date (ISO 8601) |
| endDate | string Example: endDate=2025-12-31T23:59:59.999Z End date (ISO 8601) |
| kioskSerialNumbers | string Comma-separated kiosk serial numbers |
| limit | number Example: limit=25 Page size |
| skip | number Example: skip=0 Pagination offset (0-based) |
| x-timezone | string IANA timezone for date conversion (default: Europe/Berlin) |
{- "total": 87,
- "data": [
- {
- "id": 201,
- "created": "2025-03-18T08:15:00.000Z",
- "type": "manual",
- "kiosk": {
- "id": 1,
- "name": "Lobby Fridge",
- "serialNumber": "LIV-0042"
}, - "itemsReplenished": [
- {
- "productLineId": 0,
- "productLineMetaId": 0,
- "productName": "Coca-Cola 0.33L",
- "articleNumber": "ART-001",
- "status": "Added",
- "count": 5,
- "cellId": 0,
- "weight": 250.5,
- "cost": 0.85,
- "totalCost": 4.25
}
]
}
]
}| id required | number Refill ID |
| x-timezone | string IANA timezone for date conversion (default: Europe/Berlin) |
{- "id": 201,
- "created": "2025-03-18T08:15:00.000Z",
- "type": "manual",
- "kiosk": {
- "id": 1,
- "name": "Lobby Fridge",
- "serialNumber": "LIV-0042"
}, - "itemsReplenished": [
- {
- "productLineId": 0,
- "productLineMetaId": 0,
- "productName": "Coca-Cola 0.33L",
- "articleNumber": "ART-001",
- "status": "Added",
- "count": 5,
- "cellId": 0,
- "weight": 250.5,
- "cost": 0.85,
- "totalCost": 4.25
}
]
}An organization is the root entity for data ownership. Every kiosk, product, user, and transaction belongs to an organization. Organizations can be nested (parent → child) for multi-level structures.
All API data is automatically scoped to your organization and its descendants.
| sortBy | string Enum: "name" "kioskCount" Column to sort by. Unknown values fall back to the default (name). |
| sort | number Enum: 1 -1 1 = ASC, -1 = DESC (default: 1) |
| postalCode | string Postal code filter |
| country | string Country filter |
| city | string City filter |
| organizationType | string Filter by org type |
| name | string Search by name |
| limit | number Pagination size |
| skip | number Pagination offset |
{- "total": 25,
- "data": [
- {
- "id": 42,
- "name": "SuperMarkt GmbH",
- "slug": "supermarkt-gmbh",
- "type": "CLIENT",
- "imageUrl": "string",
- "currency": "EUR",
- "description": "string",
- "kioskCount": 3,
- "address": {
- "address": "Friedrichstraße 123",
- "postalCode": "10117",
- "city": "Berlin",
- "countryCode": "DE"
}
}
]
}Required fields: name, type, currency, address.country. parentOrg is required for non-root users.
Organization creation input
| name required | string Organization name | ||||||||||||
| type required | string Enum: "general" "client" "manufacturer" Organization type | ||||||||||||
| currency required | string Enum: "eur" "chf" "gbp" "usd" "czk" Payment currency | ||||||||||||
required | object Organization address (required for creation) | ||||||||||||
| |||||||||||||
| slug | string | ||||||||||||
| description | string | ||||||||||||
| eanPrefix | string | ||||||||||||
object (OrganizationContactInput) | |||||||||||||
| |||||||||||||
object (OrganizationSupportInput) | |||||||||||||
| |||||||||||||
| parentOrg | object or null Parent organization ID. Required for non-superadmin users on create. Cannot be nullified on update. | ||||||||||||
| privacyPolicyUrl | string | ||||||||||||
| termsAndConditionsUrl | string | ||||||||||||
{- "name": "SuperMarkt GmbH",
- "type": "client",
- "currency": "eur",
- "parentOrg": 42,
- "address": {
- "country": "Germany",
- "countryCode": "DE"
}
}{- "id": 42,
- "name": "SuperMarkt GmbH",
- "slug": "supermarkt-gmbh",
- "type": "CLIENT",
- "description": "string",
- "imageUrl": "string",
- "address": {
- "address": "Friedrichstraße 123",
- "postalCode": "10117",
- "city": "Berlin",
- "countryCode": "DE"
}, - "currency": "EUR",
- "parentOrg": 1
}| id required | number |
{- "id": 42,
- "name": "SuperMarkt GmbH",
- "slug": "supermarkt-gmbh",
- "type": "CLIENT",
- "description": "string",
- "imageUrl": "string",
- "address": {
- "address": "Friedrichstraße 123",
- "postalCode": "10117",
- "city": "Berlin",
- "countryCode": "DE"
}, - "currency": "EUR",
- "parentOrg": 1
}| id required | number |
| name | string Organization name | ||||||||||||
| slug | string | ||||||||||||
| type | string Enum: "general" "client" "manufacturer" Organization type | ||||||||||||
| description | string | ||||||||||||
| currency | string Enum: "eur" "chf" "gbp" "usd" "czk" Payment currency | ||||||||||||
| eanPrefix | string | ||||||||||||
object Organization address (required for creation) | |||||||||||||
| |||||||||||||
object (OrganizationContactInput) | |||||||||||||
| |||||||||||||
object (OrganizationSupportInput) | |||||||||||||
| |||||||||||||
| parentOrg | object or null Parent organization ID. Required for non-superadmin users on create. Cannot be nullified on update. | ||||||||||||
| privacyPolicyUrl | string | ||||||||||||
| termsAndConditionsUrl | string | ||||||||||||
{- "name": "New Org Name"
}{- "id": 42,
- "name": "SuperMarkt GmbH",
- "slug": "supermarkt-gmbh",
- "type": "CLIENT",
- "description": "string",
- "imageUrl": "string",
- "address": {
- "address": "Friedrichstraße 123",
- "postalCode": "10117",
- "city": "Berlin",
- "countryCode": "DE"
}, - "currency": "EUR",
- "parentOrg": 1
}A user represents an account within your organization. The API supports managing consumer users — end customers who interact with kiosks.
List, create, and update users within your organization scope.
| skip | number Example: skip=0 Pagination offset (0-based) |
| limit | number Example: limit=25 Page size |
| sort | number Enum: 1 -1 1 = ASC, -1 = DESC |
| sortBy | string Enum: "firstName" "role" "organizationName" "updated" Column to sort by. Unknown values fall back to the default (firstName). |
| name | string Filter by name (partial match) |
| role | string Filter by role (admin, superadmin, consumer, operator) |
{- "total": 48,
- "data": [
- {
- "id": 1,
- "email": "john@example.com",
- "firstName": "John",
- "lastName": "Doe",
- "role": "admin",
- "organizationName": "SuperMarkt GmbH",
- "status": "ACTIVE",
- "root": false,
- "lang": "en",
- "created": "2025-01-15T10:00:00.000Z",
- "updated": "2025-06-20T14:30:00.000Z"
}
]
}Creates a consumer user in the specified organization. Required fields: email, firstName, lastName, organizationId, status, lang.
| email required | string User email address | ||||||||
| firstName required | string First name | ||||||||
| lastName required | string Last name | ||||||||
| status required | string Enum: "ACTIVE" "INACTIVE" User status | ||||||||
| lang required | string Enum: "en" "de" "it" "fr" Language | ||||||||
| organizationId required | number Organization ID to assign the user to | ||||||||
| mobile | string | ||||||||
| note | string | ||||||||
| avatarUrl | string | ||||||||
| membercards | Array of strings Membercard IDs | ||||||||
object (UserAddressInput) | |||||||||
| |||||||||
{- "email": "john.doe@example.com",
- "firstName": "John",
- "lastName": "Doe",
- "organizationId": 42,
- "status": "ACTIVE",
- "lang": "en"
}{- "id": 1,
- "email": "john@example.com",
- "firstName": "John",
- "lastName": "Doe",
- "status": "ACTIVE",
- "root": false,
- "lang": "en",
- "termsAccepted": true,
- "membercards": [
- "MC-001"
], - "rolesInOrganizations": [
- {
- "id": 1,
- "organizationId": 42,
- "organizationName": "SuperMarkt GmbH",
- "role": "admin",
- "status": "active"
}
], - "created": "2025-01-15T10:00:00.000Z",
- "updated": "2025-06-20T14:30:00.000Z"
}{- "id": 1,
- "email": "john@example.com",
- "firstName": "John",
- "lastName": "Doe",
- "status": "ACTIVE",
- "root": false,
- "lang": "en",
- "termsAccepted": true,
- "membercards": [
- "MC-001"
], - "rolesInOrganizations": [
- {
- "id": 1,
- "organizationId": 42,
- "organizationName": "SuperMarkt GmbH",
- "role": "admin",
- "status": "active"
}
], - "created": "2025-01-15T10:00:00.000Z",
- "updated": "2025-06-20T14:30:00.000Z"
}| id required | number User ID |
string User email address | |||||||||
| firstName | string First name | ||||||||
| lastName | string Last name | ||||||||
| mobile | string | ||||||||
| note | string | ||||||||
| avatarUrl | string | ||||||||
| status | string Enum: "ACTIVE" "INACTIVE" User status | ||||||||
| membercards | Array of strings Membercard IDs | ||||||||
| lang | string Enum: "en" "de" "it" "fr" Language | ||||||||
object (UserAddressInput) | |||||||||
| |||||||||
{- "firstName": "Jane",
- "lastName": "Smith"
}{- "id": 1,
- "email": "john@example.com",
- "firstName": "John",
- "lastName": "Doe",
- "status": "ACTIVE",
- "root": false,
- "lang": "en",
- "termsAccepted": true,
- "membercards": [
- "MC-001"
], - "rolesInOrganizations": [
- {
- "id": 1,
- "organizationId": 42,
- "organizationName": "SuperMarkt GmbH",
- "role": "admin",
- "status": "active"
}
], - "created": "2025-01-15T10:00:00.000Z",
- "updated": "2025-06-20T14:30:00.000Z"
}An alert is an operational notification generated by a kiosk — inventory
warnings, temperature issues, connectivity problems, and more. Each alert has
a severity (low, mid, high) and a lifecycle: open → raised → resolved.
List alerts with filtering by kiosk, type, severity, and status. Retrieve alert type definitions for reference.
See also: Kiosks
| offset | number Example: offset=0 Pagination offset (0-based) |
| limit | number Example: limit=50 Page size |
| kioskSerialNumbers | string Comma-separated kiosk serial numbers |
| types | string Comma-separated alert types |
| severities | string Comma-separated severities (low, mid, high) |
| statuses | string Comma-separated statuses (open, raised, resolved) |
| isAck | boolean Filter by acknowledgment status |
| startDateFrom | string Alerts created after (ISO 8601) |
| startDateTo | string Alerts created before (ISO 8601) |
| orderBy | string Sort field: startDate or createdAt |
| orderDirection | string ASC or DESC (default: DESC) |
{- "total": 156,
- "data": [
- {
- "id": 42,
- "type": "HighTemperature",
- "severity": "high",
- "status": "raised",
- "isAck": false,
- "startDate": "2025-10-15T08:30:00.000Z",
- "endDate": "2025-10-15T09:00:00.000Z",
- "kioskSerialNumber": "LIV-0042",
- "kioskName": "Lobby Fridge",
- "detailsJson": "string",
- "createdAt": "2025-10-15T08:30:00.000Z",
- "updatedAt": "2025-10-15T09:00:00.000Z"
}
]
}A promo code is a discount mechanism applied at checkout. Each code has a balance, validity period, and day-based discount rules (flat or percentage, with optional capping). Eligibility can be controlled per product line or per kiosk.
Create codes, manage eligibility, and retrieve code details.
See also: Product Lines · Kiosks
| organizationId required | number Organization ID | ||||||||||||||||||||
| code | string^\d{5}$ Custom 5-digit numeric code (auto-generated if omitted) | ||||||||||||||||||||
| quantity | number Number of codes to generate (1-100) | ||||||||||||||||||||
| balance | number Initial balance (number of uses) | ||||||||||||||||||||
| enabled | boolean | ||||||||||||||||||||
| workingDurationStart | string <date-time> Start date (ISO 8601). Defaults to now. | ||||||||||||||||||||
| workingDurationEnd | string <date-time> End date (ISO 8601). Mutually exclusive with durationEndDays. | ||||||||||||||||||||
| durationEndDays | number >= 1 Days from start until expiry. Mutually exclusive with workingDurationEnd. | ||||||||||||||||||||
Array of objects (PromocodeRuleInput) Discount rules per day of week. Creates a new config. Mutually exclusive with configId. | |||||||||||||||||||||
Array
| |||||||||||||||||||||
| configId | number Existing config ID to attach to. Mutually exclusive with rules. | ||||||||||||||||||||
{- "organizationId": 42
}{- "success": true,
- "promocodes": [
- {
- "id": 1,
- "code": "12345",
- "balance": 3,
- "enabled": true,
- "workingDurationStart": "2025-10-01T00:00:00.000Z",
- "workingDurationEnd": "2025-12-31T23:59:59.000Z",
- "organizationId": 42,
- "promocodeconfigId": 1
}
], - "configCreated": false,
- "errorMessage": "string"
}| organizationId required | number Organization ID |
| enabled required | boolean Enable or disable eligibility |
| productlineIds | Array of numbers Product line IDs to set eligibility for |
| kioskSerialNumber | string Kiosk serial number (set eligibility for all product lines in kiosk) |
| configId | number Specific promocode config ID (if org has multiple) |
| validTo | string <date-time> Eligibility expiry date (ISO 8601) |
{- "organizationId": 42,
- "enabled": true,
- "productlineIds": [
- 1,
- 2,
- 3
]
}{- "success": true,
- "affectedCount": 5
}| code required | string Example: 12345 5-digit numeric promocode |
{- "id": 1,
- "code": "12345",
- "balance": 3,
- "enabled": true,
- "workingDurationStart": "2026-07-01T00:00:00.000Z",
- "workingDurationEnd": "2026-12-31T23:59:59.000Z",
- "organizationId": 42,
- "config": {
- "id": 1,
- "enabled": true,
- "rules": [
- {
- "day": 1,
- "resetAmount": 3,
- "type": "percentage",
- "discountFlat": 0.5,
- "discountPercentage": 0.3,
- "cappingEnabled": true,
- "cappingFlat": 3,
- "cappingPercentage": 0,
- "minCart": -1,
- "description": "string"
}
]
}
}Revenue and sales performance analytics. Query time-series data (hourly, daily, weekly, monthly) or aggregate by product or kiosk. Includes top-selling kiosks and products rankings.
See also: Transactions · Kiosks · Products
Returns sales data. Use granularity for time-series, aggregateBy for product/kiosk aggregation.
| granularity required | string Enum: "hourly" "daily" "weekly" "monthly" Time granularity for grouping |
| aggregateBy | string Enum: "product" "kiosk" Aggregation dimension (omit for time-series) |
| kioskSerialNumber | string Filter to single kiosk (time-series mode) |
| kioskSerialNumbers | string Comma-separated kiosk filter (aggregateBy=kiosk) |
| startDate | string Period start (ISO 8601) |
| endDate | string Period end (ISO 8601) |
| x-timezone | string IANA timezone (default: Europe/Berlin) |
[- {
- "date": "2025-10-01T00:00:00",
- "productLineId": 42,
- "totalSales": 234.5,
- "totalNetSales": 197.06,
- "totalTax": 37.44,
- "totalCost": 120,
- "profit": 77.06
}
]| startDate | string Period start (ISO 8601) |
| endDate | string Period end (ISO 8601) |
| x-timezone | string IANA timezone |
[- {
- "rank": 1,
- "kioskSerialNumber": "LIV-0042",
- "kioskName": "Lobby Fridge",
- "netSales": 4523.5,
- "netCost": 2100,
- "profit": 2423.5
}
]| startDate | string Period start (ISO 8601) |
| endDate | string Period end (ISO 8601) |
| kioskSerialNumbers | string Comma-separated kiosk filter |
| x-timezone | string IANA timezone |
[- {
- "rank": 1,
- "productName": "Coca-Cola 0.33L",
- "manufacturer": "The Coca-Cola Company",
- "imageUrl": "string",
- "quantitySold": 342,
- "netSales": 513,
- "netCost": 240,
- "profit": 273
}
]Transaction-level KPIs and operational metrics — total transactions, average purchase value, daily profit, peak sales hours, payment type breakdown, and product lifecycle statistics (most sold, least sold, most refilled, most removed).
See also: Transactions · Analytics: Sales
| startDate | string Period start (ISO 8601) |
| endDate | string Period end (ISO 8601) |
| kioskSerialNumbers | string Comma-separated kiosk serial numbers |
| x-timezone | string IANA timezone |
{- "totalNumberOfTransactions": 1523,
- "averagePurchaseValue": 3.42,
- "totalNumberOfProductsSold": 2847,
- "totalNetIncome": 4382.5,
- "totalGrossIncome": 5215.18
}| startDate | string Period start (ISO 8601) |
| endDate | string Period end (ISO 8601) |
| kioskSerialNumbers | string Comma-separated kiosk serial numbers |
| x-timezone | string IANA timezone |
{- "start": "14:00",
- "end": "15:00",
- "sum": 47
}| startDate | string Period start (ISO 8601) |
| endDate | string Period end (ISO 8601) |
| kioskSerialNumbers | string Comma-separated kiosk serial numbers |
| x-timezone | string IANA timezone |
[- {
- "_id": "2025-10-01",
- "total_sales": 1234.56,
- "total_cost": 890.12,
- "profit": 344.44
}
]| startDate | string Period start (ISO 8601) |
| endDate | string Period end (ISO 8601) |
| kioskSerialNumbers | string Comma-separated kiosk serial numbers |
| x-timezone | string IANA timezone |
{- "visa": 423,
- "mastercard": 312,
- "girocard": 189,
- "otherCreditCard": 45,
- "membercard": 67,
- "other": 12
}| startDate | string Period start (ISO 8601) |
| endDate | string Period end (ISO 8601) |
| kioskSerialNumbers | string Comma-separated kiosk serial numbers |
| x-timezone | string IANA timezone |
{- "mostSoldProductMeta": {
- "productMetaId": 10,
- "productMetaName": "Coca-Cola 0.33L",
- "imageUrl": "string",
- "count": 142
}, - "leastSoldProductMeta": {
- "productMetaId": 10,
- "productMetaName": "Coca-Cola 0.33L",
- "imageUrl": "string",
- "count": 142
}, - "mostRefilledProductMeta": {
- "productMetaId": 10,
- "productMetaName": "Coca-Cola 0.33L",
- "imageUrl": "string",
- "count": 142
}, - "mostRemovedProductMeta": {
- "productMetaId": 10,
- "productMetaName": "Coca-Cola 0.33L",
- "imageUrl": "string",
- "count": 142
}
}Refill performance metrics — products added, products removed, spoilage rate, total restocking cost, and total sales value of restocked inventory.
See also: Refills · Analytics: Inventory
| startDate | string Period start (ISO 8601) |
| endDate | string Period end (ISO 8601) |
| kioskSerialNumbers | string Comma-separated kiosk serial numbers |
| x-timezone | string IANA timezone |
{- "totalNumberOfProductsAdded": 2456,
- "defaultTotalCostValueOfRefills": 3890.5,
- "totalNumberOfProductsRemoved": 123,
- "averageSpoilageRate": 0.05,
- "defaultTotalSalesValueOfRefills": 6120,
- "defaultTotalCostValueOfRemovedProducts": 195.5
}Inventory status reports — low/zero stock alerts across kiosks, and a product statistics grid with sold, refilled, and removed counts plus revenue and cost.
See also: Kiosks · Alerts · Analytics: Refills
| skip | number Example: skip=0 Pagination offset |
| limit | number Example: limit=25 Page size |
| kioskSerialNumbers | string Comma-separated kiosk filter |
| threshold | number Example: threshold=0 Inventory threshold (default: 0, products with qty <= threshold) |
| manufacturers | string Comma-separated manufacturer filter |
{- "total": 12,
- "data": [
- {
- "productName": "Coca-Cola 0.33L",
- "productlineProductMetaId": 10,
- "currentInventory": 0,
- "cableId": 3,
- "kioskName": "Lobby Fridge",
- "kioskSerialNumber": "LIV-0042",
- "kioskStatus": "string"
}
]
}| skip | number Example: skip=0 Pagination offset |
| limit | number Example: limit=25 Page size |
| startDate | string Filter start date (ISO 8601) |
| endDate | string Filter end date (ISO 8601) |
| kioskSerialNumbers | string Comma-separated kiosk filter |
| sortColumn | string Sort column (sold, refilled, removed, totalGrossSales, totalCost) |
| sortDirection | string ASC or DESC |
| includeZeroActivity | boolean Include products with no sales, refills, or removals in the window. Defaults to false. |
| x-timezone | string IANA timezone |
{- "total": 65,
- "data": [
- {
- "product": {
- "productMetaId": 10,
- "name": "Coca-Cola 0.33L",
- "imageUrl": "string",
- "defaultPrice": 1.5,
- "defaultCost": 0.85
}, - "totalCost": 890.12,
- "totalGrossSales": 1234.56,
- "totalRemovedCost": 45.5,
- "refilled": 1047,
- "sold": 892,
- "removed": 34
}
]
}Temperature telemetry from kiosk sensors. Query time-series data at various granularities (minutely, hourly, daily, weekly, monthly, or custom). Required for cold-chain compliance monitoring. Requires a specific kiosk serial number.
See also: Kiosks
| granularity required | string Enum: "minutely" "hourly" "daily" "weekly" "monthly" "custom" Temporal resolution |
| kioskSerialNumber required | string Kiosk serial number |
| startDate | string Period start (ISO 8601) |
| endDate | string Period end (ISO 8601) |
| grouping | string Enum: "minute" "hour" "day" "week" "month" Custom grouping (only for granularity=custom) |
| x-timezone | string IANA timezone |
[- {
- "sensorPosition": "top",
- "kioskName": "Lobby Fridge",
- "kioskSerial": "LIV-0042",
- "values": [
- {
- "timestamp": "2025-10-15T14:00:00.000Z",
- "temperature": 4.2
}
]
}
]