Skip to content

Catalogue

The catalogue is what the point of sale shows and what every sale line refers back to. An item belongs to a category, a brand and a tax; a menu decides which items a channel sees; modifiers add the questions asked at the till.

MethodPathScope
GET/v1/itemsitems.read
GET/v1/items/:iditems.read
POST/v1/itemsitems.write
PATCH/v1/items/:iditems.write
GET/v1/categoriescategories.read
POST/v1/categoriescategories.write
PATCH/v1/categories/:idcategories.write
GET/v1/brandsbrands.read
POST/v1/brandsbrands.write
PATCH/v1/brands/:idbrands.write
GET/v1/modifiersmodifiers.read
POST/v1/modifiersmodifiers.write
PATCH/v1/modifiers/:idmodifiers.write
GET/v1/menusmenus.read
GET/v1/menus/:id/fullmenus.read
POST/v1/menus/create-with-itemsmenus.write
PATCH/v1/menus/:id/update-with-itemsmenus.write
GET/v1/combo-slotsmeal_slots.read
POST/v1/combo-slotsmeal_slots.write
PUT/v1/items/:id/mealmeal_slots.write

An item cannot exist before the rows it points at. For a new catalogue, create in this order:

  1. TaxesPOST /v1/taxes. See taxes.
  2. CategoriesPOST /v1/categories.
  3. BrandsPOST /v1/brands.
  4. ItemsPOST /v1/items, referencing the ids above.
  5. ModifiersPOST /v1/modifiers, attaching them to items.
  6. MenusPOST /v1/menus/create-with-items, selecting items per channel.

Syncing an existing catalogue? Read the merchant’s current categories, brands and taxes first and map onto them. Creating duplicates of rows the merchant already curates is the most common review failure.

Terminal window
curl -s "$API_BASE_URL/categories" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "groupName": "Hot drinks", "priority": 10, "kitchenId": 2 }'
FieldTypeRequiredNotes
groupNamestringyesUp to 50 characters, unique in practice
prioritynumbernoDisplay order; lower sorts first. Default 0
kitchenIdnumbernoRoutes the category’s tickets to a kitchen printer or KDS
statusnumberno1 active (default), 0 hidden
favouritenumberno1 pins the category on the till’s quick grid
IsEBTnumbernoUS only — marks the category as EBT-eligible
Terminal window
curl -s "$API_BASE_URL/brands" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "brand": "House", "priority": 1 }'

brand (≤ 50 characters) is the only required field; priority and status behave as they do on categories. Every item needs a brand — merchants that do not think in brands keep a single House row.

Terminal window
curl -s "$API_BASE_URL/items" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"item": "Flat White",
"groupId": 12,
"brandId": 1,
"uomId": 1,
"taxId": 3,
"rate": 3.75,
"mrp": 4.00,
"barcode": "8901234567890",
"ItemCode": "COF-FW-REG",
"Description": "Double ristretto, steamed milk",
"stockable": 0,
"CanOnlineSale": 1,
"IsVeg": true,
"kitchenId": 2
}'
FieldTypeRequiredNotes
itemstringyesDisplay name, up to 100 characters
groupIdnumberyesCategory id
brandIdnumberyesBrand id
uomIdnumberyesUnit of measure id
taxIdnumberyesSales tax row applied at the till
item1stringnoSecondary name — used for a second language on receipts
ratenumbernoSelling price
mrpnumbernoMaximum retail price, where regulation requires it printed
barcodestringnoSingle barcode. One value, not a list
ItemCodestringnoYour own SKU. The field to correlate on when syncing
hsnstringnoTax classification code (HSN/SAC), up to 35 characters
DescriptionstringnoLong description for online channels
statusnumberno1 active (default), 0 inactive
stockablenumberno1 tracks stock, 0 does not
canSalenumberno0 hides the item from the till while keeping it for recipes
CanOnlineSalenumberno1 exposes the item to online ordering
kitchenIdnumbernoOverrides the category’s kitchen routing
hasBatchnumberno1 enables batch tracking
ExpiryTracknumberno1 requires expiry dates on receipt
weighingScalenumberno1 for scale-priced goods
serialNonumberno1 requires a serial number per unit
favouritenumberno1 pins the item on the till’s quick grid
IsVegbooleannoVegetarian marker used on menus
IsServicebooleannoService line rather than a physical good
IsAlcaholbooleannoAlcohol marker (spelling is part of the wire contract)
PurchTaxIdnumbernoPurchase-side tax, when it differs from the sales tax
cessId, Tax4IdnumbernoAdditional levies in jurisdictions that use them
201 Created
{
"data": {
"id": 8841,
"item": "Flat White",
"groupId": 12,
"brandId": 1,
"uomId": 1,
"taxId": 3,
"rate": 3.75,
"status": 1
}
}
Terminal window
curl -s "$API_BASE_URL/items?search=flat&groupId=12&status=1&limit=100" \
-H "Authorization: Bearer $ACCESS_TOKEN"
ParameterNotes
searchMatches name, code and barcode
groupIdOne or more category ids, comma-separated
brandId, taxIdSingle id
status1 or 0
stockStatusinStock, low or out
page, limit, sort, orderStandard paging

PATCH accepts any subset of the create fields:

Terminal window
curl -s -X PATCH "$API_BASE_URL/items/8841" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "rate": 3.95 }'

Deactivate rather than delete — {"status": 0} keeps the item’s sales history intact while removing it from the till.

A modifier group is a question — “Milk?”, “Add extras” — with options, attached to the items that should ask it.

Terminal window
curl -s "$API_BASE_URL/modifiers" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"modifier": "Milk",
"Type": 0,
"Min": 1,
"Max": 1,
"DisplayOrder": 1,
"Options": [
{ "item": "Whole", "rate": 0, "PreDefault": true },
{ "item": "Oat", "rate": 0.40 },
{ "item": "Soy", "rate": 0.40 }
],
"ItemIds": [8841]
}'
FieldTypeRequiredNotes
modifierstringyesGroup label, up to 45 characters
Typenumberyes0 single choice, 1 multiple choice
Min / MaxnumbernoSelection bounds. Min: 1 makes the question mandatory
HasMaxnumberno1 enforces Max
IncludeQtynumberno1 lets the cashier pick a quantity per option
DisplayOrdernumbernoOrder among an item’s modifier groups
Options[].itemstringyesOption label
Options[].ratenumbernoPrice delta at the till
Options[].Rate1 / Rate2numbernoTakeaway and delivery price deltas
Options[].PreDefaultbooleannoPre-selected option
Options[].Max / QtynumbernoPer-option quantity cap and default quantity
Options[].ItemIdnumbernoLinks the option to a stocked item so it depletes inventory
ItemIdsnumber[]noItems this group is attached to

A menu is a named selection of items with optional timings and channel flags. Use it to give delivery a different list from the dine-in till.

Terminal window
curl -s "$API_BASE_URL/menus/create-with-items" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"Menu": "All day",
"Description": "Everything except breakfast-only lines",
"Status": true,
"Online": true,
"Delivery": true,
"Takeaway": true,
"StoreIds": [1, 2],
"Timings": [{ "days": [1,2,3,4,5], "fromTime": "07:00", "toTime": "22:00" }],
"Items": [
{ "itemId": 8841, "variantId": 0 },
{ "itemId": 8842, "variantId": 0 }
]
}'
FieldTypeRequiredNotes
MenustringyesName, up to 45 characters
Descriptionstringyes
StatusbooleannoDefault true
Online, Delivery, TakeawaybooleannoChannel flags, default false
StoreIdsnumber[]noEmpty or omitted means every store
Timings[].daysnumber[]no0 Sunday through 6 Saturday
Timings[].fromTime / toTimestringnoHH:mm, store-local
Items[].itemIdnumberyes
Items[].variantIdnumberyes0 when the item has no variants

GET /v1/menus/:id/full returns the menu with its items and timings expanded — this is the read the Online Order API uses for menu sync.

Combo meals are built from slots: “pick a main”, “pick a side”, “pick a drink”.

Terminal window
# 1. Define a slot with its options
curl -s "$API_BASE_URL/combo-slots" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"name": "Choose a side",
"minSelect": 1,
"maxSelect": 1,
"allowRepeat": 0,
"options": [
{ "childItemId": 8850, "qty": 1, "isDefault": 1, "displayOrder": 1 },
{ "childItemId": 8851, "qty": 1, "extraPrice": 0.50, "displayOrder": 2 }
]
}'
# 2. Attach slots to the combo item
curl -s -X PUT "$API_BASE_URL/items/8900/meal" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "slots": [{ "slotId": 4, "displayOrder": 1 }] }'
FieldTypeRequiredNotes
namestringyesSlot label shown at the till
minSelect / maxSelectnumbernoSelection bounds for the slot
allowRepeatnumberno1 allows the same option more than once
options[].childItemIdnumberyesThe item offered in this slot
options[].childVariantIdnumberno0 when the item has no variants
options[].qtynumbernoUnits of the option included, default 1
options[].extraPricenumbernoSurcharge when this option is chosen
options[].isDefaultnumberno1 pre-selects the option
options[].displayOrdernumbernoOrder within the slot

On PUT /v1/items/:id/meal, slots attaches slot definitions (slotId, plus optional minSelect, maxSelect, displayOrder), fixed lists items always included in the combo (itemId, qty), and upsells offers paid additions triggered by a chosen item (triggerItemId, slotId, label).