SmVend API Spec (1.0.0)

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].

Authentication

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.

apiAuth

Security Scheme Type: API Key
Header parameter name: x-organization-key

Controller

Management and retrieval of data for a specific controller

Get controller matrix

Authorizations:
apiAuth
Request Body schema: application/json
required
controllerId
required
string <uuid>

Controller ID in UUID v4 format

Responses

Request samples

Content type
application/json
{
  • "controllerId": "5a6d4d99-405d-4cf2-9840-bd718bfab2cb"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "result": {
    }
}

Update controller matrix

Authorizations:
apiAuth
Request Body schema: application/json
required
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

Responses

Request samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "columnsNumber": 0,
  • "rowsNumber": 0,
  • "products": [
    ],
  • "resources": [
    ]
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "result": {
    }
}

Send deposit to controller

Authorizations:
apiAuth
Request Body schema: application/json
required
controllerId
required
string <uuid>

Controller ID in UUID v4 format

deposit
required
number

Deposit in cents

Responses

Request samples

Content type
application/json
{
  • "controllerId": "5a6d4d99-405d-4cf2-9840-bd718bfab2cb",
  • "deposit": 0
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "result": {
    }
}

Issue product

Authorizations:
apiAuth
Request Body schema: application/json
required
controllerId
required
string
position
required
number

Responses

Request samples

Content type
application/json
{
  • "controllerId": "string",
  • "position": 0
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "result": {
    }
}

Send remote payment to controller

Authorizations:
apiAuth
Request Body schema: application/json
required
controllerId
required
string <uuid>

Controller ID in UUID v4 format

amount
required
number

Payment value in cents

Responses

Request samples

Content type
application/json
{
  • "controllerId": "5a6d4d99-405d-4cf2-9840-bd718bfab2cb",
  • "amount": 0
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "result": {
    }
}

Get controller config

Authorizations:
apiAuth
Request Body schema: application/json
required
controllerId
required
string <uuid>

Controller ID in UUID v4 format

Responses

Request samples

Content type
application/json
{
  • "controllerId": "5a6d4d99-405d-4cf2-9840-bd718bfab2cb"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "result": {
    }
}

Update controller config

It is recommended to send only the modified values in the config property.

Authorizations:
apiAuth
Request Body schema: application/json
required
Any of
type
required
string
Value: "coffee"
controllerConfigId
required
string <uuid>

Config ID in UUID v4 format (!= controller id)

required
object

Coffee command config

Responses

Request samples

Content type
application/json
{
  • "type": "impulse",
  • "controllerConfigId": "da980242-b70d-44f0-9baf-a5b2a9fd72b9",
  • "config": {
    }
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "result": {
    }
}

Get controller state

Authorizations:
apiAuth
Request Body schema: application/json
required
controllerId
required
string <uuid>

Controller ID in UUID v4 format

Responses

Request samples

Content type
application/json
{
  • "controllerId": "5a6d4d99-405d-4cf2-9840-bd718bfab2cb"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "result": {
    }
}

Get controller connection status

Authorizations:
apiAuth
Request Body schema: application/json
required
controllerId
required
string <uuid>

Controller ID in UUID v4 format

Responses

Request samples

Content type
application/json
{
  • "controllerId": "5a6d4d99-405d-4cf2-9840-bd718bfab2cb"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "result": {
    }
}

Reports

Requests for report retrieval

Get list of controllers

Authorizations:
apiAuth
Request Body schema: application/json
required
^(.*)$
pattern property
any

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{
  • "id": "string",
  • "result": {
    }
}

Get list of sales

Authorizations:
apiAuth
Request Body schema: application/json
required
required
object

Pagination object

required
object

The time range for which the data needs to be retrieved

required
object

Controller filters

object

Sort object

Responses

Request samples

Content type
application/json
{
  • "pagination": {
    },
  • "dateRange": {
    },
  • "filters": {
    },
  • "sort": {
    }
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "result": {
    }
}

Get list of events

Authorizations:
apiAuth
Request Body schema: application/json
required
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

Responses

Request samples

Content type
application/json
{
  • "pagination": {
    },
  • "filters": {
    },
  • "status": "relevant",
  • "level": "info",
  • "source": "user",
  • "dateRange": {
    }
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "result": {
    }
}

Get list of products

Authorizations:
apiAuth
Request Body schema: application/json
required
archive
boolean

Filter products by archived status.

Responses

Request samples

Content type
application/json
{
  • "archive": true
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "result": {
    }
}

Get dictionary of events

Authorizations:
apiAuth
Request Body schema: application/json
required
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)

Responses

Request samples

Content type
application/json
{
  • "language": "en"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "result": {
    }
}

Encashment

Retrieving a list of encashments and creating an encashment

Get encashments list

Authorizations:
apiAuth
Request Body schema: application/json
required
required
object

Pagination object

required
object

The time range for which the data needs to be retrieved

required
object
object

Sort object

Responses

Request samples

Content type
application/json
{
  • "pagination": {
    },
  • "dateRange": {
    },
  • "filters": {
    },
  • "sort": {
    }
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "result": {
    }
}

Create encashment

Authorizations:
apiAuth
Request Body schema: application/json
required
controllerId
required
string <uuid>

Controller ID in UUID v4 format

Responses

Request samples

Content type
application/json
{
  • "controllerId": "5a6d4d99-405d-4cf2-9840-bd718bfab2cb"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "result": {
    }
}

Webhooks

Description

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.

The retry system is as follows

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.

Webhook authentication

To set up and use webhooks with signature verification in the SmVend application, follow these steps:

Key Pair Generation

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.

Signature Verification

To verify the signature of incoming webhook requests, follow these steps:

  • When your application receives a webhook request, it will contain a header x-signature with the signature of the request body.
  • Sort the JSON body of the request to ensure consistent ordering. This involves recursively sorting all keys and values in the JSON object to ensure that the structure is consistent for signing and verification.
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);
 }
};
  • Use the public key to verify the signature provided in the x-signature header against the sorted JSON body. The verify method in the example is used from the crypto library for JavaScript
 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');
 };

Event Webhook

Webhook for Event Creation Controller Event

Request Body schema: application/json
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)

Responses

Request samples

Content type
application/json
{
  • "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"
}

Sale Webhook

Webhook for Sale Creation Event

Request Body schema: application/json
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

Responses

Request samples

Content type
application/json
{
  • "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": [
    ],
  • "quantity": 0,
  • "totalPrice": "string",
  • "income": "string",
  • "change": "string",
  • "products": [
    ]
}