Supplier integration guideTransport & formats
Start here
Before you build
Specifications
After you submit
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
Accepted feed formats
| Format | Conformance | Levels | Constraint |
|---|---|---|---|
| CSV | RFC 4180 | L1–L4 | UTF-8, header row required, comma delimiter, double-quote escaping. One structure per file. |
| XML | XSD on request | L1–L4 | UTF-8, a single root, no external entity references. One structure per file. |
| JSON | RFC 8259 | L1–L4 | UTF-8, an array of records or NDJSON. One structure per file. |
| REST | OpenAPI 3.x | L5 | JSON 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.
Delivery methods
| Method | Direction | Credentials | Levels | Notes |
|---|---|---|---|---|
| HTTPS pull | We fetch | Yours, or an open URL | L1–L4 | The default. One stable URL per feed, TLS 1.2 or higher, returning 200 with the full current snapshot. |
| SFTP push | You send | We issue them | L1–L4 | Write to the directory we assign, and rename atomically on completion. A partial file is skipped rather than parsed. |
| API poll | We fetch | OAuth2 or bearer | L5 | We honour Retry-After. Cursor or timestamp pagination is required above 10,000 records. |
| Webhook | You notify | A shared secret | L5 | Respond 2xx within 500 ms and queue the processing asynchronously. A synchronous ERP write causes retry cascades. |
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.
| Membership tier | Catalogue data | Stock | Practical implication |
|---|---|---|---|
| Premium | Every 2 weeks | Every 4 hours | The stock export must run unattended. |
| Gold | Weekly | Hourly | An hourly stock delta, or an endpoint we can poll. |
| Platinum | Within 24 hours | Every 5–10 minutes | Stock 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.
Identifiers
| Identifier | Cardinality | Mutable | Rule |
|---|---|---|---|
| ModelCode | 1 per model | No | Groups variants. Unique across the product feed. Referenced by Level 2 print options. |
| ProductCode | 1 per variant | No | SKU level. Unique across the product feed, 1:N under a ModelCode. Referenced by price, stock, Level 3 coordinates and Level 5 order lines. |
| PositionCode | N per model | No | A print position. Defined at Level 2, consumed at Levels 3 and 4. |
| TechniqueCode | N per position | No | A decoration technique. Must resolve against the value list in §2.0 of the Level 2 specification. |
| WarehouseCode | N per variant | Yes | Optional. 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.
Standards and encoding
| Concern | Standard | Constraint |
|---|---|---|
| Character encoding | UTF-8 | No byte-order mark is required and one is tolerated. Control characters are disallowed in every text field. |
| Currency | ISO 4217 | A three-letter code. One currency per price feed, unless a per-row currency column is agreed. |
| Dates and timestamps | ISO 8601 | A date, or a date-time with an offset. Local time without an offset is rejected. |
| Country codes | ISO 3166-1 alpha-2 | Used by the restriction and origin fields. |
| Decimals | Point separator | Two 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. |
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.
| Outcome | What happens to your data |
|---|---|
| Accepted | Every row passes. The feed is applied in full. |
| Accepted with warning | Applied, with non-conforming optional values dropped and logged. |
| Row rejected | Individual rows fail and the rest is applied. Every rejected row is listed in the report. |
| Feed rejected | The rejection ratio exceeded tolerance. Nothing is applied and your previous snapshot is retained. |
Conditions and their codes
| Condition | Class | Outcome |
|---|---|---|
| A required field is missing | E-1xx | Row rejected, the feed continues. The row and the field are named in the report. |
| A type or format violation | E-2xx | Row rejected. The prior value for that row is retained. |
| An unresolved join key | E-3xx | Row rejected. This is what a price, stock or coordinate row naming an unknown ProductCode gets. |
| An unknown enum value | W-3xx | The value is dropped, the row is accepted, and a warning is logged. |
| An unreachable asset URL | W-4xx | Row accepted and the asset retried on the next cycle. Persistent failure escalates to E-4xx. |
| A parse failure | E-900 | The 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.
