Your data
Catalog
Every product the assistant can sell: name, brand, price of the sales unit, net size, weight or pack, stock.
What it does in the conversation
It is the price list the assistant reads at every request. It searches by name, brand, department and barcode; reads the size and the price of the sales unit; decides whether a product is sold by the piece, by weight or only as a whole pack; and checks whether it is available. Every cart line and every order you receive carries the code (sku) of a row of this file.
The price is always the price of what the customer puts in the cart: the pack, the case of six, or the kilo for a product sold by weight without an average piece weight. With «sold by weight» and the average piece weight, «a kilo of apples» becomes the right number of apples; with «pieces per pack» and «whole pack only», «ten bottles» become two cases of six.
«Reliable stock = no» is for fresh counter products (meat, fish, fruit) whose stock you do not count: they stay on sale even at zero stock.
Customer: Can you add ten bottles of still water and a kilo of apples?
Assistant: Done! 🛒 • Acqua naturale 6x1,5l [Fonte Esempio] 2x6x1.5l – €6.60 • Mele Golden 4x250g (1kg) – €2.40 Water is sold in cases of six: for ten bottles I added two cases (twelve bottles). Anything else?
The water has «pieces per pack» 6 and «whole pack only» yes; the apples are sold by weight with an average piece weight of 0.25 kg. Illustrative example, with the products of the template and an invented store.
If it is missing
- Without the code or the name, the row is rejected and the product does not exist for the assistant.
- Without the price, the product has no amount: it stays «to be confirmed» and the customer does not see what it costs.
- Without the brand, the cart line does not say it, and the customer does not recognise their usual product.
- Without the net size (quantity and unit), the size comes from the name; if the name says nothing, the line says «pack» and the customer does not know how much they are buying.
- Without «sold by weight», a product sold by weight is sold as one piece: «a kilo of apples» becomes one apple.
- Without the average piece weight, the assistant does not know how many pieces make a kilo.
- Without «pieces per pack» and «whole pack only», «ten bottles» does not become cases.
- Without «reliable stock = no» on fresh counter products, meat, fish and fruit at zero stock look unavailable.
- Without the department, cart lines are not grouped; without the sub-department, there are no shelf links.
- Without the product page and the image, the reply has no link and no photo.
- A product you no longer sell stays on sale until you switch it off («sold online» = no) or send the file as the whole catalog.
The fields
Required: without it the product is not sold the way the customer expects. Recommended: without it there is a declared fallback, but the experience is poorer. Optional: an improvement.
skurequired- Column in the file
- SKU
- Type
- text
- Example
000201111 · 000301555 · 000405020- Rule
- required, unique in the file, max 128 characters, stable over time
titlerequired- Column in the file
- Product name
- Type
- text
- Example
Pasta Spaghetti n.5 500g · Acqua naturale 6x1,5l · Mele Golden- Rule
- required, as the customer reads it, max 512 characters
brandrequired- Column in the file
- Brand
- Type
- text
- Example
Barilla · Fonte Esempio- Rule
- required (empty = warning, not a rejection)
categoryrecommended- Column in the file
- Department
- Type
- text
- Example
Pasta e riso · Bevande · Frutta e verdura- Rule
- the department: groups the cart lines
subcategoryrecommended- Column in the file
- Subdepartment
- Type
- text
- Example
Pasta secca · Acqua · Frutta- Rule
- the shelf within the department
descriptionoptional- Column in the file
- Long description
- Type
- text
- Example
Mele di montagna, calibro 75-80- Rule
- max 4,000 characters; does not replace the name
gtinoptional- Column in the file
- GTIN (EAN)
- Type
- text
- Example
2000000000015 · 2000000000022- Rule
- 8, 12, 13 or 14 digits with the GS1 check digit
pricerequired- Column in the file
- Selling price
- Type
- number (¤)
- Example
1.29 · 3.30 · 2.40- Rule
- VAT included, of the sales unit (the pack, the case; the kg if sold by weight without an average weight)
min_order_qtyrequired- Column in the file
- Net size (quantity)
- Type
- number
- Example
500 · 9 · 1- Rule
- > 0: net content of the pack sold; by weight, the minimum quantity
min_order_unitrequired- Column in the file
- Net size (unit)
- Type
- symbol
- Example
g · l · kg- Rule
- one of: kg g l ml cl pz
sold_by_weightrequired- Column in the file
- Sold by weight
- Type
- yes/no
- Example
no · sì- Rule
- yes/no: the cart quantity is in units of average weight
avg_piece_weight_kgrecommended- Column in the file
- Average piece weight (kg)
- Type
- number (kg)
- Example
0.25- Rule
- > 0, only for products sold by weight: «1 kg» becomes a number of pieces
items_per_packrequired- Column in the file
- Items per pack
- Type
- integer
- Example
1 · 6- Rule
- integer ≥ 1 (1 if it is not a multipack)
pack_onlyrecommended- Column in the file
- Pack only
- Type
- yes/no
- Example
no · sì- Rule
- yes/no: only the pack is sold (water, beer): «10 bottles» become cases
stock_managedrecommended- Column in the file
- Stock is tracked
- Type
- yes/no
- Example
sì · no- Rule
- yes/no: «no» for fresh counter goods, sellable even at stock 0
unit_priceoptional- Column in the file
- Price per kg or litre
- Type
- number (¤/kg ¤/l)
- Example
2.58 · 0.37- Rule
- > 0, as on the label; never instead of the selling price
gross_weight_kgoptional- Column in the file
- Gross weight (kg)
- Type
- number (kg)
- Example
0.52 · 9.3- Rule
- > 0, packaging included: weighs the cart for the courier and heavy items
tare_kgoptional- Column in the file
- Tare (kg)
- Type
- number (kg)
- Example
0.02- Rule
- ≥ 0
vat_rateoptional- Column in the file
- VAT rate (%)
- Type
- number (%)
- Example
4 · 10- Rule
- 0-100
linkrecommended- Column in the file
- Product page
- Type
- web address
- Example
https://www.esempio.it/p/000201111- Rule
- https:// on the store website
image_linkrecommended- Column in the file
- Image
- Type
- web address
- Example
https://www.esempio.it/img/000201111.jpg- Rule
- https://
diet_tagsoptional- Column in the file
- Dietary tags
- Type
- list
- Example
organic|local- Rule
- separated by |: organic vegan lactose_free gluten_free whole_grain local
is_onlinerequired- Column in the file
- Sold online
- Type
- yes/no
- Example
sì- Rule
- yes/no (empty = yes)
stock_qtyrequired- Column in the file
- Stock
- Type
- number
- Example
120 · 40 · 0- Rule
- ≥ 0, in sales units
Download the template
The first row is the header; the second row (starting with #) describes each column; the three example rows also start with # and are not imported. Column names are recognised in all six languages and by their field name.
Frequent errors and their message
SKU_MANCANTE«The product code is missing.»
What to do: Every row needs the code your till or management system uses, always the same over time.
TITLE_MANCANTE«The product name is missing.»
What to do: Write the name as the customer reads it on the shelf.
PREZZO_NON_VALIDO«The price must be a number, zero or more.»
What to do: Only the number, without the currency symbol: 1.29 or 1,29.
NUMERO_AMBIGUO«This number reads two ways: write it without the thousands separator, or with two decimals.»
What to do: Use the same decimal separator in the whole file and no thousands separator.
BOOLEANO_NON_VALIDO«Yes or no is needed here.»
What to do: Write yes/no (or sì/no, 1/0) in «sold by weight», «whole pack only», «reliable stock», «sold online».
UNITA_NON_AMMESSA«The net size unit must be one of: kg, g, l, ml, cl, pz.»(explanation of this guide: Core returns the code)
What to do: Units go with their symbol: GroceryAI reads no words in any language to understand a unit.
GTIN_NON_VALIDO«The barcode is not valid: check the digits.»
What to do: 8, 12, 13 or 14 digits with the GS1 check digit; leave it empty if you do not have it.
OFFERTA_SUPERIORE_AL_PREZZO«The offer price is higher than the price: check the two columns.»
What to do: The selling price is the full price; the offer price is the lower one.
How to send it
- From the portalIn part
Today: Products → upload a CSV file; the page's own template has code, name, price, barcode, brand, department, stock and sold online, and the preview shows rows to fix with their number and reason before anything is written. Coming: this guide's 24-column template, the Excel workbook, the # rows skipped, and «this file is the whole catalog».
- From the APIAvailable
PUT /v1/products (permission catalog:write), up to 500 products per batch: each product updates only the fields it carries; a field sent as null is removed. DELETE /v1/products/{sku} withdraws a product (switched off, never deleted). Snapshots (POST /v1/products/snapshots) withdraw what the whole catalog no longer carries.
- Scheduled feedAvailable
PUT /v1/catalog/feed with the address of your file: we read it every 24 hours (or every_hours). Our CSV or Excel template, or the Google Merchant / Meta Commerce product feed (XML or TSV) as it is.
Availability as measured on the live service on 30 October 2026.
Update two products (only the fields you send change)
curl
curl -X PUT "https://oxjqgjbiltoviwldailg.supabase.co/functions/v1/core-api/v1/products" \
-H "Authorization: Bearer $GAI_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: listino-2026-11-02" \
-d '{"products":[{"sku":"000201111","title":"Pasta Spaghetti n.5 500g","brand":"Barilla","price":1.29,"min_order_qty":500,"min_order_unit":"g","items_per_pack":1,"stock_qty":120},{"sku":"000301555","title":"Acqua naturale 6x1,5l","price":3.30,"items_per_pack":6,"pack_only":true}]}'Node.js (18+)
const risposta = await fetch("https://oxjqgjbiltoviwldailg.supabase.co/functions/v1/core-api/v1/products", {
method: "PUT",
headers: {
Authorization: `Bearer ${process.env.GAI_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
products: [
{ sku: "000201111", title: "Pasta Spaghetti n.5 500g", brand: "Barilla", price: 1.29,
min_order_qty: 500, min_order_unit: "g", items_per_pack: 1, stock_qty: 120 },
{ sku: "000301555", title: "Acqua naturale 6x1,5l", price: 3.3, items_per_pack: 6, pack_only: true },
],
}),
});
console.log(risposta.status, await risposta.json());