Download OpenAPI specification:
This is the first version of the SmVend service API. The documentation will be continuously updated and improved, but we will maintain backward compatibility with all previously published API versions. If you have discovered any errors or inaccuracies in the documentation, please email us at [email protected].
In the current version of the API, authentication is implemented using the x-organization-key
parameter in the request headers. You can obtain this key from the Settings -> Integration -> API section of your SmVend account's.
x-organization-key
is the publicKey property from the pair of generated keys.
In the future, we will add request signing for additional security in API interactions.
If you want to get data for a specific user, pass the user ID in the x-user-id
header.
controllerId required | string <uuid> Controller ID in UUID v4 format |
{- "controllerId": "5a6d4d99-405d-4cf2-9840-bd718bfab2cb"
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "columnsNumber": 0,
- "rowsNumber": 0,
- "products": [
- {
- "columnNumber": 0,
- "rowNumber": 0,
- "productId": "dcd53ddb-8104-4e48-8cc0-5df1088c6113",
- "price": 0
}
], - "resources": [
- {
- "resourceId": "026d60bb-63a8-407e-bf67-01dcfc6022e6",
- "maxRefillQuantity": 0
}
]
}
}
}
id required | string <uuid> Identifier of the controller matrix (ControllerMatrixId). |
columnsNumber required | number Number of columns in matrix |
rowsNumber required | number Number of rows in matrix |
required | Array of objects Products in matrix |
required | Array of objects An array of the maximum number of ingredients from the products of the matrix |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "columnsNumber": 0,
- "rowsNumber": 0,
- "products": [
- {
- "columnNumber": 0,
- "rowNumber": 0,
- "price": 0,
- "productId": "dcd53ddb-8104-4e48-8cc0-5df1088c6113"
}
], - "resources": [
- {
- "resourceId": "026d60bb-63a8-407e-bf67-01dcfc6022e6",
- "maxRefillQuantity": 0
}
]
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": {
- "success": true
}
}
}
controllerId required | string <uuid> Controller ID in UUID v4 format |
deposit required | number Deposit in cents |
{- "controllerId": "5a6d4d99-405d-4cf2-9840-bd718bfab2cb",
- "deposit": 0
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": {
- "success": true
}
}
}
controllerId required | string |
position required | number |
{- "controllerId": "string",
- "position": 0
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": {
- "success": true
}
}
}
controllerId required | string <uuid> Controller ID in UUID v4 format |
amount required | number Payment value in cents |
{- "controllerId": "5a6d4d99-405d-4cf2-9840-bd718bfab2cb",
- "amount": 0
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": { }
}
}
controllerId required | string <uuid> Controller ID in UUID v4 format |
{- "controllerId": "5a6d4d99-405d-4cf2-9840-bd718bfab2cb"
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": {
- "type": "coffee",
- "controllerConfigId": "da980242-b70d-44f0-9baf-a5b2a9fd72b9",
- "config": {
- "re": true,
- "in": true,
- "hl": true,
- "bp": true,
- "qr": true,
- "2f": true,
- "2c": "string",
- "vg": true,
- "vl": true,
- "th": 0,
- "sm": 0,
- "bm": 0,
- "em": 0,
- "cd": 0,
- "cf": 0,
- "qt": 0,
- "da": true,
- "2a": 0,
- "2r": "string",
- "2e": 0,
- "2l": "string",
- "2p": "string",
- "2t": 0,
- "vt": 0,
- "vr": 0,
- "tt": 0,
- "td": "stri",
- "ti": 0,
- "tg": 0,
- "ft": 0,
- "fc": 0,
- "wf": "string",
- "wn": "string",
- "wp": "string",
- "wt": "string",
- "an": "string",
- "al": "string",
- "ap": "string",
- "sa": "string",
- "sp": 0,
- "pt": 0,
- "mv": true,
- "ss": 0,
- "2m": 0,
- "ha": "string",
- "hp": "string",
- "co": true,
- "1a": "string",
- "1l": true,
- "1t": true,
- "1w": true,
- "3a": "string",
- "3p": "string"
}, - "pendingChangeConfigCommand": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "customData": {
- "controllerType": "impulse",
- "delta": {
- "tm": true,
- "hm": true,
- "dl": true,
- "dc": true,
- "re": true,
- "in": true,
- "hl": true,
- "ib": true,
- "ip": true,
- "ss": true,
- "ai": true,
- "dr": true,
- "2a": 0,
- "2b": true,
- "cp": true,
- "bb": true,
- "vl": true,
- "vg": true,
- "qr": true,
- "n1": 0,
- "n2": 0,
- "t1": 0,
- "t0": 0,
- "qt": 0,
- "2e": 0,
- "ps": 0,
- "p1": 0,
- "p2": 0,
- "p3": 0,
- "bt": 0,
- "b1": 0,
- "b2": 0,
- "b3": 0,
- "2l": "string",
- "2p": "string",
- "wn": "string",
- "wp": "string",
- "an": "string",
- "al": "string",
- "ap": "string",
- "2f": true,
- "2c": "string",
- "2m": 0,
- "nc": true,
- "ha": "string",
- "hp": "string",
- "f3": 0,
- "3a": "string",
- "3p": "string"
}
}
}
}
}
}
It is recommended to send only the modified values in the config
property.
type required | string Value: "coffee" |
controllerConfigId required | string <uuid> Config ID in UUID v4 format (!= controller id) |
required | object Coffee command config |
{- "type": "impulse",
- "controllerConfigId": "da980242-b70d-44f0-9baf-a5b2a9fd72b9",
- "config": {
- "tm": true,
- "hm": true,
- "dl": true,
- "dc": true,
- "re": true,
- "in": true,
- "hl": true,
- "ib": true,
- "ip": true,
- "ss": true,
- "ai": true,
- "dr": true,
- "2a": 0,
- "2b": true,
- "cp": true,
- "bb": true,
- "vl": true,
- "vg": true,
- "qr": true,
- "n1": 0,
- "n2": 0,
- "t1": 0,
- "t0": 0,
- "qt": 0,
- "2e": 0,
- "ps": 0,
- "p1": 0,
- "p2": 0,
- "p3": 0,
- "bt": 0,
- "b1": 0,
- "b2": 0,
- "b3": 0,
- "2l": "string",
- "2p": "string",
- "wn": "string",
- "wp": "string",
- "an": "string",
- "al": "string",
- "ap": "string",
- "2f": true,
- "2c": "string",
- "2m": 0,
- "nc": true,
- "ha": "string",
- "hp": "string",
- "f3": 0,
- "3a": "string",
- "3p": "string"
}
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": { }
}
}
controllerId required | string <uuid> Controller ID in UUID v4 format |
{- "controllerId": "5a6d4d99-405d-4cf2-9840-bd718bfab2cb"
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": {
- "type": "coffee",
- "data": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "controllerId": "5a6d4d99-405d-4cf2-9840-bd718bfab2cb",
- "connectionStatus": "online",
- "connectionStatusUpdatedAt": 0,
- "createdAt": 0,
- "updatedAt": 0,
- "t0": 0,
- "t0UpdatedAt": 0,
- "t1": 0,
- "t1UpdatedAt": 0,
- "t2": 0,
- "t2UpdatedAt": 0,
- "t3": 0,
- "t3UpdatedAt": 0,
- "t4": 0,
- "t4UpdatedAt": 0,
- "t5": 0,
- "t5UpdatedAt": 0,
- "t6": 0,
- "t6UpdatedAt": 0,
- "t7": 0,
- "t7UpdatedAt": 0,
- "t8": 0,
- "t8UpdatedAt": 0,
- "t9": 0,
- "t9UpdatedAt": 0,
- "tA": 0,
- "tAUpdatedAt": 0,
- "tB": 0,
- "tBUpdatedAt": 0,
- "tC": 0,
- "tCUpdatedAt": 0,
- "tD": 0,
- "tDUpdatedAt": 0,
- "tE": 0,
- "tEUpdatedAt": 0,
- "tF": 0,
- "tFUpdatedAt": 0,
- "boot": 0,
- "bootUpdatedAt": 0,
- "imei": "string",
- "imeiUpdatedAt": 0,
- "on": "string",
- "onUpdatedAt": 0,
- "ccid": "string",
- "ccidUpdatedAt": 0,
- "sg": 0,
- "sgUpdatedAt": 0,
- "dhcp": "string",
- "dhcpUpdatedAt": 0,
- "git": "string",
- "gitUpdatedAt": 0,
- "s0": 0,
- "s0UpdatedAt": 0,
- "s1": 0,
- "s1UpdatedAt": 0,
- "s2": 0,
- "s2UpdatedAt": 0,
- "s3": 0,
- "s3UpdatedAt": 0,
- "min": 0,
- "minUpdatedAt": 0,
- "avg": 0,
- "avgUpdatedAt": 0,
- "max": 0,
- "maxUpdatedAt": 0,
- "lastOnline": 0,
- "lastOnlineUpdatedAt": 0,
- "er": true,
- "erUpdatedAt": 0,
- "brst": true,
- "brstUpdatedAt": 0,
- "eth": true,
- "ethUpdatedAt": 0,
- "gq": 0,
- "gqUpdatedAt": 0,
- "gi": 0,
- "giUpdatedAt": 0,
- "pq": 0,
- "pqUpdatedAt": 0,
- "bc": 0,
- "bcUpdatedAt": 0,
- "bs": 0,
- "bsUpdatedAt": 0,
- "mc": 0,
- "mcUpdatedAt": 0,
- "ms": 0,
- "msUpdatedAt": 0,
- "dc": 0,
- "dcUpdatedAt": 0,
- "ob": 0,
- "obUpdatedAt": 0,
- "ps": 0,
- "psUpdatedAt": 0,
- "tc": 0,
- "tcUpdatedAt": 0,
- "ga": 0,
- "gaUpdatedAt": 0,
- "pa": 0,
- "paUpdatedAt": 0,
- "fs": "f",
- "fsUpdatedAt": 0,
- "im": "string",
- "imUpdatedAt": 0,
- "ib": "string",
- "ibUpdatedAt": 0,
- "ic": "string",
- "icUpdatedAt": 0
}
}
}
}
controllerId required | string <uuid> Controller ID in UUID v4 format |
{- "controllerId": "5a6d4d99-405d-4cf2-9840-bd718bfab2cb"
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": {
- "connectionStatus": "online",
- "lastActive": { }
}
}
}
^(.*)$ pattern property | any |
{ }
{- "id": "string",
- "result": {
- "$case": "success",
- "success": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "serialNumber": "148d7a56-176d-413b-9eb5-c62f6f5bb67a",
- "humanName": "string"
}
]
}
}
required | object Pagination object |
required | object The time range for which the data needs to be retrieved |
required | object Controller filters |
object Sort object |
{- "pagination": {
- "currentPage": 1,
- "perPage": 1
}, - "dateRange": {
- "from": 0,
- "to": 0
}, - "filters": {
- "paymentTypes": [
- "cash"
], - "fiscalizedStatus": "all",
- "controllerIds": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
], - "collaboratorIds": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
], - "controllerConnectionStatus": "online",
- "groupIds": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
], - "searchString": "string"
}, - "sort": {
- "field": "controllerSerialNumber",
- "direction": -1
}
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": {
- "items": [
- {
- "controllerId": "5a6d4d99-405d-4cf2-9840-bd718bfab2cb",
- "controllerHumanName": "string",
- "controllerSerialNumber": "d0c5ce0d-9dcd-4a0f-a616-b17107be115d",
- "controllerType": "coffee",
- "controllerLocation": "string",
- "controllerConnectionStatus": "online",
- "insertedMoney": "string",
- "bill": "string",
- "coin": "string",
- "digital": "string",
- "remotePayment": "string",
- "remoteDeposit": "string",
- "controllerTimezone": "Europe/Lisbon",
- "saleId": "2bab4348-b09e-4b08-a600-8273f0d2907f",
- "controllerCreatedAt": 0,
- "createdAt": 0,
- "paymentTypes": [
- "cash"
], - "quantity": 0,
- "totalPrice": "string",
- "income": "string",
- "change": "string",
- "products": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "quantity": 0
}
], - "receipts": [
- {
- "status": "pending",
- "failedReason": "string",
- "successData": { },
- "type": "sale"
}
], - "shouldBeFiscalized": true,
- "webhookActionExists": true,
- "canceled": true
}
], - "total": 0
}
}
}
required | object Pagination object |
required | object |
"relevant" (string) or "irrelevant" (string) Event status (relevant or irrelevant) | |
"info" (string) or "warning" (string) or "danger" (string) Event level (info, warning, danger) | |
"user" (string) or "controller" (string) Event source type (user or controller) | |
required | object The time range for which the data needs to be retrieved |
{- "pagination": {
- "currentPage": 1,
- "perPage": 1
}, - "filters": {
- "controllerIds": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
], - "collaboratorIds": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
], - "controllerConnectionStatus": "online",
- "groupIds": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
], - "searchString": "string"
}, - "status": "relevant",
- "level": "info",
- "source": "user",
- "dateRange": {
- "from": 0,
- "to": 0
}
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": {
- "items": [
- {
- "controllerId": "5a6d4d99-405d-4cf2-9840-bd718bfab2cb",
- "controllerHumanName": "string",
- "controllerSerialNumber": "d0c5ce0d-9dcd-4a0f-a616-b17107be115d",
- "controllerType": "coffee",
- "controllerLocation": "string",
- "controllerConnectionStatus": "online",
- "id": null,
- "controllerTimezone": "Europe/Lisbon",
- "createdAt": 0,
- "controllerCreatedAt": 0,
- "tag": "string",
- "code": "string",
- "localizeKey": "string",
- "source": "user",
- "status": "relevant",
- "level": "info",
- "webhookActionExists": true
}
], - "total": 0
}
}
}
archive | boolean Filter products by archived status. |
{- "archive": true
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "type": "goods",
- "externalId": "string",
- "vatValue": 0,
- "resources": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "unit": "string",
- "quantity": 0
}
]
}
]
}
}
required | "en" (string) or "pt" (string) or "es" (string) or "de" (string) or "fr" (string) or "ru" (string) Language code (en, pt, es, de, fr, ru) |
{- "language": "en"
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": {
- "dictionary": { }
}
}
}
required | object Pagination object |
required | object The time range for which the data needs to be retrieved |
required | object |
object Sort object |
{- "pagination": {
- "currentPage": 1,
- "perPage": 1
}, - "dateRange": {
- "from": 0,
- "to": 0
}, - "filters": {
- "controllerIds": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
], - "collaboratorIds": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
], - "controllerConnectionStatus": "online",
- "groupIds": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
], - "searchString": "string"
}, - "sort": {
- "field": "controllerSerialNumber",
- "direction": -1
}
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": {
- "items": [
- {
- "coin": "string",
- "bill": "string",
- "controllerSerialNumber": "string",
- "controllerHumanName": "string",
- "controllerCreatedAt": 0,
- "createdAt": 0,
- "controllerConnectionStatus": "online",
- "controllerId": "5a6d4d99-405d-4cf2-9840-bd718bfab2cb",
- "controllerType": "coffee",
- "controllerLocation": { },
- "insertedMoney": "string",
- "digital": "string",
- "remotePayment": "string",
- "remoteDeposit": "string",
- "paymentTypes": { },
- "totalPrice": "string",
- "income": "string",
- "quantity": 0,
- "cashboxId": { },
- "controllerTimezone": "string",
- "saleId": "string",
- "change": "string",
- "products": [
- {
- "name": "string",
- "id": "string",
- "quantity": 0
}
], - "fiscalizationStatus": { },
- "fiscalizationFailedReason": { },
- "fiscalizationSuccess": { }
}
], - "total": 0
}
}
}
controllerId required | string <uuid> Controller ID in UUID v4 format |
{- "controllerId": "5a6d4d99-405d-4cf2-9840-bd718bfab2cb"
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": { }
}
}
Webhooks are a method used to automatically send real-time data from the SmVend application to an integrated application when a specific event occurs.
When an event happens in the SmVend application, it triggers an HTTP POST request to a predefined URL specified in the Settings -> Integration -> Webhooks section of the SmVend application.
Any response to a webhook with a status code of 200 is considered successful.
If, for any reason, the integrated application responds with any other status code, the SmVend application will attempt to resend the requests after 1 minute, 5 minutes, 10 minutes, 30 minutes, 2 hours, and 5 hours.
If a response with a status code of 200 is not received after 6 attempts, the SmVend application will stop sending webhooks.
To set up and use webhooks with signature verification in the SmVend application, follow these steps:
Open the SmVend application, go Settings -> Integration -> Webhooks section.
In the Webhooks section, generate an RSA key pair. This typically involves creating a public and private key that will be used for signing and verifying webhook requests.
To verify the signature of incoming webhook requests, follow these steps:
const createDeepSortedJSONString = (data: any): string => {
if (Array.isArray(data)) {
return JSON.stringify(data.map(item => JSON.parse(createDeepSortedJSONString(item))));
} else if (typeof data === 'object' && data !== null) {
const sortedData = Object.keys(data)
.sort()
.reduce((result: Record<string, any>, key: string) => {
result[key] = JSON.parse(createDeepSortedJSONString(data[key]));
return result;
}, {});
return JSON.stringify(sortedData);
} else {
return JSON.stringify(data);
}
};
const verifySignature = (body: string, signature: string, publicKey: string): boolean => {
const publicKeyBuffer = Buffer.from(publicKeyHex, 'hex');
return verify(
null,
Buffer.from(body),
{
key: publicKeyBuffer,
format: 'der',
type: 'spki',
},
Buffer.from(signature, 'base64')
);
}
const requestBody = { /* received request body */ };
const sortedRequestBody = createDeepSortedJSONString(requestBody);
const signature = req.headers['x-signature']; // assuming express.js
const isSignatureValid = verifySignature(sortedRequestBody, signature, publicKey);
if (isSignatureValid) {
console.log('Signature is valid');
} else {
console.log('Invalid signature');
};
Webhook for Event Creation Controller Event
controllerId required | string <uuid> Controller ID in UUID v4 format |
controllerHumanName required | string Human-readable name assigned to the controller. |
controllerSerialNumber required | string <uuid> The serial number of the controller. |
required | "coffee" (string) or "impulse" (string) Controller type (coffee or impulse) |
required | string or null Controller location (address) |
id required | any <uuid> Controller event ID in UUID v4 format |
controllerTimezone required | any The timezone of the user. |
createdAt required | number The timestamp (UNIX) of when the entity was created. |
controllerCreatedAt required | number The timestamp (UNIX) of when the entity was created on the controller. |
tag required | string Event tag (Char32). |
code required | string Event code (Char32). |
localizeKey required | string Localization key for the event message. |
required | "user" (string) or "controller" (string) Event source type (user or controller) |
required | "relevant" (string) or "irrelevant" (string) Event status (relevant or irrelevant) |
required | "info" (string) or "warning" (string) or "danger" (string) Event level (info, warning, danger) |
{- "controllerId": "5a6d4d99-405d-4cf2-9840-bd718bfab2cb",
- "controllerHumanName": "string",
- "controllerSerialNumber": "d0c5ce0d-9dcd-4a0f-a616-b17107be115d",
- "controllerType": "coffee",
- "controllerLocation": "string",
- "id": null,
- "controllerTimezone": "Europe/Lisbon",
- "createdAt": 0,
- "controllerCreatedAt": 0,
- "tag": "string",
- "code": "string",
- "localizeKey": "string",
- "source": "user",
- "status": "relevant",
- "level": "info"
}
Webhook for Sale Creation Event
controllerId required | string <uuid> Controller ID in UUID v4 format |
controllerHumanName required | string Human-readable name assigned to the controller. |
controllerSerialNumber required | string <uuid> The serial number of the controller. |
required | "coffee" (string) or "impulse" (string) Controller type (coffee or impulse) |
required | string or null Controller location (address) |
insertedMoney required | string Total inserted money (bill + coin + digital + remotePayment + remoteDeposit). |
bill required | string Bill amount. |
coin required | string Coin amount. |
digital required | string Digital payment amount. |
remotePayment required | string Remote payment amount. |
remoteDeposit required | string Remote deposit amount. |
controllerTimezone required | any The timezone of the user. |
saleId required | string <uuid> Identifier of the sale (SaleId). |
controllerCreatedAt required | number The timestamp (UNIX) of when the entity was created on the controller. |
createdAt required | number The timestamp (UNIX) of when the entity was created. |
required | (Array of "cash" (string) or "electronic" (string) or "coin" (string) or "remote-deposit" (string) or "remote-payment" (string)) or null |
quantity required | number Total quantity of products in sale |
totalPrice required | string Total price of sale (in cents) |
income required | string Total income of sale (in cents) |
change required | string Total change of sale (in cents) |
required | Array of objects |
{- "controllerId": "5a6d4d99-405d-4cf2-9840-bd718bfab2cb",
- "controllerHumanName": "string",
- "controllerSerialNumber": "d0c5ce0d-9dcd-4a0f-a616-b17107be115d",
- "controllerType": "coffee",
- "controllerLocation": "string",
- "insertedMoney": "string",
- "bill": "string",
- "coin": "string",
- "digital": "string",
- "remotePayment": "string",
- "remoteDeposit": "string",
- "controllerTimezone": "Europe/Lisbon",
- "saleId": "2bab4348-b09e-4b08-a600-8273f0d2907f",
- "controllerCreatedAt": 0,
- "createdAt": 0,
- "paymentTypes": [
- "cash"
], - "quantity": 0,
- "totalPrice": "string",
- "income": "string",
- "change": "string",
- "products": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "quantity": 0,
- "externalId": "string",
- "position": 0
}
]
}