Products
Product CSV format, validation, pricing, stock, pack sizes, images, categories, and search behaviour.
Overview
The product importer is a full catalogue snapshot for one store. Each row creates or updates a product, keyed by SKU.
Products missing from the file are hidden from the storefront. They are restored, with the values from the file, when their SKU reappears in a later import.
The background job processes uploaded product files about every 15 minutes.
File format
- Header row required. Headers are case-insensitive.
- Unknown columns are ignored. Duplicate headers are rejected.
- Files must be UTF-8. A leading UTF-8 BOM is allowed.
Columns
SKU, TITLE, and PRICE are required. All other columns are optional.
| Column | Required | Rules |
|---|---|---|
SKU | Yes | Product code and the key for updates. Must not contain ~. Matching is case-sensitive. If the same SKU appears more than once, the last row wins. |
TITLE | Yes | Product name, 1-255 characters. Shown on all product listings, searchable, and the default catalogue sort. |
PRICE | Yes | The standard price. See money values below. |
CATEGORY_IDS | No | Pipe-separated category IDs, e.g. drinks|soft-drinks. Each ID must match a CATEGORY_ID from the category CSV (case-insensitive). Unknown IDs are ignored. Parent categories are linked automatically. |
VAT | No | VAT percentage from 0 to 100 with up to 1 decimal place, e.g. 20.0. No % sign. If the column is present, every row must have a value - leave the whole column out if unused. |
SPECIAL_PRICE | No | Offer price, same format as PRICE. Shown only when lower than the price the customer would otherwise pay. Requires the special pricing feature. |
IMAGE_URL | No | Pipe-separated list of public image URLs. The first URL is the main image; the rest appear in the product page gallery. |
UNITS | No | Pack description shown as the pack size, e.g. 24 x 330ml. When blank, the pack size is built from UNITS_PER_CASE and UNIT_SIZE. |
UNIT_SCALE | No | Quantity step for ordering, a positive number. Defaults to 1. |
UNIT_SIZE | No | Size of a single unit, e.g. 330ml. |
UNITS_PER_CASE | No | Number of units in a case. Whole-number values also enable POR calculations. |
STOCK | No | Stock level, 0 or greater. Defaults to 9999. Negative values are treated as 0. Drives the store's stock and low-stock indicators. |
MAX_QTY | No | Maximum quantity per order line. Defaults to 9999. |
MIN_QTY | No | Minimum order quantity. Defaults to 0. Must not exceed MAX_QTY when both are set. Enforced only when minimum quantities are enabled for the store. |
SHORT_DESCRIPTION | No | Short description shown on product listings. |
DESCRIPTION | No | Full description shown on the product page. |
BRAND | No | Brand name. Searchable. |
BARCODES | No | Pipe-separated barcodes. Barcode search matches each value exactly. |
PROMOTED | No | 1, true, or yes marks the product as promoted: it gains the store's promotion badge and sorts first. Defaults to no. |
BADGE_ONE | No | 1, true, or yes adds the store's second promotion badge. Defaults to no. |
KEYWORDS | No | Extra search terms, up to 2048 characters. |
RESTRICTED_TYPES | No | ALCOHOL or TOBACCO hides the product in the native mobile apps. Other values have no effect. |
SPONSORED | No | 1, true, or yes marks the product as sponsored for boosted placement in search results. Defaults to no. |
RANK | No | Whole number, 1 or greater. Orders sponsored products - lower ranks appear first. |
RRP | No | Recommended retail price for a single unit, same format as PRICE. Enables POR display. |
Boolean columns (PROMOTED, BADGE_ONE, SPONSORED) accept 1, true, or yes, and 0, false, or no. A blank cell means no. Any other value fails validation.
Pipe-separated columns (CATEGORY_IDS, IMAGE_URL, BARCODES) have no escaping mechanism, so individual values cannot contain a literal |.
Money values
PRICE, SPECIAL_PRICE, and RRP accept currency values with up to 2 decimal places, from 0 to 9,999,999.99:
- Currency symbols and thousands separators are tolerated:
£1,234.56and1234.56are both read as 1234.56. - A third decimal place rounds half-up:
1.005becomes1.01. - Do not use a comma as the decimal separator:
12,34is read as 1234. - Negative prices are rejected.
VAT and UNIT_SCALE are stricter: plain numbers only, with no symbols or separators.
Pack size display
The pack size shown on product listings is built from three columns:
UNITS, verbatim, when set - e.g.24 x 330ml.- Otherwise
UNITS_PER_CASE x UNIT_SIZE- e.g.24 x 330mlfrom24and330ml. - Otherwise
UNIT_SIZEorUNITS_PER_CASEalone, or-when all three are blank.
POR
POR (profit on retail) shows customers the retail margin a product offers. It is calculated when all three of RRP, VAT, and a whole-number UNITS_PER_CASE are provided:
POR % = (RRP × UNITS_PER_CASE − price including VAT) ÷ UNITS_PER_CASE ÷ RRP × 100The price used is the price that customer actually pays: their customer-specific price or the special price when one applies, otherwise the standard price. Products can also be sorted by POR on the storefront.
Categories and search
CATEGORY_IDS places the product in the category tree from the category CSV. Linking a subcategory automatically links all of its parents, so a product in drinks|soft-drinks also appears when browsing drinks.
Product search matches against the SKU, title, brand, the titles of the product's categories, KEYWORDS, and barcodes.
Validation
Product imports are all-or-nothing. If one row fails validation, the whole file is rejected and nothing is imported.
When validation fails, the Import log shows a failure report with the rejected rows and reasons.
How updates are applied
Rows in the file are upserted as purchasable products. Every listed field is rewritten on each import, so include every column you use, populated, in every file - a blank or missing optional column resets that field to its default on every product in the file.
Purchasable products missing from the file are hidden from the storefront but keep their stored values, and are restored when their SKU reappears.
A file that is valid but contains no data rows counts as an empty snapshot and hides every product in the store. Always send the complete catalogue.
Some stores run on the legacy v2 product feed, which preserves existing descriptions when DESCRIPTION or SHORT_DESCRIPTION is blank. On the current feed, a blank always overwrites. Check with ProConnect if you're unsure which feed your store uses.
Example
SKU,TITLE,PRICE,CATEGORY_IDS,VAT,STOCK,BRAND,UNITS_PER_CASE,UNIT_SIZE,RRP
SKU-001,Still Water 500ml,3.99,drinks|water,20.0,120,Acme,24,500ml,0.79
SKU-002,Orange Juice 1L,5.49,drinks|soft-drinks,20.0,80,Acme,6,1L,1.85Download the sample product CSV for a template that includes every column.