Product data feed mapping
Every supplier sends the same catalogue in a different shape. We split mapping into what can be measured and what has to be judged - so you approve products, not JSON.
Measured
Identity, fill rates, types and ranges first.
Bounded
AI works inside hard limits. No invented fields.
Deterministic
After approval every sync is arithmetic.
Step 1
Measure first. No AI.
We parse the file and count what matters.
Field fill rates, value types and ranges.
Field names matched across 18 European languages.
Identity tests on every possible product key.
The result is a ~33 KB measurement sheet. Same size for 7 rows or 750,000.
Feed analysisno AI involved
7,500 rows parsed · 19 fields measured · vocabulary matched in 18 languages
Identity test: ProductSKU repeats on 93 rows
Keyed on ProductSKU this catalogue holds 7,407 products, not 7,500.
| Field | Filled | Distinct | Type | What we measured |
|---|---|---|---|---|
| Artikelnummer | 100% | 7,500 | text | unique key candidate |
| ProductSKU | 99.2% | 7,407 | text | repeats on 93 rows |
| kaina | 100% | 1,812 | number | range 2.99 – 1,499.00 |
| ProductPriceDealer | 100% | 1,790 | number | below kaina on every row |
| ProductPriceRRP | 96.4% | 1,634 | number | range 4.99 – 1,899.00 |
| strekkode | 88.1% | 6,602 | number | 13-digit · GTIN shape |
| description_html | 71.3% | 5,340 | HTML | avg 412 chars |
Same size at 7 rows or 750,000 - the sheet describes fields, not rows.
Step 2
AI judges only meaning.
When counting stops, a model reads the measurements plus sample rows.
One sentence of reasoning per decision.
Cannot invent fields, currency or VAT.
Cannot save anything without your approval.
If validation fails twice, you see the partial proposal with broken parts marked.
Mapping proposal
Read the measurement sheet + 60 sample records · one sentence per decision
Cannot invent fields
Every proposal points at a field in your feed.
Currency & VAT are yours
EUR · 21% - stated by you, never inferred.
Cannot save anything
One retry on validation errors, then you see the partial.
ProductPriceDealer → cost
Sits below RRP on every sampled row - that is your cost, not the customer price.
ProposedProductPriceRRP → price
Retail price in this market usually includes VAT - grossed at the 21% you set.
Proposedbrand + model → title
No title field exists; brand and model together read as a product name.
ProposedArtikelnummer → product key
Unique across all 7,500 rows. ProductSKU collides on 93 rows and cannot be the key.
Proposedkaina → ignored
Duplicate of ProductPriceRRP once currency and VAT are applied.
Ignoredstrekkode → gtin
13-digit numeric values match the GTIN format and are unique.
ProposedSample output
Row 1 rendered as a finished product before anything is saved.
Step 3
Approve products, not JSON.
The proposal is run against real sample rows before you see it.
Review finished products with prices, stock and variants.
See anything that was dropped and why.
Change a field, then accept. Nothing saves until you do.
Luumaform XML → Webshopv7 live
Luumaform feed → Elkor Retail · Webshop v3 · 2 sources bound
1 required field left
15/22 rows resolved · All changes saved
Feed field
rrp_eur
119.00 · 65.00 · 299.00
Feed field
lead_time_days
2 · 5 · 14
Feed field
colour_name → color
Sand · Ink · Moss
Feed field
size_label → size
XS/S · M · L
What Elkor receiveslive
seller_sku
LF-1042
from sku
title
Linen Wrap Dress
from product_name_en
gtin
4751234567890
from ean
price
89.00 EUR
from price_gross_eur
availability_qty
14
from stock_qty
1 required field still missing - these block publishing.
Step 4
After approval, the AI is gone
Every sync from then on is arithmetic. Same file plus same mapping produces the same products, every time, with no model and no 3am surprises.
When a supplier changes their feed structure, we detect it and bring you a proposed update to approve. Your live catalogue never changes shape because a model had a different opinion.
Shopify sources skip mapping entirely - the schema is already known.