Case study · Product data engineering

Enriched 36,817 product SKUs in five days for $206 — with a 99.99% production import

Two thirds of the catalogue carried nothing but a brand and a barcode. Faceted filters could not work. Here is what was done, what was deliberately left alone, and how correctness was established before anything reached production.

European online retailer 64,536 SKUs Bilingual storefront May 2026 Sole engineer

The problem

Average attributes per product: 3.9. Products with zero attributes: 1,727. Half the catalogue carried three attributes or fewer.

The consequence was not aesthetic. A shopper could not narrow by material, volume, power or size across most of the catalogue, and category pages had almost nothing structured to index. Done by hand at a conservative two minutes per product, closing that gap across 36,000 SKUs is on the order of 1,200 content-team hours — my own estimate, and the arithmetic is right there.

Results

36,817SKUs enriched
119 / 119batches succeeded
$205.64total API spend
99.99%import success
5 daysend to end
$0.00346per SKU
MeasureBeforeAfter
Attributes per SKU3.911.24
SKUs with ≥10 attributes7.8%61.9%
SKUs with zero attributes1,7270
SKUs with only 1–3 attributes31,8132,963

59,473 SKUs went through the API in 119 batch submissions. 7,456 bilingual attribute definitions were created, grouped into 312 base types and scoped to categories so that faceted filters actually resolve. Total project spend, including translation passes, came to under $215; tooling and infrastructure were already in place.

Production import: 36,814 of 36,817 SKUs landed cleanly. Zero errors on attribute definitions. The three failures were SKU codes that no longer existed in the catalogue.

How correctness was established

This is the part that matters, and it is where most AI content projects quietly fail. Model output that looks plausible is not the same as output that is correct, and the difference usually surfaces only after it is in production.

22 data tests covering structure, types, uniqueness, bilingual completeness, duplicate attributes within a card, category binding and translation coverage. Staged import — 100 SKUs, then 1,000, then the full set — with verification at each step and a rollback procedure written before the first import ran.

Then an adversarial audit of my own work, before production: a read-only critical review against 25 explicit hypotheses, with a standing instruction that an audit returning “everything is fine” would itself be treated as a failed audit.

It returned 3 blockers, 8 warnings, 14 passes. The blockers were real:

Both were fixed before import. That audit is why the number above is 99.99% and not 97%.

Bilingual coverage was handled without API cost: translation of roughly 131,000 variant values ran through an offline dictionary — 150 phrases, 500 words, transliteration fallback — reaching 100% coverage at zero marginal cost, rather than paying per token for work a lookup table does.

What I did not do, and why

27,412 SKUs — 42% of the catalogue — were deliberately left untouched. They already carried good human-written content. Overwriting them with model output would have been measurable activity and a net loss in quality. Enrichment was scoped to the 57% that needed it.

1,341 SKUs were skipped because they had no category assigned. Attribute extraction without a category has no target schema to map into; those products need classification first. Documented as open work, not quietly omitted.

4,884 SKUs already carried ten or more attributes and were preserved as-is, even where the model might have added more. Above a certain density, marginal attributes add noise rather than value.

What I would do differently

The precision gate should not have been bypassed during the pivot, even under schedule pressure. The audit recovered it, but that was luck plus process, not design. On a repeat I would make the gate a hard blocker in the pipeline rather than a checkpoint a phase change can step around.

What this is evidence of

Not that a model can fill in product attributes. It can, and that is not the hard part.

The hard part is knowing which 42% of a catalogue to leave alone, catching the 16,399 cells that would have broken the import format, and being willing to say that a spot-check found a 30–50% error rate on low-confidence output before shipping it rather than after.