Skip to content
Open menu
Supplier integration guideLevel 1

Level 1 · Required

Level 1 — products, prices and stock.

Three feeds — product data, prices and stock availability — joined on identifiers that never change. This is the mandatory foundation, and no other level can be validated until it passes.

It is what puts your catalogue on the network: once it is in place, any distributor on the platform can find your products, see what they cost and see what is available. Transport, encoding and identifier rules are not repeated here — they are in the transport and formats document and apply to all three feeds.

Document
SPEC-L1-001
Revised
8 September 2026
Depends on
Nothing
§1.0

The feed set

Product dataL1—Defines your models and their sellable variants. The other two feeds are meaningless without it.
Product pricesL1ProductCodeQuantity-break net pricing, per variant.
Stock availabilityL1ProductCodeCurrent quantities, optionally per warehouse.

All three feeds must use identical identifier values

A price or stock row naming a ProductCode we do not know is rejected with E-3xx. It is not held pending a later product feed, so the order you send them in does not rescue a mismatch.

§2.0

Product data fields

ModelCodestringL1The stable identifier grouping variants. Unique per model. Immutable.
ProductCodestringL1SKU-level identifier. Unique per variant, 1:N under a ModelCode. Immutable.
ProductNamestringL1The human-readable name. 256 characters or fewer.
ColorstringL1Free text or normalised — Navy, PMS 281. Supply ColorCode alongside it where you have one.
SizestringL1Where applicable — apparel, bags. Use consistent tokens across the catalogue.
Capacitystring / numberL1Where applicable, e.g. 500 ml. Prefer CapacityValue and CapacityUnit as two fields.
ImageURLurlL1At least 1000 px on the longest side. JPG or PNG, and a white or transparent background is preferred.
CategoryPathstringRecommendedFormatted Top > Sub > Leaf.
BrandstringRecommended256 characters or fewer.
DescriptionHTMLstring—Must be valid HTML. 4,096 characters or fewer.
Materialstring—Comma-separated where there is more than one.
Keywordsstring—Comma-separated.
CountryRestrictionsstring—ISO 3166-1 alpha-2, comma-separated. Enforcement requires the Premium tier or higher.

One row per sellable variant

Not one row per model. A catalogue flattened to model level has no orderable variant in it, which is the most common reason a first Level 1 submission is sent back.

§3.0

Price fields

ProductCodestringL1Must resolve against the product feed.
CurrencyISO 4217L1EUR, CZK, GBP. One currency per feed unless another arrangement is agreed.
QtyBreakintegerL11 or more. Strictly increasing per ProductCode, with no overlaps.
UnitPricedecimalL1The net unit price at that break. Two decimal places, point separator.
ListPricedecimal—The recommended retail price, if you publish one.
ValidFrom / ValidToISO 8601—Treated as open-ended when omitted.
CustomerPriceGroupstring—Individual customer pricing requires the Premium tier or higher.
§4.0

Stock availability fields

ProductCodestringL1Must resolve against the product feed.
InStockintegerL1The current physical quantity. A negative value is rejected.
WarehouseCodestring—Defaults to MAIN. Quantities across warehouses are summed for display.
OnOrderinteger—Inbound quantity not yet available.
ETAISO 8601 date—Expected arrival of the OnOrder quantity. Required when OnOrder is greater than zero.

Stock is the feed that fails visibly

Distributor webshops show availability to end customers in real time, so a stale quantity becomes an order against something you have already sold. The refresh limits are in §3.0 of the transport and formats document; a nightly batch meets none of them. Where your ERP cannot export more often, expose a stock-by-SKU endpoint we can poll for deltas instead of regenerating the whole file.

§5.0

Validation rules

These are the codes the validation report prints. Quote one in an email and we will be looking at the same rule.

ModelCode is not uniqueE-101Row rejected. Duplicate values are reported with their line numbers.
ProductCode is not uniqueE-102Row rejected. The first occurrence is retained.
Color, Size or Capacity empty on a variant-driven lineE-110Row rejected, or mapped to Default where a per-catalogue mapping is agreed.
ImageURL does not return HTTP 200W-401Row accepted and the asset retried next cycle. Persistent failure escalates to E-401.
ImageURL has the wrong MIME typeE-402The asset is dropped. It must be image/jpeg or image/png.
CapacityValue without CapacityUnitE-120Row rejected. The pair is all or nothing.
A control character in a text fieldE-201Row rejected.
Field length exceededE-202Row rejected. 256 for a code, 4,096 for a description.
A price row names an unknown ProductCodeE-301Row rejected. The previous pricing for that variant is retained.
QtyBreak overlaps or does not increaseE-204Row rejected. The previous pricing is retained.
§6.0

A minimal record

One variant, its two price breaks and its stock. JSON here for readability; CSV and XML carry the same fields, one row per record.

Level 1 · Product data · one variantproduct.jsonJSON
{
  "ModelCode": "POLO-CLASSIC",
  "ProductCode": "POLO-CLASSIC-BLK-M",
  "ProductName": "Classic Cotton Polo",
  "Color": "Black",
  "Size": "M",
  "CategoryPath": "Apparel > Polos",
  "Brand": "Example Co.",
  "Material": "Cotton 100%",
  "ImageURL": "https://cdn.example.com/polo-classic-blk.jpg"
}
The required fields plus the recommended metadata. Everything else in §2.0 is optional.
Level 1 · Prices · two breaksprices.jsonJSON
[
  { "ProductCode": "POLO-CLASSIC-BLK-M", "Currency": "EUR", "QtyBreak": 1, "UnitPrice": 7.90 },
  { "ProductCode": "POLO-CLASSIC-BLK-M", "Currency": "EUR", "QtyBreak": 250, "UnitPrice": 6.40 }
]
Breaks strictly increase per ProductCode. An overlap is rejected with E-204 and your previous pricing stands.
Level 1 · Stock · one warehousestock.jsonJSON
[
  { "ProductCode": "POLO-CLASSIC-BLK-M", "WarehouseCode": "MAIN", "InStock": 1250,
    "OnOrder": 400, "ETA": "2026-08-12" }
]
ETA is required whenever OnOrder is greater than zero.

Send twenty variants before you send the catalogue

A sample exercising every field you intend to populate settles the contract in one round. Run the Level 1 checklist first — it names what to assemble and the six patterns that account for most rejections.