Product API
Required. One endpoint that returns the venue's complete, current product list.
Required and Optional Data
| Data | Required | Notes |
|---|---|---|
| Identifier | Yes | Stable and never reused. The Cheers product is linked to this value -- if it changes, the link is lost and the product appears as a new, unmatched one. |
| Name | Yes | Used for display and to help the partner match products. |
| Gross price | Yes | In the major currency unit -- for HUF that means forints, without decimals. Not minor units (no fillér, no cents). |
| VAT rate | Yes | As a percentage. See VAT rates. |
| Takeaway VAT rate | No | If absent, no separate takeaway price is handled. |
| Stock information | No | Boolean or a status value (e.g. ACTIVE, available). If absent, stock sync stays disabled. |
| Currency | No | Assumed to be HUF if absent. |
| Description, category, barcode, tags, unit of measure | No | Stored as supplementary data and shown to the partner in the Cheers CMS. |
VAT Rates
Send the rate as a percentage, not as a multiplier or a tax code.
- Supported: integer values from
0to27, plus5.5,7.7and9.5. - Anything else: Cheers assumes
27.
A value such as A, TAX_1 or 3 (meaning "the third VAT band") cannot be interpreted and
falls back to 27%. If your POS stores VAT as a code, resolve it to a percentage before
responding.
What You Are Free to Choose
Response Shape
A plain JSON array or an object wrapping the array under data, results or content -- all
four are in live use.
Field Names and Language
Entirely up to you. One live integration returns Hungarian field names; the adapter maps them.
HTTP Method
Typically GET, but POST with a request body is equally acceptable.
Pagination
Not required. If you do not paginate, Cheers requests the whole list in one call.
If you do paginate, two things are mandatory:
- Signal whether more pages exist -- e.g. a
last: trueflag, anextURL, or a total page count. - Order deterministically -- the same query must return items in the same order across pages. Without a stable sort, products shift between pages while Cheers is walking them and some are never seen.
Examples
All three of these are accepted. They differ only in shape.
Plain array
[
{
"id": "SKU-1042",
"name": "Draft Beer 0.5L",
"price": 1890,
"vat": 27
},
{
"id": "SKU-1043",
"name": "Mineral Water 0.33L",
"price": 690,
"vat": 27,
"takeawayVat": 5,
"available": true
}
]
Wrapped in an object
{
"data": [
{
"cikkszam": "SKU-1042",
"megnevezes": "Csapolt sör 0,5L",
"bruttoAr": 1890,
"afaKulcs": 27,
"keszleten": true
}
]
}
Paginated
{
"content": [
{ "id": "SKU-1042", "name": "Draft Beer 0.5L", "price": 1890, "vat": 27 }
],
"page": 0,
"size": 100,
"totalElements": 254,
"last": false
}
Recommended schema
If you are building this endpoint from scratch and have no existing shape to preserve, the following needs no clarification on our side and is the fastest path to a working adapter.
{
"id": "SKU-1042",
"name": "Draft Beer 0.5L",
"price": 1890,
"vat": 27,
"takeawayVat": 5,
"currency": "HUF",
"available": true,
"description": "Locally brewed lager",
"category": "Beers",
"barcode": "5998765432109",
"unit": "pcs"
}
Do not restructure an existing endpoint to match it. Any other naming, nesting or language is equally accepted -- the adapter is written per POS. Only the content requirements in the table above are binding.
Variants
If a product has several variants, sizes or packagings, each variant needs its own identifier and its own price. In Cheers every variant becomes a separate product.
[
{ "id": "SKU-1042-05", "name": "Draft Beer 0.5L", "price": 1890, "vat": 27 },
{ "id": "SKU-1042-03", "name": "Draft Beer 0.3L", "price": 1390, "vat": 27 }
]
A single product carrying a list of sizes without individual identifiers cannot be imported -- Cheers has no stable value to link each variant to.
Modifiers
Modifiers (add-ons, options, extras -- "extra lemon", "no ice", "double shot") may be returned either on a separate endpoint or embedded in the product. Both work.
Modifiers also become separate products in Cheers, so each one requires an identifier, a name and a price:
{
"id": "SKU-1042",
"name": "Draft Beer 0.5L",
"price": 1890,
"vat": 27,
"modifiers": [
{ "id": "MOD-01", "name": "Extra lemon", "price": 150, "vat": 27 },
{ "id": "MOD-02", "name": "No ice", "price": 0, "vat": 27 }
]
}
When an order comes back through Counter Order, the modifier
productId is exactly the identifier you sent here -- no mapping needed on your side.
Processing Rules
Always return the full current list
Every sync compares your complete response against the previous one. A product that is absent from the current response is flagged in the CMS as "disappeared from the POS".
This means you must return the entire current catalogue every time -- never a delta, never "only what changed since last time". Sending a changes-only response would flag the entire rest of the catalogue as missing.
Price and stock sync overwrite Cheers data
If the partner enables price sync, the price from your response replaces the price on the Cheers product. The same applies to stock. So the price you return must always be the real, current gross selling price -- not a list price, not a net price, not a historical one.
Duplicate identifiers
If the same identifier appears more than once in a response, Cheers keeps the first occurrence and discards the rest.