Download OpenAPI specification:Download
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 Controller ID in UUID v4 format |
{- "controllerId": "string"
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": {
- "id": "string",
- "columnsNumber": 0,
- "rowsNumber": 0,
- "products": [
- {
- "columnNumber": 0,
- "rowNumber": 0,
- "productId": "string",
- "price": 0
}
], - "resources": [
- {
- "resourceId": "string",
- "maxRefillQuantity": 0
}
]
}
}
}
id required | string Controller matrix ID in UUID v4 format (!= controller id) |
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": "string",
- "columnsNumber": 0,
- "rowsNumber": 0,
- "products": [
- {
- "columnNumber": 0,
- "rowNumber": 0,
- "productId": "string",
- "price": 0
}
], - "resources": [
- {
- "resourceId": "string",
- "maxRefillQuantity": 0
}
]
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": {
- "success": true
}
}
}
controllerId required | string Controller ID in UUID v4 format |
deposit required | number Deposit in cents |
{- "controllerId": "string",
- "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 Controller ID in UUID v4 format |
amount required | number Payment value in cents |
{- "controllerId": "string",
- "amount": 0
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": { }
}
}
controllerId required | string Controller ID in UUID v4 format |
{- "controllerId": "string"
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": {
- "type": "coffee",
- "controllerConfigId": "string",
- "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": 1,
- "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": "string"
}, - "pendingChangeConfigCommand": {
- "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,
- "2b": true,
- "cp": true,
- "bb": true,
- "vg": true,
- "vl": true,
- "qr": true,
- "n1": 0,
- "n2": 0,
- "t1": 0,
- "t0": 0,
- "qt": 0,
- "2a": 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"
}
}
}
}
}
It is recommended to send only the modified values in the config
property.
type required | string Value: "coffee" |
controllerConfigId required | string Config ID in UUID v4 format (!= controller id) |
required | object Coffee command config |
{- "type": "impulse",
- "controllerConfigId": "string",
- "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,
- "2b": true,
- "cp": true,
- "bb": true,
- "vg": true,
- "vl": true,
- "qr": true,
- "n1": 0,
- "n2": 0,
- "t1": 0,
- "t0": 0,
- "qt": 0,
- "2a": 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"
}
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": { }
}
}
controllerId required | string Controller ID in UUID v4 format |
{- "controllerId": "string"
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": {
- "type": "coffee",
- "data": {
- "id": "string",
- "controllerId": "string",
- "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": "string",
- "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
}
}
}
}
controllerId required | string Controller ID in UUID v4 format |
{- "controllerId": "string"
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": {
- "connectionStatus": "online",
- "lastActive": { }
}
}
}
{ }
{- "id": "string",
- "result": {
- "$case": "success",
- "success": [
- {
- "id": "string",
- "serialNumber": "string",
- "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": [
- "string"
], - "controllerConnectionStatus": "online",
- "groupIds": [
- "string"
], - "searchString": "string"
}, - "sort": {
- "field": "controllerSerialNumber",
- "direction": -1
}
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": {
- "items": [
- {
- "controllerId": "string",
- "controllerHumanName": "string",
- "controllerSerialNumber": "string",
- "controllerType": "coffee",
- "controllerLocation": "string",
- "controllerConnectionStatus": "online",
- "insertedMoney": "string",
- "bill": "string",
- "coin": "string",
- "digital": "string",
- "remotePayment": "string",
- "remoteDeposit": "string",
- "controllerTimezone": "string",
- "saleId": "string",
- "controllerCreatedAt": 0,
- "createdAt": 0,
- "paymentTypes": [
- "cash"
], - "quantity": 0,
- "totalPrice": "string",
- "income": "string",
- "change": "string",
- "products": [
- {
- "id": "string",
- "name": "string",
- "quantity": 0
}
], - "receipts": [
- {
- "status": "pending",
- "failedReason": "string",
- "successData": { },
- "type": "sale"
}
], - "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": [
- "string"
], - "controllerConnectionStatus": "online",
- "groupIds": [
- "string"
], - "searchString": "string"
}, - "status": "relevant",
- "level": "info",
- "source": "user",
- "dateRange": {
- "from": 0,
- "to": 0
}
}
{- "id": "string",
- "result": {
- "$case": "success",
- "success": {
- "items": [
- {
- "id": "string",
- "controllerId": "string",
- "controllerType": "coffee",
- "controllerConnectionStatus": "online",
- "controllerLocation": "string",
- "controllerSerialNumber": "string",
- "controllerTimezone": "string",
- "controllerHumanName": "string",
- "controllerCreatedAt": 0,
- "createdAt": 0,
- "tag": "string",
- "code": "string",
- "localizeKey": "string",
- "source": "user",
- "status": "relevant",
- "level": "info",
- "webhookActionExists": true
}
], - "total": 0
}
}
}
{ }
{- "id": "string",
- "result": {
- "$case": "success",
- "success": [
- {
- "id": "string",
- "name": "string",
- "type": "goods",
- "externalId": "string",
- "vatValue": 0,
- "resources": [
- {
- "id": "string",
- "name": "string",
- "unit": "string",
- "quantity": 0
}
]
}
]
}
}
required | "en" (string) or "es" (string) or "de" (string) or "fr" (string) or "ru" (string) |
{- "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": [
- "string"
], - "controllerConnectionStatus": "online",
- "groupIds": [
- "string"
], - "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": "string",
- "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 Controller ID in UUID v4 format |
{- "controllerId": "string"
}
{- "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
id required | string |
controllerId required | string |
required | "coffee" (string) or "impulse" (string) Controller type (coffee or impulse) |
required | string or null Controller location (address) |
controllerSerialNumber required | string Serial number of the controller |
controllerTimezone required | string Timezone of the controller |
controllerHumanName required | string Human name of the controller |
controllerCreatedAt required | number The timestamp (UNIX) of when the entity was created on the controller. |
createdAt required | number The timestamp (UNIX) of the server processing time. |
tag required | string Tag of the event |
code required | string Code of the event |
localizeKey required | string Localize key (i18n) of the event |
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) |
{- "id": "string",
- "controllerId": "string",
- "controllerType": "coffee",
- "controllerLocation": "string",
- "controllerSerialNumber": "string",
- "controllerTimezone": "string",
- "controllerHumanName": "string",
- "controllerCreatedAt": 0,
- "createdAt": 0,
- "tag": "string",
- "code": "string",
- "localizeKey": "string",
- "source": "user",
- "status": "relevant",
- "level": "info"
}
Webhook for Sale Creation Event
controllerId required | string Controller ID in UUID v4 format |
controllerHumanName required | string Controller human name |
controllerSerialNumber required | string Controller serial number |
required | "coffee" (string) or "impulse" (string) Controller type (coffee or impulse) |
required | string or null Controller location (address) |
insertedMoney required | string Inserted money |
bill required | string Bill |
coin required | string Coin |
digital required | string Digital (card, electron payment) |
remotePayment required | string Remote payment |
remoteDeposit required | string Remote deposit |
controllerTimezone required | string Controller timezone |
saleId required | string Sale ID in UUID format |
controllerCreatedAt required | number The timestamp (UNIX) of when the entity was created on the controller. |
createdAt required | number The timestamp (UNIX) of the server processing time. |
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": "string",
- "controllerHumanName": "string",
- "controllerSerialNumber": "string",
- "controllerType": "coffee",
- "controllerLocation": "string",
- "insertedMoney": "string",
- "bill": "string",
- "coin": "string",
- "digital": "string",
- "remotePayment": "string",
- "remoteDeposit": "string",
- "controllerTimezone": "string",
- "saleId": "string",
- "controllerCreatedAt": 0,
- "createdAt": 0,
- "paymentTypes": [
- "cash"
], - "quantity": 0,
- "totalPrice": "string",
- "income": "string",
- "change": "string",
- "products": [
- {
- "id": "string",
- "name": "string",
- "quantity": 0,
- "externalId": "string",
- "position": 0
}
]
}