Skip to content
Open menu
Supplier integration guideTransport & formats

Reference · All levels

Transport, formats and identifiers.

The rules that apply to every feed at every level. Where a per-level specification is silent on encoding, delivery or identifier behaviour, the rules here govern.

Read this before you write the exporter rather than after. Most of what makes a first submission fail is settled here — a file that mixes two record shapes, a partial upload that was parsed halfway, a date with no offset — and none of it is visible in a field table.

Document
REF-FMT-010
Revised
8 September 2026
Encoding
UTF-8
§1.0

Accepted feed formats

CSVRFC 4180L1–L4UTF-8, header row required, comma delimiter, double-quote escaping. One structure per file.
XMLXSD on requestL1–L4UTF-8, a single root, no external entity references. One structure per file.
JSONRFC 8259L1–L4UTF-8, an array of records or NDJSON. One structure per file.
RESTOpenAPI 3.xL5JSON payloads only. The specification is issued per supplier.

One structure per feed

A single file must contain one record shape. Do not concatenate products and prices into one export, and do not vary the column set between rows of the same file — both are rejected at parse time, before any field validation runs.

§2.0

Delivery methods

HTTPS pullWe fetchYours, or an open URLL1–L4The default. One stable URL per feed, TLS 1.2 or higher, returning 200 with the full current snapshot.
SFTP pushYou sendWe issue themL1–L4Write to the directory we assign, and rename atomically on completion. A partial file is skipped rather than parsed.
API pollWe fetchOAuth2 or bearerL5We honour Retry-After. Cursor or timestamp pagination is required above 10,000 records.
WebhookYou notifyA shared secretL5Respond 2xx within 500 ms and queue the processing asynchronously. A synchronous ERP write causes retry cascades.
§3.0

Refresh cadence

Catalogue and stock are read on separate schedules. The values below are the maximum permitted age of the data at the moment a distributor queries it, and they are set by your membership tier.

PremiumEvery 2 weeksEvery 4 hoursThe stock export must run unattended.
GoldWeeklyHourlyAn hourly stock delta, or an endpoint we can poll.
PlatinumWithin 24 hoursEvery 5–10 minutesStock must be queried live rather than exported.

What each tier costs and what else it decides is on the membership page. Nothing in a feed changes the cadence — it is a property of your export and of your tier, not of the ingest.

§4.0

Identifiers

ModelCode1 per modelNoGroups variants. Unique across the product feed. Referenced by Level 2 print options.
ProductCode1 per variantNoSKU level. Unique across the product feed, 1:N under a ModelCode. Referenced by price, stock, Level 3 coordinates and Level 5 order lines.
PositionCodeN per modelNoA print position. Defined at Level 2, consumed at Levels 3 and 4.
TechniqueCodeN per positionNoA decoration technique. Must resolve against the value list in §2.0 of the Level 2 specification.
WarehouseCodeN per variantYesOptional. Defaults to MAIN when omitted.

Immutable means never reused, either

A code marked not mutable must never change value and must never be reused for a different item. A changed code is interpreted as a deletion plus a creation, which orphans every print, coordinate and pricing row attached to the previous value.

§5.0

Standards and encoding

Character encodingUTF-8No byte-order mark is required and one is tolerated. Control characters are disallowed in every text field.
CurrencyISO 4217A three-letter code. One currency per price feed, unless a per-row currency column is agreed.
Dates and timestampsISO 8601A date, or a date-time with an offset. Local time without an offset is rejected.
Country codesISO 3166-1 alpha-2Used by the restriction and origin fields.
DecimalsPoint separatorTwo decimal places for money. No thousands separators and no currency symbol inside the value.
Field length—256 characters for a code, 4,096 for a description.
§6.0

What a validation outcome means

Four outcome classes. Which one a submission gets depends on how much of it failed, not on which rule it broke.

AcceptedEvery row passes. The feed is applied in full.
Accepted with warningApplied, with non-conforming optional values dropped and logged.
Row rejectedIndividual rows fail and the rest is applied. Every rejected row is listed in the report.
Feed rejectedThe rejection ratio exceeded tolerance. Nothing is applied and your previous snapshot is retained.
§7.0

Conditions and their codes

A required field is missingE-1xxRow rejected, the feed continues. The row and the field are named in the report.
A type or format violationE-2xxRow rejected. The prior value for that row is retained.
An unresolved join keyE-3xxRow rejected. This is what a price, stock or coordinate row naming an unknown ProductCode gets.
An unknown enum valueW-3xxThe value is dropped, the row is accepted, and a warning is logged.
An unreachable asset URLW-4xxRow accepted and the asset retried on the next cycle. Persistent failure escalates to E-4xx.
A parse failureE-900The whole feed is rejected before field validation runs. Nothing is applied in part.

Every report names the correction, not only the fault

A validation report identifies the affected row, the affected field, the failing rule and what to do about it. Reports are retained for seven days.

Get these right once and every level inherits them

Encoding, delivery and identifiers are the same at every level, so a mistake here is a mistake in all of your feeds at once — and most of what makes a first submission fail is settled on this page rather than in a field table.