Skip to main content
Enrichment is how MerchantOps turns a thin product record into a complete one. For each product it gathers data from trusted sources, generates the content that’s still missing, standardizes property values, and merges everything into a single result. It runs automatically in the background, so you don’t have to trigger it by hand. This page explains what enrichment does and how it decides which value wins. For the shared vocabulary, see Core concepts.

What enrichment does

For each product, enrichment works through a few steps:
1

Search the lakehouse

It looks up the product in the shared lakehouse — a knowledge base of product, technology, and document data — before going to the open web.
2

Scrape the brand's official site

It finds the product on the brand’s own website and reads the authoritative description, specifications, and properties published there.A successful fetch isn’t automatically trusted. Bot-protection and CAPTCHA challenge pages return perfectly valid-looking responses, so MerchantOps sanity-checks what came back on two levels: the content itself — text that reads like a block page, or a product name sharing nothing with the product it asked for — and the raw response the site returned underneath it. That second check matters because a challenge page controls what a reader extracts from it, so it can present a plausible-looking product while the site was in fact refusing the request. Reading the underlying response catches those.When a scrape is judged bad, the entire scraped result is discarded — no scraped value is saved, and none of it is passed on as context for generation. The run continues on the lakehouse and generated content alone, and records a warning on the job and on the product saying the scrape looked suspect and was dropped. Suspect scrapes are thrown away, not trusted.Bad scrapes also count against the brand. Repeated failures — and a single detected bot-protection challenge — pause brand-site scraping for that brand for a while, because retrying a site that is refusing to serve pages costs you allowance and cannot succeed. See When brand-site scraping is paused.
3

Generate missing content

Where a field is still empty, it generates the missing content (for example, a product description) — but only when there’s enough grounded input to write responsibly. When a field can’t be grounded in real source data or supporting context, enrichment leaves it blank rather than inventing a value, so a record may still show deliberate gaps. A run where nothing at all could be grounded finishes with a warning on the Jobs page rather than a clean success.Generation — and the standardization step below — depends on an outside AI provider, and that provider can refuse a call: a plan or budget limit, an authorization rejection, or a request it declines to serve. When a call is refused, the run keeps everything it did gather, records a warning on the job naming the refusal, and leaves that product’s item on the job unfinished so you can re-run it. A refused call is never reported as a clean success. See Provider errors.
4

Standardize properties

It normalizes property values to your catalog’s standard form — so a color, size, or material entered many different ways lands on one consistent value.
The result is saved as a new version of the product rather than overwriting the one you started with. See Versioning for how versions work and which one to trust.

How enrichment decides which value wins

A single product can pick up the same field from four places: the shared lakehouse, the brand’s official site, content generated during the run, and the values you entered yourself. Enrichment resolves the conflict field by field, not once for the whole product.

Priority is set per property

Each property definition carries its own source_priority — an ordered list of sources, best first. There is no single site-wide ranking, and the built-in defaults deliberately differ by what kind of field it is: A property that doesn’t set its own order falls back to the default: generated content, then the brand site, then the lakehouse, then your input. Both the order and the merchant-input guard below are editable in the app: open a property in the Property Dictionary, enable generation, and set its prompt, the context fields to pass in, and the source order. The same settings can be overridden for one product type or a whole category — see Enrichment configuration and overrides.
Ranking generated content first does not mean it usually replaces real source data — most of the time it is never generated at all. See the next section.

Generation is skipped when good source data already exists

Before generating anything, enrichment looks at what the field already holds. If a scraped or lakehouse value is already there with a confidence of 0.70 or higher, generation for that field is skipped entirely — no generated value is produced, so there is nothing to outrank the source data. In practice, generated copy wins mainly where source data was missing or low-confidence. Re-running enrichment on a product that already has more than one version bypasses this check, so a re-run can refresh content an earlier run left untouched.

Values you supplied are protected on most fields

A field whose current value came from you — a value you typed, or one your feed or import file supplied — is normally left alone, whatever a source produces. That protection is a per-property switch, overwrite_merchant_input, and it is off by default — meaning your value stays. Three built-in fields ship with it on, because they are content MerchantOps is expected to author:
  • Description
  • Features
  • Meta title
On those three, enrichment may rewrite a merchant-supplied value. To keep the copy your feed sends on one of them, turn overwrite_merchant_input off on that property. A value you changed by hand is protected on every field regardless of this switch — see Edits you make by hand below. The guard is evaluated against the field’s currently tracked source, so it protects a value only while that value is still attributed to your input. A field another source filled — because you left it blank — is not covered; editing it yourself puts it back under the guard.

Edits you make by hand

When you change a product property — in the app, or through the product API — MerchantOps records that it was a manual edit, along with who made it and when. A hand-edited field is then protected from every automated run, permanently:
  • Enrichment honors it. No enrichment run replaces a value you edited by hand, including on the three fields above and however the property’s source_priority is ordered. Re-running enrichment fills the gaps around your edit instead.
  • Feed imports honor it. An imported row never overwrites a hand-edited field; rows that disagree are reported as conflicts on the import job instead of being applied silently.
  • Clearing a field counts as an edit. If you deliberately empty a value, it stays empty — enrichment doesn’t treat it as a gap to refill. (The one exception is technologies, which is always refreshed from the lakehouse while it’s empty.)
The protection is per field, and only fields whose value you actually changed are marked. It lasts until you release it: the Reset to feed action clears the manual-edit mark and hands the field back to your feed and to enrichment. The mark covers product properties. Editing a variant’s own properties is not recorded as a manual edit today.
Uploading a file — a CSV or an edited Excel export — is an import, not a hand edit. Those rows are merchant input governed by overwrite_merchant_input, and they don’t mark a field as manually edited.
One deliberate override exists, and only on the JSON import: that import can be run as an authoritative resync, which turns the manual-edit protection off for that run and lets the incoming rows win. It is off by default — you opt in per run in the JSON import dialog. When you use it, protect specific fields by leaving them out of the payload.

It runs automatically

Enrichment runs in the background as a job — you don’t have to start it for each product. When you create or import products, they’re queued for enrichment and processed in parallel, and you can watch progress on the Jobs page.

Reviewing enriched products

Check enrichment status, read the completeness score, and re-run enrichment.

Jobs

Monitor enrichment, import, and export jobs and their progress.