RESTful-JSON-API Reference

The KassaForte API uses HTTP verbs and a RESTful endpoint structure. HTTP Basic Authentication in combination with SSL/TLS is used for securly identifing a KassaForte-Webshop. All requests and responses are formated in JSON. JSON-Schemas (draft-04) are available for every request and response.

Table of Contents

API Operations

This API is intended for use with a webserver or mobile app to recieve all data needed to build a working shop-solution. This includes a complete menu, data about open hours, delivery costs and much more. All data can (and should) be stored localy, the noteable exception being "Get Shop Infos", which should be updated frequently, at least during open hours.

The API is available in the live-environment and a sandbox-environment for testing. To access the live-environment use the domain, to access the sandbox use

A REST operation is performed by sending a request with a valid HTTP method to one of the endpoints defining the operation. For example to request the menu of a shop from the live-environmet you send the following request:


The same request on a sandbox-shop would be:



To authenticate your request you will have to connect to the api using a https-connection. Attempts to connect via http will lead to 403 Forbidden-errors. For now authentication will be handled via HTTP Basic Authentication. The username and password will be a random string containing upper and lower case letters, numbers and symbols and will be provided by us.
Authentication is required for every operation.

Possible Operations

General server responses

The server responds with the aid of HTTP-Statuscodes to inform you about the status of your request. Some responses are common among many operations, these are described here:

200 Ok
The standard response if everything was alright.
400 Bad Request
The request body could not be validated against the corresponding JSON-Schema.
401 Unauthorized
Either your username was not recognized or the password differed from the one on our server.
403 Forbidden
You tried to access the endpoint without SSL.
404 Not Found
The endpoint of the request is unknown.
405 Method Not Allowed
The HTTP-Method used to adress the operation is not valid. A list of valid methods is supplied in the HTTP-Accept header.
500 Internal Server Error
An internal error has occured. Sadly there is nothing you can do. The Admin has most likely been automaticly informed about the error.

Get Shop Infos

GET https://{DOMAIN}/v1/infos

This operation shows you important information about the operational status of the shop. Therefore this data should be updated frequently to be able to inform your users in time about changes. The currently transmitted infos are:

The date of the last update of the menu.
The date of the last update of the open hours.
The date of the last update of the delivery costs definition.
The current status of the KassaForte->Webserver-connection. If the connection is interrupted during open hours, you should consider not sending orders and informing your users until the connection is reestablished. The API-Server will accept orders, even if the connection is interrupted, so you can decide yourself, how you want to deal with this situation.
An object with the two keys delivery and pickup. This shows you if the shop was closed manually for any of the delivery types. This may be nessessary, if a shop has a pickup-serivce at noon and in the evening, but delivery-service only in the evening. Or delivery service is suspended due to icy roads.
The time in minutes a customer is likely to wait, until its order is finished. As with shopOpenStatus has two values for delivery and pickup.
A list of item numbers, that are currently unavailable. Those items should not be omitted when the menu is presented to the user, as they are still part of the menu, but be marked as unavailable. Ordering unavailable items will result in validation errors on sending

This operation doesn't need a request body, just send an authenticated request to the endpoint to recieve the data.

Get Open Hours

GET https://{DOMAIN}/v1/openhours

This operation gives you a list of all open hours for each day, as well as a configuration when to start and end accepting orders.

The index of this array represents the day of the week, starting with 0 for Monday, 1 for Tuesday and so on. Index 7 contains the times for holidays.
Defines the number of minutes the app should start accepting orders before the shop is actually opened.
Defines the number of minutes the app should stop accepting orders before the shop is actually closed.

This operation doesn't need a request body, just send an authenticated request to the endpoint to recieve the data.

Get the Menu

GET https://{DOMAIN}/v1/menu

With this operation you get access to the complete menu of the shop. The response will contain information about categories, products, menus, ingredients, choice-ingredients, sizes, special offers and general properties. Please refer to the schema and example for more detailed information.

This operation doesn't need a request body, just send an authenticated request to the endpoint to recieve the data.

Get Delivery Costs

GET https://{DOMAIN}/v1/deliverycosts

This operation will give you access to the delivery costs configuration for the shop. As there are many different ways to deal with delivery costs we currently support two differnt ways of determining delivery costs in the App:

  1. via Zip-Code and
  2. via Distance
As both ways differ slightly in their requirements, the response will differ, depending on the type. Take a look at the schema and the two examples for more details.
If no delivery costs shall be applied, this operation will just return "null".


Some fields are common for both types, these will be explained here.

The minimum amount that the order should have, before it can be send.
The actual costs for the delivery. Has to be added, after the minimumOrderValue-check.
The amount when delivery costs should not be applied anymore. The value is 40, the sum of the cart is 36, then delivery costs apply. Another product is added to the cart, raising the sum to 40 or higher, then no more delivery costs shall be raised. If the value is negative (usually -1), delivery costs always apply.


The delivery costs will be determined by the zip-code chosen by the user. The chosen id of the list-entry has to be transmitted, when you send the order (more info here: Post an Order).

An unique identifier for this zip-code. Needed for validation on the server. If an id with value -1 exists, delivery to other places than defined is possible with the values provided by this id.
The zip-code
The city this zip-code belongs to.
The district of the city this zip-code belong to.
Please note, that it is possible to have multiple definitions for the same zip-code (hence the usage of an id).


The delivery costs will be determined by the distance form the shop to the customer. How you compute this value is up to you, but we suggest using a routing service like Google Maps. The computed distance has to be transmitted, when you send the order (more info here: Post an Order).
The distance type just has one extra key per definition:

Defines the maximum distance for which this definition applies.
You should always use the closest definition that can be applied. E.g. you have three definitions with values 1000, 2000 and 4000, the distance is 1439. In this case, you use the 2000 defintion, because the 1000 definition cannot be applied and 4000 is not the closest possible definition, as 2000 is between 1439 and 4000.

This operation doesn't need a request body, just send an authenticated request to the endpoint to recieve the data.


The order-operation is currently the only endpoint with different behavior depending on the HTTP-verb.

Post an Order

POST https://{DOMAIN}/v1/order

With this operation you can submit an order to the webshop. The order will be validated based on the request schema and the data on the server. This means, that it might happen, that an order will be rejected by the server with a 409 Conflict, because an update of the menu happend in the time between your last update of Get Shop Infos and the submission of the order. Please be prepared for this case.

Operation-specific server responses
201 Created
The order has been successfully validated and is currently awaiting transmission to KassaForte. The response body contains an <order-id> for use with Get Order status.
409 Conflict
The data submitted in the request differs from the data on the server (e.g. unknown ingredient-id). The response-body will contain more information on the error (see Error Codes), so you may be able alter the request, so it validates. It may be nessessary to re-request the menu, if it was updated in the meantime. A complete list of all possible errors can be found at the end of this document.

Get Order status

GET https://{DOMAIN}/v1/order/<order-id>

With this operation you can request the current status of an order. Just replace <order-id> in the endpoint with the order-id supplied by the resonse of Post an Order.

This operation doesn't need a request body, just send an authenticated request to the endpoint to recieve the data.

Operation-specific server responses
400 Bad Request
The supplied order-id did not match the expected format (14-digits).

Check a Discount Code

GET https://{DOMAIN}/v1/discountcode

With this operation you can confirm the validity of a discount code and recieve information about its configuration.
There are currently three types of discount codes:

An amount, by which the sum of the cart should be reduced. The exceptions must be respected.
A percentage, by which the sum of the cart should be reduced. The exceptions must be respected.
A combination of item-number and size, which should be added to the cart without charge.
The exceptions-list specifies categories that are excluded from the discount. That means the prices of products from these categories will not be reduced by a percent-discount and the remaining amount of an amount-discount will be discarded, if it would reduce the price of an protected product.
On article-discounts the exceptions-list will be omitted.

Check a Coupon

GET https://{DOMAIN}/v1/coupon

With this operation you can confirm the validity of a coupon. You send the coupon-number and the corresponding verify-code and get the coupon-number and the remaining amount of the coupon in response.
This amount has to be subtracted from the sum of the cart without exceptions. If the coupon has a higher value than the sum, the coupon will stay valid with the reduced value.

Operation-specific server responses
404 Not Found
No coupon with this number could be found.
409 Conflict
The verifyCode didn't match the one stored in the database.

Send a Contact Request

POST https://{DOMAIN}/v1/contactrequest

This operation enables you to send contact requests directly to KassaForte.

Error Codes

This API validates every order, that is submitted to it. It is possible that the validation fails, if there was an update of the menu or the date has changed (discount code may expire) or something similar. We try to make it possible for you to react to those situations as good as possible.
Every validation error has its own error-code and a (hopefully) meaningful description. Depending on the situation, the description may contain the item-number or id of the element, that caused the error, in a parseable manner (surrounded by #).

<name> are placeholders for the corresponding variable

1xx Error occured while validating the order

No choices have been supplied for #<item-no>#, but choices are mandatory
Computed overall sum of #<our-sum># differs from send sum #<your-sum>#
Invalid payment method #<payment-method>#

2xx Error occured while validating a article

Article #<item-no># has no price for size #<size-id>#
Unknown article #<item-no>#
Computed price of #<our-price># differs from send price #<your-price>#
Ingredient #<ingredient-id># is not allowed in category with id #<category-id>#
Invalid choice #<choice-id>#

3xx Error occured while validating a menu

Menu #<item-no># has no price.
Unknown menu #<item-no>#
Expected item count of <expected-count> differs from actual itemcount of <actual-count>
Computed price of #<our-price># differs from send price #<your-price>#
Can't find a match for article #<item-no># in size #<size-id># in categories of menu #<item-no>"#
Article #<item-no># is not allowed in menus.

4xx Error occured while validating a ingredient

Ingredient #<ingredient-id># has no price for size #<size-id>#
Unknown ingredient #<ingredient-id>#

5xx Error occured while validating a discount-code

Unknown discount #<discount-code>#

6xx Error occured while validating delivery costs

Unknown delivery cost type
Wrong delivery cost type #<delivery-type>#, extected type #<delivery-type>#
Unknown zipId #<zip-id>#
Delivery allowed only to defined zipIds
Minimum order value of #<minimum-sum># not reached with order value of #<your-sum>#
Computed delivery costs of #<our-sum># differs from send delivery costs #<your-sum>#
No data defined for distance #<distance>#


MENU: Added "minimumOrderValue" to "categories". This indicates if producty of this category shall be included in the computation of the minimum order value. This is an integer-field so you can just multiplicate its value this the sum of the product.
ORDER: Changed type of payment method from string to integer, for easier addition of new payment types. The payment method is now the index of this list
MENU: Added Allergens and Additives to the Menu. Both are added as comma-separated lists of indexes to each product and indexed lists to the menu itself.
MENU: Fixed some bugs with menus and choices for products.