FORMAT: 1A HOST: https://checkout-clients-live-eu.qnips.com/ # qnips Checkout API Welcome to the **qnips Checkout API**. This API provides access to the checkout service. *** **ATTENTION** This documentation is still under development. Breaking changes and updates can be expected throughout the v1 version. *** # General information From here on, we'll refer to the qnips Checkout API simply as the "API". ## Environments The API is available in two separate environments: * **Live environment:** used for production traffic and real customer data. * **Sandbox environment:** used for development, testing and integration. Each environment exposes the same API structure and functionality but differs in data persistence, rate limits, and operational guarantees. ### Environment URLs Environment | Base URL ---|--- **Live** | https://checkout-clients-live-eu.qnips.com **Sandbox** | https://checkout-clients-sandbox-eu.qnips.com Accessing a different environment only requires changing the base URL and using the appropriate authorization details. No code changes should be required if your integration follows the API contract consistently. ## Requests All requests to the API **must** be performed over secure transport channels. All requests should use the HTTPS protocol and a minimum TLS version of 1.2. + Requests made over HTTP will be **redirected** to HTTPS. + Requests using deprecated TLS versions are **rejected**. All requests to the API **must** follow the conventions below. *** ### API versioning The API is versioned to allow backward-incompatible changes without breaking existing clients. Upgrading to a new version can require updates to existing code. Each API version is exposed through a dedicated URI path. When sending requests to the API, the client must specify the API version directly in the request URI: `GET {baseUrl}/api/v1/{resource}` **Clients should:** + Periodically review version deprecation notices. + Test integrations against newer versions. + Plan migrations early to avoid disruption. *** ### Authorization Header All requests to protected endpoints **must** provide one of the supported `Authorization` headers: Schema | Example ---|--- **Basic** | `Authorization: Basic :)>` **ApiKey** | `Authorization: ApiKey ` **Token** | `Authorization: Token ` Please check the API reference and examples, to pick the right schema for the right resource. *** ### Idempotency Idempotency ensures that performing the same API request multiple times results in the same outcome as performing it once. This mechanism protects both clients and backend systems from unintended side effects caused by retries, network issues, or duplicate submissions. By assigning a unique idempotency key to each logical operation, clients can safely resend requests for `24` hours without risking duplicated charges, repeated state changes, or inconsistent data. For `POST` requests that **create** resources, the API supports idempotent requests via the `Idempotency-Key` header: `Idempotency-Key: ` + The key **must** be a `V4 UUID`/`GUID` and is generated by the client. + The key must be unique per logical operation (e.g., per order attempt). If the same API request is submitted multiple times, the API responds based on the state of the original request: Code | Description ---|--- `200` | **OK** - A previous instance of this request has been successfully processed within the past `24` hours, and the API returns the original response. `202` | **Accepted** - A previous instance of this request is still being processed.

If this occurs frequently, consider increasing your timeouts and retry using exponential backoff. `422` | **Unprocessable Content** - A request with the same `Idempotency-Key` was submitted, but the request body differs. The API rejects the request. *** ### Security token Some security-critical endpoints require an additional `Security-Token` on top of API key or access token authentication. This prevents attackers from using intercepted data to perform sensitive actions. A valid `Security-Token` cannot be created without the clients `securityKey`, intercepted requests quickly become unusable, modified requests are rejected, and replayed requests are detected and handled safely. Obtaining a `Security-Token` alone is not sufficient to create or submit new requests, as reused idempotency keys are detected and blocked. #### `Security-Token` generation The `Security-Token` is a HMACSHA256 hash of a number of request properties that assures message integrity and prevents misuse by actors not in posession of the `securityKey` obtained in client registration. Requests with a `Security-Token` also require a `Timestamp` header, containing the request UTC timestamp of the client in the format: `yyyy-MM-ddTHH:mm:ssZ` Example: `2026-02-23T11:56:49Z` In order to generate the binary input data for the hash, build the following string with your request data and UTF8 encode it: `{requestMethod};{requestUrlIncludingQuery};{timestampHeader}` If the request has an `Idempotency-Key` header, append the binary representation of the UUID/GUID used as `Idempotency-Key`. The UUID/GUID is encoded in normal reading order from left to right with regard to the common format "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", i.e. removing the "-" segment delimiters will produce the hex representation of the data. If the request has a body, further append the SHA256 hash of the request body. Having generated the binary input data, use the `securityKey` the client received during registration to HMACSHA256 hash this data. Base64 encode the resulting hash and add it to the request in the `Security-Token` header. ##### Example: Property | Data ---|--- `securityKey` of the client (Base64) | qGkfn2Ze7HltL+XiJNAT8S449mF8DbjHYP4GR3n0t6A= requestMethod | POST requestUrl | https://checkout-clients-sandbox-eu.qnips.com/api/v1/orders timestampHeader | 2025-11-18T18:41:13Z idempotencyKey | f0cdc088-02fc-46a1-8bfe-9c01df84e458 requestBody: ```json { "startTimestamp": "2025-11-18T18:40:45Z", "endTimestamp": "2025-11-18T18:41:12Z", "orderTimestamp": "2025-11-18T18:41:12Z", "profileToken": "BRBZU5RRXEVXGKHLBZR6", "basketId": "c926d56f-f071-4511-a959-513099a9ff78", "menuId": 514717, "positions": [ { "positionId": 0, "productPlu": "QNI-1757944121588", "quantity": 2 } ], "consumptionMode": "Takeaway", "totalGross": 990, "currency": "EUR" } ``` ##### Generating the token: Binary data is shown in Base64 representation in this example. Only the finished token needs to be Base64 converted to be written into the `Security-Token` header. Input string: `"POST;https://checkout-clients-sandbox-eu.qnips.com/api/v1/orders;2025-11-18T18:41:13Z"` Input string UTF8 encoded: `UE9TVDtodHRwczovL2NoZWNrb3V0LWNsaWVudHMtc2FuZGJveC1ldS5xbmlwcy5jb20vYXBpL3YxL29yZGVyczsyMDI1LTExLTE4VDE4OjQxOjEzWg==` Idempotency-Key in binary: `8M3AiAL8RqGL/pwB34TkWA==` Encoded input concatenated with idempotency key: `UE9TVDtodHRwczovL2NoZWNrb3V0LWNsaWVudHMtc2FuZGJveC1ldS5xbmlwcy5jb20vYXBpL3YxL29yZGVyczsyMDI1LTExLTE4VDE4OjQxOjEzWvDNwIgC/Eahi/6cAd+E5Fg=` SHA256 hash of request body: `xvgl4JkVxrgNEgoKmhQPGekMKhrtOQcQpOMh4Eqmepg=` Input further concatenated with request body hash: `UE9TVDtodHRwczovL2NoZWNrb3V0LWNsaWVudHMtc2FuZGJveC1ldS5xbmlwcy5jb20vYXBpL3YxL29yZGVyczsyMDI1LTExLTE4VDE4OjQxOjEzWvDNwIgC/Eahi/6cAd+E5FjG+CXgmRXGuA0SCgqaFA8Z6QwqGu05BxCk4yHgSqZ6mA==` Full input HMACSHA256 hashed with the `securityKey`, final `Security-Token` to add as header: `Security-Token: oe60R+gVBgAxo2wqjZ8PXAwamT893buQyr9fOZy7tnY=` *** ### Payloads The API uses JSON as payload format. All requests with a body **must** include the following headers: + `Content-Type: application/json; charset=utf-8` + `Accept: application/json` + Fields that are not explicitily marked as `required` are optional. ### Currencies The API expects `amount` currency values using the given denomination's smallest (minor) unit represented without decimals. For example: + `1095` to process 10.95 `EUR` (or any other two-decimal currency). + `10` to process 10 `JPY` (or any other zero-decimal currency). Make sure to use three-letter `ISO 3166-1 alpha-3` codes as currency. ### Dates & times **Timestamps:** * All timestamps sent to or returned by the API **must** be in UTC. * All timestamps are formatted using the `ISO 8601` standard: `yyyy-MM-ddTHH:mm:ssZ`. Example: `2025-12-05T08:47:57Z` * qnips uses the time zone of the associated store to convert UTC timestamps to local timestamps. **Dates:** All dates are formatted using the `ISO 8601` standard: `yyyy-MM-dd`. Example: `2025-12-05` *** ### Localization Some endpoints support localized responses. Clients may specify their preferred language(s) using the `Accept-Language` header, however, this does not guarantee that the response will be localized. If no localization is available, the API will return the default language. *** ## Responses All API responses follow a consistent structure to ensure predictable parsing, error handling, and integration behavior. + Responses are returned in JSON format and encoded `UTF-8`. + A JSON schema is provided for each endpoint with a response body. **Clients should:** + Not assume a field is always present + Handle `null` or missing values gracefully + Follow the schema for each API version API responses are normal HTTP-responses with an HTTP status code, response headers and, if applicable, a response body. The following HTTP status codes are used unless explicitly specified otherwise: | Code| Description | | --- | --- | |`200`| **OK** - Marks the successful execution. | |`400`| **Bad Request** - Request cannot be executed due to failed validations or unfulfilled preconditions. | |`401`| **Unauthorized** - `Authorization` and/or `Security-Token` header is not or incorrectly specified. | |`500`| **Server error** - Something went wrong during processing.| **[COMING SOON] Error response format:** ``` { "Error": { "Reference": "123.754", "Code": "unkown_error", "Message": "Something unexpected happened" } } ``` # Authorization The API implements a layered authentication and authorization model designed to ensure secure client identification, controlled access to resources, and minimal exposure of long-term credentials. The mechanism is composed of three core components: + Client registration + Long-lived API keys + Short-lived access tokens **Clients must:** Implement appropriate storage mechanisms, rotation procedures, and renewal logic to maintain continuous authenticated access. *** ## Client registration All consuming applications must complete a client registration process prior to accessing the API. Clients have to be created in the qnips Dashboard. After the intitial creation, the client is in a unregistered state and has to be activated by finalizing the registration through the API. Once a client is registred, the client can request long-lived API keys. *** ## Long-lived API keys + Are used exclusively to obtain short-lived access tokens or rotate API keys and are not accepted for direct access to resource endpoints. + Expire in `60 days` and may be rotated or revoked at any time to maintain security standards. + Must be securely stored and never be exposed or embedded in publicly accessible environments. *** ## Short-lived access tokens + Are used to access resource endpoints. + Expire automatically after `10 minutes`, reducing the impact of credential leakage or interception. + Must be included in each request to resource endpoints via the `Authorization` header. *** # Menus The API provides access to menu cards and the products associated with them. These endpoints allow clients to retrieve available menus as well as drill down into the products offered within a specific menu for a specific day. ## Baskets & Orders A basket represents a collection of items selected during the checkout process. It serves as a temporary workspace where items, quantities and pricing information can be assembled before finalizing. Items can be added, updated, or removed at any time while the basket is in an editable state. *** ## Basket evaluation + Each time the basket is updated, the API recalculates any metadata, such as discounts, rewards, taxes and surcharges. + A basket may optionally be tied to a profile. When a profile token is provided, the API will return a personalized evaluation response. + A basket remains mutable until it is explicitly finalized. *** ## Order + A basket can be finalized, by turning it into an order. Once finalized, the reward activation, invoicing and order processing flows get triggered. + Orders are no longer baskets and can not be re-evaluated. *** # Profiles A profile is always linked to an end user (a consumer/customer) and can be either an app profile or a card profile. A profile can be used to create personalized basket evaluation requests, link orders, or initiate balance transactions. The API uses the profile's unique `Token` or an one-time password (OTP) for identification. These are provided and transmitted as `reference` or `profileReference`, depending on the context of the operation. When an OTP is supplied, the API validates its authenticity, confirms its association with the intended profile, and checks its expiration before authorizing the request. This provides a secure, time-limited identification mechanism. Profiles can be identified via a QR code presented in the app or through alternative identification methods at the point of sale. *** ## Balance Balance represents the amount of funds associated with a profile. This amount is safely stored in a personal digital wallet. The balance amount is mutable and changes based on approved transactions, such as top-ups, charges, refunds, etc. A digital wallet is linked to a balance provider. The appropriate balance provider is automatically selected for the client based on the store where they are registered. Different stores may use different balance providers. The balance provider defines the applicable limits and validation rules. An app profile may be linked to multiple card profiles. In that case, the sum of all balance in the digital wallets is available as balance for the requested profile. Balance is always tied to one specific currency. + The currencies provided in the balance requests **must** match the profile's balance currency. Any request specifying a different `currency` will be rejected. + All balance requests undergo multiple validation checks, including balance-limit and negative-balance validations. If any check fails, the request will be rejected. + Negative balance (overdraft) is not permitted. *** # Check-ins A profile can use the qnips app to scan a QR code or NFC tag to create a check-in within the qnips system. Check-ins are currently always associated with a physical tray, which is manually collected by the profile user to transport products or orders prior to checkout. The API can return check-in information based on a provided tray ID. If a check-in exists for the specified tray ID, selected metadata of the associated profile is returned. A check-in can be removed either manually by the profile via the qnips app or automatically once the corresponding order has been successfully processed. # Group Clients ## Registration [/api/v1/clients/{clientId}/register] ### POST register [POST] Registers a client. Prior to the registration, the client has to be created in the qnips Dashboard. **[COMING SOON]** + During creation, each client is issued a unique `clientId` and `clientSecret`. These are used for authorization and should be treated as username and password and **must** be kept secret at all times. + On registration completion, the client receives configuration metadata which are important for further API request. Please check the response attributes section for a detailed explanation. + Request (application/json; charset=utf-8) + Headers Authorization: Basic base64(:) Idempotency-Key: + Response 200 (application/json; charset=utf-8) + Attributes (object) + securityKey (string, required) - The unique security key to generate `Security-Token`s with. + Body { "securityKey": "ykkBKHJG+EBQbFhLyCkWDFjRQJ4NgChiGKrMCManhkg=" } + Schema { "type": "object", "properties": { "securityKey": { "type": "string" } } } ## API keys [/api/v1/clients/{clientId}/api-keys] ### POST [POST] Creates a new long-lived API key for the registered client. + Returns the key once; it cannot be retrieved again. + Newly created keys can be used immediately to request short-lived access tokens. + For any matters concerning your API key, please provide qnips with the public `id` and not the secret `key`. + Parameters + clientId (guid, required) - The unique identifier of the client. + Request (application/json; charset=utf-8) + Headers Authorization: Basic base64(:) Idempotency-Key: Security-Token: Timestamp: + Response 200 (application/json; charset=utf-8) + Attributes (object) + id: `f8975cdc-0902-4e35-9faa-cdc1492b4a5c` (string, required) - The unique identifier of the API key. + key: `qnp_qnipscheckout_sandbox_1V0mHEQk8Ki0CLaaOJTCBzr6776LfPh0PvQJs3li440nVaN` (string, required) - The actual API key. + expirationTimestamp: `2025-11-18T00:00:00.000Z` (string, required) - The expiration date and time of the API key in UTC. + Body { "id": "f8975cdc-0902-4e35-9faa-cdc1492b4a5c", "key": "qnp_qnipscheckout_sandbox_1V0mHEQk8Ki0CLaaOJTCBzr6776LfPh0PvQJs3li440nVaN", "expirationTimestamp": "2025-11-18T00:00:00.000Z" } + Schema { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "key": { "type": "string" }, "expirationTimestamp": { "type": "string", "format": "date-time" } } } ### POST rotate [POST /api/v1/clients/{clientId}/api-keys/rotate] Rotates the client's active long-lived API key by generating a new one. + The previously active API key remains valid for `10` minutes, unless it expires sooner or the newly generated key makes its first API request. + **[WIP]** Revokes the previously active API key upon successful rotation. + The newly issued key can be used immediately to request short-lived access tokens. + Parameters + clientId (guid, required) - The unique identifier of the client. + Request (application/json; charset=utf-8) + Headers Authorization: ApiKey Idempotency-Key: Security-Token: Timestamp: + Response 200 (application/json; charset=utf-8) + Attributes + rotatingIn (object, required) - The new API key that will be replacing the old API key. + id: `068933bb-1f50-46b9-bd2f-3414e8a83e36` (string, required) - The unique identifier of the new API key. + key: `qnp_qnipscheckout_sandbox_O9nFZH77g1fhq3KXUowBqPl9v7rkPwwLa1FJb9jiXDFQPSX` (string, required) - The actual API key. + expirationTimestamp: `2026-01-17T00:00:00.000Z` (string, required) - The expiration date and time of the new API key in UTC. + rotatingOut (object, required) - The old API key that will be replaced by the new API key. + id: `f8975cdc-0902-4e35-9faa-cdc1492b4a5c` (string, required) - The unique identifier of the old API key. + expirationTimestamp: `2025-11-18T00:00:00.000Z` (string, required) - The expiration date and time of the old API key in UTC. + Body { "rotatingIn": { "id": "068933bb-1f50-46b9-bd2f-3414e8a83e36", "key": "qnp_qnipscheckout_sandbox_O9nFZH77g1fhq3KXUowBqPl9v7rkPwwLa1FJb9jiXDFQPSX", "expirationTimestamp": "2026-01-17T00:00:00.000Z" }, "rotatingOut": { "id": "f8975cdc-0902-4e35-9faa-cdc1492b4a5c", "expirationTimestamp": "2025-11-18T00:00:00.000Z" } } + Schema { "type": "object", "properties": { "rotatingIn": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "key": { "type": "string" }, "expirationTimestamp": { "type": "string", "format": "date-time" } } }, "rotatingOut": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "expirationTimestamp": { "type": "string", "format": "date-time" } } } } } ## Access tokens [/api/v1/clients/{clientId}/tokens] ### POST [POST] Creates a new short-lived access token. + The newly issued access token can be used immediately to access resource endpoints. + Once an access token has expired after `10` minutes, all requests to our API will return a `401 Unauthorized` error code. Please make sure that the client requests a new access token as soon as it receives this error response. + Parameters + clientId (guid, required) - the unique identifier of the client. + Request (application/json; charset=utf-8) + Headers Authorization: ApiKey Idempotency-Key: Security-Token: Timestamp: + Response 200 (application/json; charset=utf-8) + Attributes + token: `5ryYz0Jxo3NR5ZISaFHWuZ3ueZiEsM` (string, required) - The actual access token. + expirationTimestamp: `2025-11-18T17:50:21.517Z` (string, required) - The expiration date and time of the access token in UTC. + Body { "token": "5ryYz0Jxo3NR5ZISaFHWuZ3ueZiEsM", "expirationTimestamp": "2025-11-18T17:50:21.517Z" } + Schema { "type": "object", "properties": { "token": { "type": "string" }, "expirationTimestamp": { "type": "string", "format": "date-time" } } } # Group Menus ## Info [/api/v1/menus] ### GET [GET] Retrieves a collection of menus available to the client. + The `Accept-Language` header can be used by the client to specify the preferred language(s) for localized menu information. + Request (application/json; charset=utf-8) + Headers Authorization: Token Accept-Language: + Response 200 (application/json; charset=utf-8) + Attributes (object) + id: `514717` (number, required) - The unique identifier of the menu card. + name: `Checkout menu card` (string) - The localized name of the menu card. + Body [ { "id": "514717", "name": "Checkout menu card" } ] + Schema { "type": "array", "items": { { "type": "object", "properties": { "id": { "type": "number" }, "name": { "type": "string" } } } } ## Products [/api/v1/menus/{menuId}/products{?date}] ### GET [GET] **[Coming soon]** Retrieves a collection of products associated with a specific menu. + When a `date` is supplied, only the products available on that date are returned. If no `date` is provided, the current date is used by default. + The `Accept-Language` header can be used by the client to specify the preferred language(s) for localized product information. + Parameters + menuId (number, required) - The unique identifier of the menu. + date (date, optional) - Filters products by the date they are available on the menu. Format: `yyyy-MM-dd` + Request (application/json; charset=utf-8) + Headers Authorization: Token Accept-Language: + Response 200 (application/json; charset=utf-8) + Attributes (object) + gtin: `6383738268077` (string) - The GTIN of the product. + plu: `QNI-1757944121588` (string, required) - The PLU of the product, which has to be unique. + name: `Project Mango Fusion` (string) - The internal name of the product. + displayName: `Spiced Mango Coconut Stir-Fry` (string) - The localized (external) name of the product. + pictureUrl: `https://files.qnips.com/livepics/qnips-casino-hannover_2024.02.27_16.51.18.jpg` (string) - The picture url of the product. + Body [ { "gtin": "6383738268077", "plu": "QNI-1757944121588", "name": "Project Mango Fusion", "displayName": "Spiced Mango Coconut Stir-Fry", "pictureUrl": "https://files.qnips.com/livepics/qnips-casino-hannover_2024.02.27_16.51.18.jpg" } ] + Schema { "type": "array", "items": { "type": "object", "properties": { "gtin": { "type": "string" }, "plu": { "type": "string" }, "name": { "type": "string" }, "displayName": { "type": "string" }, "pictureUrl": { "type": "string", "format": "uri" } } } } # Group Baskets & Orders A basket may be submitted without a `profileReference`, but an order requires one. We recommend adding a `profileReference` to the request body as early as possible to ensure the API can provide a personalized evaluation response. **[Coming soon]** Component configuration. ## Baskets [/api/v1/baskets/{basketId}] ### PUT [PUT] Evaluates the basket and potentially enriches it with the following information: | Type | Description | | --- | --- | |**Prices**| Prices are calculated and added to the basket. | |**Vats**| Vats are calculated and added to the basket. | |**Reusable packaging**| **[Coming soon]** | |**Allowance**| **[Coming soon]** | |**Rewards/Loyalty**| **[Coming soon]** | `consumptionMode` Values: | Type | Description | | --- | --- | |**OnPremise**| On-Premise consumption refers to customers consuming a product or service at the business's physical location. | |**Takeaway**| Takeaway (also known as takeout or to-go) refer to customers ordering food or products to consume elsewhere. | + Parameters + basketId: `c926d56f-f071-4511-a959-513099a9ff78` (guid, required) - The unique identifier of the basket generated by the client. + Request (application/json; charset=utf-8) + Headers Authorization: Token + Attributes (object) + profileReference: `BRBZU5RRXEVXGKHLBZR6` (string) - The unique token identifier or an OTP of the profile. + menuId: 514717 (number, required) - The unique identifier of the menu card. + positions (array, required) - The items to be processed. + (object) + positionId: 0 (number, required) - A number used to reference a specific position within the basket. + productPlu: `QNI-1757944121588` (string, required) - The PLU of the product, which has to be unique. + quantity: 2 (number, required) - The quantity of the product. + consumptionMode: `Takeaway` (string, required) - The type of consumption. + balance (object) - Contains balance charge information. + requestCharge: true (boolean) - Signals the intention to pay the order with balance. + Body { "profileReference": "BRBZU5RRXEVXGKHLBZR6", "menuId": 514717, "positions": [ { "positionId": 0, "productPlu": "QNI-1757944121588", "quantity": 2 } ], "consumptionMode": "Takeaway", "balance": { "requestCharge": true } } + Schema { "type": "object", "properties": { "profileReference": { "type": "string" }, "menuId": { "type": "number" }, "positions": { "type": "array", "items": { "type": "object", "properties": { "positionId": { "type": "number" }, "productPlu": { "type": "string" }, "quantity": { "type": "number" } } } }, "consumptionMode": { "oneOf": [ { "type": "string", "enum": ["OnPremise", "Takeaway"] }, { "type": "integer", "minimum": 0, "maximum": 1 } ] }, "balance": { "type": "object", "properties": { "requestCharge": { "type": "boolean" } } } } } + Response 200 (application/json; charset=utf-8) + Attributes (object) + profileReference: `BRBZU5RRXEVXGKHLBZR6` (string) - The unique token identifier or an OTP of the profile. + menuId: 514717 (number, required) - The unique identifier of the menu card. + positions (array, required) - The items to be processed. + (object) + positionId: 0 (number, required) - A number used to reference a specific position within the basket. + productPlu: `QNI-1757944121588` (string, required) - The PLU of the product, which has to be unique. + quantity: 2 (number, required) - The quantity of the product. + price: 495 (number, required) - The total basket value for this position in the currency's minor unit. + vat (object, required) - An object containing VAT information for this position. + rate: 7 (number) - The VAT rate (in percent) applied to this position. + gross: 990 (number) - The gross amount (including VAT) for this position in the currency's minor unit. + net: 925 (number) - The net amount (excluding VAT) for this position in the currency's minor unit. + taxAmount: 65 (number) - The VAT amount calculated for this position in the currency's minor unit. + consumptionMode: `Takeaway` (string, required) - The type of consumption. + receiptUrl: `https://sandbox.cateringportal.io/.../c926d56f-f071-4511-a959-513099a9ff78` (string) - The URL for retrieving a digital receipt. + totalGross: 990 (number, required) - The total gross amount (including VAT) for the basket in the currency's minor unit. + currency: EUR (string, required) - The currency of the basket. + vats (array, required) + (object) + rate: 7 (number) - The VAT rate (in percent) applied to the basket. + gross: 990 (number) - The gross amount (including VAT) for the basket in the currency's minor unit. + net: 925 (number) - The net amount (excluding VAT) for the basket in the currency's minor unit. + taxAmount: 65 (number) - The VAT amount calculated for the basket in the currency's minor unit. + balance (object) - Balance information of the profile. + availableAmount: 1550 (number) - The available balance of the profile in the currency's minor unit. Reserved balance is not included here until the reservation expires. + totalAmount: 2050 (number) - The total balance of the profile in the currency's minor unit including reserved balance that is temporarily inaccessible without the reservation's reference. + currency: EUR (string) - The currency of the balance. + config (object) - The balance configuration for the profile. + isChargeAllowed: true (boolean) - Indicateds whether the profile is allowed to create charges. + Body { "profileReference": "BRBZU5RRXEVXGKHLBZR6", "menuId": 514717, "positions": [ { "positionId": 0, "productPlu": "QNI-1757944121588", "quantity": 2, "price": 495, "vat": { "rate": 7, "gross": 990, "net": 925, "taxAmount": 65 } } ], "consumptionMode": "Takeaway", "receiptUrl": "https://sandbox.cateringportal.io/.../c926d56f-f071-4511-a959-513099a9ff78", "totalGross": 990, "currency": "EUR", "vats": [ { "rate": 7, "gross": 990, "net": 925, "taxAmount": 65 } ], "balance": { "availableAmount": 1550, "totalAmount": 2050, "currency": "EUR", "config": { "isChargeAllowed": true } } } + Schema { "type": "object", "properties": { "profileReference": { "type": "string" }, "menuId": { "type": "number" }, "positions": { "type": "array", "items": { "type": "object", "properties": { "positionId": { "type": "number" }, "productPlu": { "type": "string" }, "quantity": { "type": "number" }, "price": { "type": "number" }, "vat": { "type": "object", "properties": { "rate": { "type": "number" }, "gross": { "type": "number" }, "net": { "type": "number" }, "taxAmount": { "type": "number" } } } } } }, "consumptionMode": { "oneOf": [ { "type": "string", "enum": ["OnPremise", "Takeaway"] }, { "type": "integer", "minimum": 0, "maximum": 1 } ] }, "receiptUrl": { "type": "string", "format": "uri" }, "totalGross": { "type": "number" }, "currency": { "type": "string" }, "vats": { "type": "array", "items": { "type": "object", "properties": { "rate": { "type": "number" }, "gross": { "type": "number" }, "net": { "type": "number" }, "taxAmount": { "type": "number" } } } }, "balance": { "type": "object", "properties": { "availableAmount": { "type": "number" }, "totalAmount": { "type": "number" }, "currency": { "type": "string" }, "config": { "type": "object", "properties": { "isChargeAllowed": { "type": "boolean" } } } } } } } ## Orders [/api/v1/orders] ### POST [POST] Creates a new order. + `totalGross` is used to validate the calculated value in the API, ensuring the client displayed the correct price to the customer. + Request (application/json; charset=utf-8) + Headers Authorization: Token Idempotency-Key: Security-Token: Timestamp: + Attributes (object) + startTimestamp: `2025-11-18T18:40:45Z` (string) - The basket creation date and time in UTC. + endTimestamp: `2025-11-18T18:41:12Z` (string) - The basket last updated date and time in UTC. + orderTimestamp: `2025-11-18T18:41:12Z` (string, required) - The date and time used for the order in UTC. + basketId: `c926d56f-f071-4511-a959-513099a9ff78` (string, required) - The unique identifier of the basket generated by the client. + profileReference: `BRBZU5RRXEVXGKHLBZR6` (string, required) - The unique token identifier or an OTP of the profile. + menuId: 514717 (number, required) - The unique identifier of the menu card. + checkInIds (array) - The check-ins associated with the order. + Members + `89644` (number) - The unique identifiers of check-in. + positions (array, required) - The items to be processed. + (object) + positionId: 0 (number, required) - A number used to reference a specific position within the basket. + productPlu: `QNI-1757944121588` (string, required) - The PLU of the product, which has to be unique. + quantity: 2 (number, required) - The quantity of the product. + consumptionMode: `Takeaway` (string, required) - The type of consumption. + totalGross: 990 (number, required) - The total gross amount (including VAT) for the basket in the currency's minor unit. + currency: EUR (string, required) - The currency of the basket. + balance (object) - Contains balance charge information. + requestCharge: true (boolean, required) - Request for the order to be paid with balance. + reservation (object) - Contains balance reservation information. Include to perform the balance charge against reserved balance. + reference: `f032f960-9b87-43eb-b434-48a65d7d3efe` (string, required) - The reference of the reservation that will be charged. + cancelRemainingAmount: true (boolean) - Cancel the reservation after payment, causing any leftover reserved balance to become freely available again without waiting for the reservation to time out. + Body { "startTimestamp": "2025-11-18T18:40:45Z", "endTimestamp": "2025-11-18T18:41:12Z", "orderTimestamp": "2025-11-18T18:41:12Z", "profileReference": "BRBZU5RRXEVXGKHLBZR6", "basketId": "c926d56f-f071-4511-a959-513099a9ff78", "menuId": 514717, "checkInIds": [ 89644 ], "positions": [ { "positionId": 0, "productPlu": "QNI-1757944121588", "quantity": 2 } ], "consumptionMode": "Takeaway", "totalGross": 990, "currency": "EUR", "balance": { "requestCharge": true, "reservation": { "reference": "f032f960-9b87-43eb-b434-48a65d7d3efe", "cancelRemainingAmount": true } } } + Schema { "type": "object", "properties": { "startTimestamp": { "type": "string", "format": "date-time" }, "endTimestamp": { "type": "string", "format": "date-time" }, "orderTimestamp": { "type": "string", "format": "date-time" }, "basketId": { "type": "string", "format": "uuid" }, "profileReference": { "type": "string" }, "menuId": { "type": "number" }, "checkInIds": { "type": "array", "items": { "type": "number" } }, "positions": { "type": "array", "items": { "type": "object", "properties": { "positionId": { "type": "number" }, "productPlu": { "type": "string" }, "quantity": { "type": "number" } } } }, "consumptionMode": { "oneOf": [ { "type": "string", "enum": ["OnPremise", "Takeaway"] }, { "type": "integer", "minimum": 0, "maximum": 1 } ] }, "totalGross": { "type": "number" }, "currency": { "type": "string" }, "balance": { "type": "object", "properties": { "requestCharge": { "type": "boolean" }, "reservation": { "type": "object", "properties": { "reference": { "type": "string", "format": "uuid" }, "cancelRemainingAmount": { "type": "boolean" } } } } } } } + Response 200 (application/json; charset=utf-8) + Attributes (object) + startTimestamp: `2025-11-18T18:40:45Z` (string) - The basket creation date and time in UTC. + endTimestamp: `2025-11-18T18:41:12Z` (string) - The basket last updated date and time in UTC. + orderTimestamp: `2025-11-18T18:41:12Z` (string, required) - The date and time used for the order in UTC. + basketId: `c926d56f-f071-4511-a959-513099a9ff78` (string, required) - The unique identifier of the basket generated by the client. + profileReference: `BRBZU5RRXEVXGKHLBZR6` (string, required) - The unique token identifier or an OTP of the profile. + menuId: 514717 (number, required) - The unique identifier of the menu card. + positions (array, required) - The items to be processed. + (object) + positionId: 0 (number, required) - A number used to reference a specific position within the basket. + productPlu: `QNI-1757944121588` (string, required) - The PLU of the product, which has to be unique. + quantity: 2 (number, required) - The quantity of the product. + price: 495 (number, required) - The total basket value for this position in the currency's minor unit. + vat (object, required) - An object containing VAT information for this position. + rate: 7 (number) - The VAT rate (in percent) applied to this position. + gross: 990 (number) - The gross amount (including VAT) for this position in the currency's minor unit. + net: 925 (number) - The net amount (excluding VAT) for this position in the currency's minor unit. + taxAmount: 65 (number) - The VAT amount calculated for this position in the currency's minor unit. + consumptionMode: `Takeaway` (string, required) - The type of consumption. + receiptUrl: `https://sandbox.cateringportal.io/.../c926d56f-f071-4511-a959-513099a9ff78` (string) - The URL for retrieving a digital receipt. + totalGross: 990 (number, required) - The total gross amount (including VAT) for the basket in the currency's minor unit. + currency: EUR (string, required) - The currency of the basket. + vats (array, required) + (object) + rate: 7 (number) - The VAT rate (in percent) applied to the basket. + gross: 990 (number) - The gross amount (including VAT) for the basket in the currency's minor unit. + net: 925 (number) - The net amount (excluding VAT) for the basket in the currency's minor unit. + taxAmount: 65 (number) - The VAT amount calculated for the basket in the currency's minor unit. + balance (object) + oldAmount: 1000 (number) - The old amount before paying the order with balance, expressed in the currency's minor unit. + newAmount: 10 (number) - The new amount after paying the order with balance, expressed in the currency's minor unit. + currency: `EUR` (string) - The currency of the transaction. + reservation (object) + oldAmountExcludingReservation: 0 (number) - The profile's balance prior to the transaction, factoring out the reservation that is used for the charge, expressed in the currency's minor unit. + newAmountExcludingReservation: 10 (number) - The profile's balance after the transaction, factoring out the potentially remaining amount of the used reservation, expressed in the currency's minor unit. + reservedAmountRemaining: 0 (number) - The remaining amount of the reservation, expressed in the currency's minor unit. + reservedAmountUsed: 990 (number) - The amount of the reservation used by the transaction, expressed in the currency's minor unit. + unreservedAmountUsed: 0 (number) - The amount of unreserved profile balance used by the transaction in case the reserved amount was insufficient to cover the whole transaction, expressed in the currency's minor unit. + Body { "startTimestamp": "2025-11-18T18:40:45Z", "endTimestamp": "2025-11-18T18:41:12Z", "orderTimestamp": "2025-11-18T18:41:12Z", "basketId": "c926d56f-f071-4511-a959-513099a9ff78", "profileReference": "BRBZU5RRXEVXGKHLBZR6", "menuId": 514717, "positions": [ { "positionId": 0, "productPlu": "QNI-1757944121588", "quantity": 2, "price": 495, "vat": { "rate": 7, "gross": 990, "net": 925, "taxAmount": 65 } } ], "consumptionMode": "Takeaway", "receiptUrl": "https://sandbox.cateringportal.io/.../c926d56f-f071-4511-a959-513099a9ff78", "totalGross": 990, "currency": "EUR", "vats": [ { "rate": 7, "gross": 990, "net": 925, "taxAmount": 65 } ], "balance": { "oldAmount": 1000, "newAmount": 10, "reservation": { "oldAmountExcludingReservation": 0, "newAmountExcludingReservation": 10, "reservedAmountRemaining": 0, "reservedAmountUsed": 990, "unreservedAmountUsed": 0 } } } + Schema { "type": "object", "properties": { "startTimestamp": { "type": "string", "format": "date-time" }, "endTimestamp": { "type": "string", "format": "date-time" }, "orderTimestamp": { "type": "string", "format": "date-time" }, "basketId": { "type": "string", "format": "uuid" }, "profileReference": { "type": "string" }, "menuId": { "type": "number" }, "positions": { "type": "array", "items": { "type": "object", "properties": { "positionPlu": { "type": "string" }, "productId": { "type": "number" }, "quantity": { "type": "number" }, "price": { "type": "number" }, "vat": { "type": "object", "properties": { "rate": { "type": "number" }, "gross": { "type": "number" }, "net": { "type": "number" }, "taxAmount": { "type": "number" } } } } } }, "consumptionMode": { "oneOf": [ { "type": "string", "enum": ["OnPremise", "Takeaway"] }, { "type": "integer", "minimum": 0, "maximum": 1 } ] }, "receiptUrl": { "type": "string", "type": "uri" }, "totalGross": { "type": "number" }, "currency": { "type": "string" }, "vats": { "type": "array", "items": { "type": "object", "properties": { "rate": { "type": "number" }, "gross": { "type": "number" }, "net": { "type": "number" }, "taxAmount": { "type": "number" } } } }, "balance": { "type": "object", "properties": { "oldAmount": { "type": "number" }, "newAmount": { "type": "number" }, "reservation": { "type": "object", "properties": { "oldAmountExcludingReservation": { "type": "number" }, "newAmountExcludingReservation": { "type": "number" }, "reservedAmountRemaining": { "type": "number" }, "reservedAmountUsed": { "type": "number" }, "unreservedAmountUsed": { "type": "number" } } } } } } } # Group Profiles ## Info [/api/v1/profiles] ### GET [GET /api/v1/profiles/{reference}] Retrieves profile info, including: * Personal information. * Balance information. * The tags linked to the profile, primarily used for organizing user groups. + Parameters + reference (string, required) - The unique token identifier or an OTP of the profile. + Request (application/json; charset=utf-8) + Headers Authorization: Token + Response 200 (application/json; charset=utf-8) + Attributes (object) + fullName: `John Doe` (string) - The full name of the account owner, linked to the profile, if available. + language: `en-US` (string) - The user-defined language setting for the qnips system. + balance (object) - Balance information of the profile. + availableAmount: 1550 (number) - The available balance of the profile in the currency's minor unit. Reserved balance is not included here until the reservation expires. + totalAmount: 2050 (number) - The total balance of the profile in the currency's minor unit including reserved balance that is temporarily inaccessible without the reservation's reference. + currency: EUR (string) - The currency of the balance. + remainingTopUpAmount: 9000 (number) - The remaining monthly balance that is allowed to be added in top-ups. + config (object) - The balance configuration for the profile. + isTopUpAllowed: true (boolean) - Indicateds whether the profile is allowed to create top-ups. + isChargeAllowed: true (boolean) - Indicateds whether the profile is allowed to create charges. + maxAmount: 10000 (number) - The maximum balance a profile is permitted to hold, expressed in the currency's minor unit. + maxSingleTopUpAmount: 10000 (number) - The maximum balance a profile is allowed to add in a single top-up, expressed in the currency's minor unit. + minSingleTopUpAmount: 100 (number) - The minimum balance a profile has to add in a single top-up, expressed in the currency's minor unit. + maxMonthlyTopUpAmount: 10000 (number) - The maximum balance a profile is allowed to add in a single month, starting for the 1th of the month, expressed in the currency's minor unit. + tags (array) - The tags linked to the profile, primarily used for organizing user groups. + (object) + id: 58977 (number) + name: Student (string) + vytal (object) - The Vytal configuration for the profile. + userId: `d89accd2-135b-49f6-81eb-33ab27ef0389` (string) - The unique identifier of the Vytal user. + Body { "fullName": "John Doe", "language": "en-US", "balance": { "availableAmount": 1550, "totalAmount": 2050, "currency": "EUR", "remainingTopUpAmount": 9000, "config": { "isTopUpAllowed": true, "isChargeAllowed": true, "maxAmount": 10000, "maxSingleTopUpAmount": 10000, "minSingleTopUpAmount": 100, "maxMonthlyTopUpAmount": 10000 } }, "tags": [{ "id": 58977, "name": "Student" }], "vytal": { "userId": "d89accd2-135b-49f6-81eb-33ab27ef0389" } } + Schema { "type": "object", "properties": { "fullName": { "type": "string" }, "language": { "type": "string" }, "balance": { "type": "object", "properties": { "availableAmount": { "type": "number" }, "totalAmount": { "type": "number" }, "currency": { "type": "string" }, "remainingTopUpAmount": { "type": "number" }, "config": { "type": "object", "properties": { "isTopUpAllowed": { "type": "boolean" }, "isChargeAllowed": { "type": "boolean" }, "maxAmount": { "type": "number" }, "maxSingleTopUpAmount": { "type": "number" }, "minSingleTopUpAmount": { "type": "number" }, "maxMonthlyTopUpAmount": { "type": "number" } } } } }, "tags": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "number" }, "name": { "type": "string" } } } }, "vytal": { "type": "object", "properties": { "userId": { "type": "string", "format": "uuid" } } } } } ## Balance [/api/v1/profiles/{reference}/balance] **[Coming soon]** Postponement support. ### POST top-ups [POST /api/v1/profiles/{reference}/balance/top-ups] Creates a new balance top-up. + Make sure to check if top-up is allowed for the profile first. + Make sure the top-up limits are respected. + Parameters + reference (string, required) - The unique token identifier or an OTP of the profile. + Request (application/json; charset=utf-8) + Headers Authorization: Token Idempotency-Key: Security-Token: Timestamp: + Attributes (object) + amount: 1000 (number, required) - The amount to be added to the profile's balance, expressed in the currency's minor unit. + currency: EUR (string, required) - The currency of the amount to be added to the profile's balance. + Body { "amount": 1000, "currency": "EUR" } + Schema { "type": "object", "properties": { "amount": { "type": "number" }, "currency": { "type": "string" } } } + Response 200 (application/json; charset=utf-8) + Attributes (object) + oldAmount: 50 (number, required) - The old amount before making the charge request, expressed in the currency's minor unit. + newAmount: 1050 (number, required) - The new amount after making the charge request, expressed in the currency's minor unit. + currency: EUR (string, required) - The currency of the amounts. + Body { "oldAmount": 50, "newAmount": 1050, "currency": "EUR" } + Schema { "type": "object", "properties": { "oldAmount": { "type": "number" }, "newAmount": { "type": "number" }, "currency": { "type": "string" } } } ### POST charges [POST /api/v1/profiles/{reference}/balance/charges] Creates a new balance charge. + Make sure to check if charge is allowed for the profile first. + Parameters + reference (string, required) - The unique token identifier or an OTP of the profile. + Request (application/json; charset=utf-8) + Headers Authorization: Token Idempotency-Key: Security-Token: Timestamp: + Attributes (object) + amount: 195 (number, required) - The amount to be deducted from the profile's balance, expressed in the currency's minor unit. + currency: EUR (string, required) - The currency of the amount to be deducted from the profile's balance. + reservation (object) - Contains balance reservation information. Include to perform the charge against reserved balance. + reference: `f032f960-9b87-43eb-b434-48a65d7d3efe` (string, required) - The reference of the reservation that will be charged. + cancelRemainingAmount: false (boolean) - Cancel the reservation after payment, causing any leftover reserved balance to become freely available again without waiting for the reservation to time out. + Body { "amount": 195, "currency": "EUR", "reservation": { "reference": "f032f960-9b87-43eb-b434-48a65d7d3efe", "cancelRemainingAmount": false } } + Schema { "type": "object", "properties": { "amount": { "type": "number" }, "currency": { "type": "string" }, "reservation": { "type": "object", "properties": { "reference": { "type": "string", "format": "uuid" }, "cancelRemainingAmount": { "type": "boolean" } } } } } + Response 200 (application/json; charset=utf-8) + Attributes (object) + oldAmount: 1050 (number, required) - The old amount before making the charge request, expressed in the currency's minor unit. + newAmount: 855 (number, required) - The new amount after making the charge request, expressed in the currency's minor unit. + currency: EUR (string, required) - The currency of the amounts. + reservation (object) + oldAmountExcludingReservation: 850 (number) - The profile's balance prior to the transaction, factoring out the reservation that is used for the charge, expressed in the currency's minor unit. + newAmountExcludingReservation: 850 (number) - The profile's balance after the transaction, factoring out the potentially remaining amount of the used reservation, expressed in the currency's minor unit. + reservedAmountRemaining: 5 (number) - The remaining amount of the reservation, expressed in the currency's minor unit. + reservedAmountUsed: 195 (number) - The amount of the reservation used by the transaction, expressed in the currency's minor unit. + unreservedAmountUsed: 0 (number) - The amount of unreserved profile balance used by the transaction in case the reserved amount was insufficient to cover the whole transaction, expressed in the currency's minor unit. + Body { "oldAmount": 1050, "newAmount": 855, "currency": "EUR", "reservation": { "oldAmountExcludingReservation": 850, "newAmountExcludingReservation": 850, "reservedAmountRemaining": 5, "reservedAmountUsed": 195, "unreservedAmountUsed": 0 } } + Schema { "type": "object", "properties": { "oldAmount": { "type": "number" }, "newAmount": { "type": "number" }, "currency": { "type": "string" }, "reservation": { "type": "object", "properties": { "oldAmountExcludingReservation": { "type": "number" }, "newAmountExcludingReservation": { "type": "number" }, "reservedAmountRemaining": { "type": "number" }, "reservedAmountUsed": { "type": "number" }, "unreservedAmountUsed": { "type": "number" } } } } } ### POST refunds [POST /api/v1/profiles/{reference}/balance/refunds] Creates a new balance refund. + Parameters + reference (string, required) - The unique token identifier or an OTP of the profile. + Request (application/json; charset=utf-8) + Headers Authorization: Token Idempotency-Key: Security-Token: Timestamp: + Attributes (object) + amount: 195 (number, required) - The amount to be refunded to the profile's balance, expressed in the currency's minor unit. + currency: EUR (string, required) - The currency of the amount to be refunded to the profile's balance. + Body { "amount": 195, "currency": "EUR" } + Schema { "type": "object", "properties": { "amount": { "type": "number" }, "currency": { "type": "string" } } } + Response 200 (application/json; charset=utf-8) + Attributes (object) + oldAmount: 855 (number, required) - The old amount before making the refund request, expressed in the currency's minor unit. + newAmount: 1050 (number, required) - The new amount after making the refund request, expressed in the currency's minor unit. + currency: EUR (string, required) - The currency of the amounts. + Body { "oldAmount": 855, "newAmount": 1050, "currency": "EUR" } + Schema { "type": "object", "properties": { "oldAmount": { "type": "number" }, "newAmount": { "type": "number" }, "currency": { "type": "string" } } } ### POST payouts [POST /api/v1/profiles/{reference}/balance/payouts] Creates a new balance payout. + Parameters + reference (string, required) - The unique token identifier or an OTP of the profile. + Request (application/json; charset=utf-8) + Headers Authorization: Token Idempotency-Key: Security-Token: Timestamp: + Attributes (object) + amount: 1050 (number, required) - The amount to be paid out to the profile's , expressed in the currency's minor unit. + currency: EUR (string, required) - The currency of the amount to be paid out to the profile's . + reservation (object) - Contains balance reservation information. Include to perform the payout against reserved balance. + reference: `f032f960-9b87-43eb-b434-48a65d7d3efe` (string, required) - The reference of the reservation that will be paid out. + cancelRemainingAmount: true (boolean) - Cancel the reservation after payment, causing any leftover reserved balance to become freely available again without waiting for the reservation to time out. + Body { "amount": 1050, "currency": "EUR", "reservation": { "reference": "f032f960-9b87-43eb-b434-48a65d7d3efe", "cancelRemainingAmount": true } } + Schema { "type": "object", "properties": { "amount": { "type": "number" }, "currency": { "type": "string" }, "reservation": { "type": "object", "properties": { "reference": { "type": "string", "format": "uuid" }, "cancelRemainingAmount": { "type": "boolean" } } } } } + Response 200 (application/json; charset=utf-8) + Attributes (object) + oldAmount: 2050 (number, required) - The old amount before making the payout request, expressed in the currency's minor unit. + newAmount: 1000 (number, required) - The new amount after making the payout request, expressed in the currency's minor unit. + currency: EUR (string, required) - The currency of the amounts. + reservation (object) + oldAmountExcludingReservation: 1550 (number) - The profile's balance prior to the transaction, factoring out the reservation that is used for the payout, expressed in the currency's minor unit. + newAmountExcludingReservation: 1000 (number) - The profile's balance after the transaction, factoring out the potentially remaining amount of the used reservation, expressed in the currency's minor unit. + reservedAmountRemaining: 0 (number) - The remaining amount of the reservation, expressed in the currency's minor unit. + reservedAmountUsed: 500 (number) - The amount of the reservation used by the transaction, expressed in the currency's minor unit. + unreservedAmountUsed: 550 (number) - The amount of unreserved profile balance used by the transaction in case the reserved amount was insufficient to cover the whole transaction, expressed in the currency's minor unit. + Body { "oldAmount": 2050, "newAmount": 1000, "currency": "EUR", "reservation": { "oldAmountExcludingReservation": 1550, "newAmountExcludingReservation": 1000, "reservedAmountRemaining": 0, "reservedAmountUsed": 500, "unreservedAmountUsed": 550 } } + Schema { "type": "object", "properties": { "oldAmount": { "type": "number" }, "newAmount": { "type": "number" }, "currency": { "type": "string" }, "reservation": { "type": "object", "properties": { "oldAmountExcludingReservation": { "type": "number" }, "newAmountExcludingReservation": { "type": "number" }, "reservedAmountRemaining": { "type": "number" }, "reservedAmountUsed": { "type": "number" }, "unreservedAmountUsed": { "type": "number" } } } } } ### POST reservations [POST /api/v1/profiles/{reference}/balance/reservations] Creates a new balance reservation. + Parameters + reference (string, required) - The unique token identifier or an OTP of the profile. + Request (application/json; charset=utf-8) + Headers Authorization: Token Idempotency-Key: Security-Token: Timestamp: + Attributes (object) + amount: 500 (number, required) - The amount to be reserved from the profile's balance, expressed in the currency's minor unit. + currency: EUR (string, required) - The currency of the amount to be reserved from the profile's balance. + releaseTimestamp: `2025-12-10T15:04:55Z` (string) - The timestamp at which the reservation will be released, causing the balance to become freely available again. + Body { "amount": 500, "currency": "EUR", "releaseTimestamp": "2025-12-10T15:04:55Z" } + Schema { "type": "object", "properties": { "amount": { "type": "number" }, "currency": { "type": "string" }, "releaseTimestamp": { "type": "string", "format": "date-time" } } } + Response 200 (application/json; charset=utf-8) + Attributes (object) + amount: 500 (number, required) - The reserved amount from the profile's balance, expressed in the currency's minor unit. + currency: EUR (string, required) - The currency of the reserved amount from the profile's balance. + reference: `906a314d-d839-4b34-a629-37d15a4c343a` (string, required) - The unique identifier of the balance reservation. + releaseTimestamp: `2025-11-20T16:45:32Z` (string, required) - The expiration timestamp of the balance reservation. + Body { "amount": 500, "currency": "EUR", "reference": "906a314d-d839-4b34-a629-37d15a4c343a", "releaseTimestamp": "2025-11-20T16:45:32Z" } + Schema { "type": "object", "properties": { "amount": { "type": "number" }, "currency": { "type": "string", }, "reference": { "type": "number", "format": "uuid" }, "releaseTimestamp": { "type": "string", "format": "date-time" } } } ## Group Check-ins ## Info [/api/v1/check-ins] ### GET [GET /api/v1/check-ins{?tray_id}] Retrieves a check-in. + Parameters + tray_id (string, required) - The unique identifier of the tray to look up. + Request (application/json; charset=utf-8) + Headers Authorization: Token + Response 200 (application/json; charset=utf-8) + Attributes + id: 89644 (number, required) - The unique identifier of the check-in. + profile (object) - The entity used to represent a user or card. + token: `BRBZU5RRXEVXGKHLBZR6` (string) - An unique token identifier of the profile. + language: `en-US` (string) - The language preference. + Body { "id": 89644, "profile": { "token": "BRBZU5RRXEVXGKHLBZR6", "language": "en-US" } } + Schema { "type": "object", "properties": { "id": { "type": "number" }, "profile": { "type": "object", "properties": { "token": { "type": "string" }, "language": { "type": "string" } } } } }