The Review Queue

Work the staged decisions a catalog feed produces — approve, reject, filter and bulk-decide matches, then apply them or create the new products they propose.

A product feed never writes to your catalog on its own. Every conclusion a run reaches — this vendor item is your product, these two could both be it, this one is something you don’t carry yet — is staged in the review queue, where you approve or reject it before anything is committed.

What a proposal is

A proposal is one staged decision about one vendor line item, keyed to that vendor’s part number. It holds the vendor’s side of the row — part number, description, UPC, MPN, brand, cost, drop-ship cost, MSRP and MAP — plus whichever product it matched (or the shortlist of candidates when more than one did), and the content the row could contribute later: manufacturer description, vendor description, image URL, weight, category path and the vendor’s spec text.

Nothing about a proposal touches your catalog. Approving is an opinion; Apply (for matches) and Create (for new products) are the commits. That separation is what lets you work a 3,000-item onboarding over a morning without the catalog shifting under you halfway through.

ℹ️ Note: One kind of row never reaches the queue at all: an item already linked to this vendor under that same part number. There is nothing left to decide, so the run refreshes the existing link’s cost, drop-ship cost, list price and MAP, fills any gaps on the product under the feed’s update rules, and counts the row as matched on the run summary. That is why a second run of a catalog you have already applied produces a small queue and a large matched count.

Re-running the feed does not duplicate the queue. An open proposal is refreshed in place from the vendor’s current file, so a corrected price or a description the vendor added since the first run reaches the row you are looking at. A row you have already decided — Approved, Applied or Rejected — is never re-surfaced and never overwritten by a later run.

ℹ️ Note: The one exception to “your status is preserved” is the brand gate: if a re-run judges a new product’s brand suspect, the row is promoted to Flagged even if it was sitting in Needs a decision. The gate only ever promotes — it never downgrades a decision you made.

Staging every decision is how product feeds behave for you: a run can stage, refresh and enrich, but it cannot create or link a product you have not approved. (A feed can be configured to write confident single matches straight through and stage only the exceptions. That is not a switch in the dashboard — ask ILLUMA support if you want a feed set up that way.)

Getting to the queue

  1. Open the vendor — Purchasing → Vendors, then the vendor whose feed you ran.
  2. Follow the review link — after a product-feed run the feed row shows Review N to review →. It opens the Catalog review page for that vendor.
  3. Or go straight there — the page lives at /dashboard/dealer/vendors/<vendor>/review.

The queue is per vendor, not per feed. A vendor can carry more than one product feed — an item-master feed plus an enrichment feed, say — and everything they stage lands in the same six tabs. That is also why the Review N to review → count on a feed row is the vendor’s whole open queue, while the stat grid beside it (matched / created / need review / flagged / not carried / filtered out) is only that run’s own numbers.

ℹ️ Note: The settings Apply and Create work from — drop-ship mode, SKU source, title template, image handling and the per-field update rules — are read from this vendor’s product feed configuration. When a vendor carries more than one product feed, keep those settings consistent between them so a row commits the same way whichever feed staged it.

📷 Screenshot: The vendor detail page with a product feed’s last-run panel expanded, showing the run stats and the blue “Review N to review →” button. (placeholder — replace with /docs-images/vendors/review-queue-feed-row-cta.png)

Match types

Every proposal carries an outcome — what the run concluded — and that outcome decides which tab it lands in.

Outcome What it means Where it lands
Matched Exactly one product in your catalog matched on the feed’s chosen identifier To approve
Ambiguous Two or more of your products matched the same identifier — only a person can say which Needs a decision → Pick a match
New product Nothing matched, and the feed is set to create products for unmatched items Needs a decision → New products
New product, held Same as above, but the resolved brand looked wrong Flagged
Already linked to this vendor The product it matched is already linked to this vendor under a different vendor part number Needs a decision (visible under All)

The last one is worth knowing because it is easy to misread: the “Which product?” column shows a dash, since there is nothing safe to link. One product can carry only one part number per vendor. Either reject the row, or sort out the correct part number on the product’s Vendors tab.

ℹ️ Note: If the feed is not set to create products for unmatched items, unmatched rows are counted on the run summary as “not carried” and never enter the queue at all. On a distributor catalog that is usually tens of thousands of rows, and queueing them would bury the handful of real decisions.

The status lifecycle

The tabs across the top are the statuses, with a live count on each.

Status Tab What it means How a row gets there
proposed To approve A confident single match, waiting on your yes Staged by a product-feed run
needs_review Needs a decision An ambiguity, a new product, or an already-linked conflict Staged by a product-feed run
flagged Flagged A new product held back because its brand looks suspect The brand gate, during a run
approved Approved You said yes. Still nothing written Approve, per row or in bulk
creating (no tab) The create job has claimed this row and is minting the product right now The create job
applied Applied Committed — the vendor source exists on the product Apply, or the create job finishing a row
rejected Rejected You said no, or the feed excluded it Reject, a row filter, a blacklist, or three failed create attempts

Two details that catch people out:

  • creating has no tab. While the create job is working a row it belongs to none of the six tabs, so counts dip briefly during a big run. If a worker restarts mid-run, the next create job flips those rows back to Approved and re-drives them.
  • Applied is final. Applied rows show no Undo, and the server refuses a re-decision with “This one has already been applied. Edit the vendor source on the product instead.” Change it on the product’s Vendors tab.

Reading a row

Each row shows four things: the vendor’s item, their money, what it would become, and the actions.

  • Vendor item — the vendor’s description (or their part number if there is no description), then the part number, UPC, MPN and brand underneath.
  • Their price — the vendor’s cost and/or drop-ship cost, whichever the feed carries, with MSRP beneath. This is the column that makes a match judgeable: a pairing that looks right by name and wrong by price is the one worth catching.
  • Which product? / Matched to — a radio list of candidates on an ambiguous row, “New product” plus the brand that would be used on a new-product row, or the matched product’s title, SKU and your cost on a matched row.
  • Actions — Approve and Reject while the row is open; a status badge and Undo once you have decided.

The chips

Chip Meaning
no content This part number is not in the vendor’s current file, or the feed’s row filter excludes it. Applying it links the vendor and the routing but carries no description, image or category. (A row that carries only a price still counts as having content — price rides its own columns.)
⚑ No brand found Held: the row resolved to no brand at all
⚑ Brand is just a number Held: the brand column was all digits
⚑ Brand looks like a set/season, not a maker Held: the brand reads like “2025 Topps” rather than a manufacturer
Excluded by row filter On the Rejected tab: closed automatically by the feed’s row filter, not by a person
SKU blacklisted / Brand blacklisted On the Rejected tab: closed automatically by one of the feed’s skip lists
Create failed (see job errors) On the Rejected tab: the create job tried this row three times and gave up

📷 Screenshot: The review table on the Needs a decision tab showing one ambiguous row with two candidate radio buttons (each with its own SKU and your cost) and one new-product row carrying a “no content” chip. (placeholder — replace with /docs-images/vendors/review-queue-row-anatomy.png)

Approving and rejecting

  1. Work a row — click Approve to accept it or Reject to refuse it. Neither writes anything to your catalog.
  2. Pick first on an ambiguous row — approving without choosing a candidate is refused with “Pick which product this is first.” A candidate is pre-selected only when the matcher already had a preferred answer; on a genuine ambiguity nothing is ticked, deliberately.
  3. Undo if you change your mind — Approved and Rejected rows keep an Undo link until they are applied.

What each action records:

  • Approve on a match records the product you chose — and a bulk approve keeps the matcher’s own single answer — so Apply reads one answer no matter how the row got there.
  • Approve on a new product means “yes, create this” — there is nothing to point at yet; the product is minted later by the create job.
  • Reject closes the row permanently as far as the feed is concerned. Later runs skip that part number instead of re-asking.
  • Undo returns the row to wherever the importer had it: a match goes back to To approve, a new product with a suspect brand goes back to Flagged (never to Needs a decision, so an undo can’t quietly hand junk to the create job), and everything else goes to Needs a decision.

Narrowing the queue

Sub-filters on Needs a decision

That tab holds two unrelated jobs, so it splits them: Pick a match (usually a handful of real ambiguities), New products (potentially tens of thousands), and All. Landing on the tab defaults to Pick a match, so a wall of new products never buries the decisions only you can make. Every bulk action on the tab respects the chip you are on — “Reject all new products” leaves the ambiguous matches untouched. Already-linked conflicts carry neither chip, so they show up only under All.

Filters

Choose a field in the filter bar, type a value, click Add filter, and it becomes a chip. Stack as many as you need (up to 12); they are ANDed together.

Filter Behaviour
Brand contains Partial, case-insensitive match on the vendor’s brand. The box suggests this vendor’s most common brands across open proposals
Vendor SKU contains Partial match on the vendor’s part number
UPC contains Partial match on the vendor’s UPC
MPN contains Partial match on the manufacturer part number
Cost ≥ / Cost ≤ The vendor’s stocking cost
Drop-ship cost ≥ / ≤ The vendor’s drop-ship cost
MSRP ≥ / MSRP ≤ The vendor’s list price
Has content Only rows carrying the vendor’s stored row data — description, image, category path, weight, identifiers or spec text
No content Only rows carrying none of that, so applying them would write the link and the routing and nothing else

⚠️ Warning: The Has content / No content filters test only the vendor row data, while the no content chip also counts a price. A row whose only payload is an MSRP or MAP therefore shows no chip but still answers the No content filter. When you are hunting hollow rows, read the chip on the row before you bulk-reject a filtered set.

Search and paging

The search box matches vendor part number, description, UPC and MPN. Press Enter or click Search — typing alone does not re-run it, and the counts on screen always reflect the last submitted search.

Rows per page is 50, 100 or 200. The list is sorted by outcome, then vendor part number, and paged with Previous / Next.

💡 Tip: Filters are the whole strategy on a large onboarding. Filter to one brand you know you carry, approve all of it, then move to the next. Every bulk action is scoped to exactly what the filter shows.

Bulk actions

Deciding a handpicked set

Tick the checkboxes on the rows you want and use Approve N selected / Reject N selected. These run each row through the same per-row logic as the buttons, so an ambiguous row you selected without picking a candidate is skipped rather than guessed at, and reported at the end (“2 skipped — pick which product first”).

Deciding a whole tab or filter

Where Button Acts on
To approve Approve all N Every confident match on the tab, narrowed by any filter/search
Needs a decision Reject all N The rows on the current sub-filter, narrowed by any filter/search
Flagged Approve all N / Reject all N The flagged rows, narrowed by any filter/search

When a filter or search is active the labels say “matching” and the number is the filtered count — so a “Reject all” fired off a brand filter rejects only that brand’s rows.

There is deliberately no whole-tab Approve all on Needs a decision: approving an ambiguity in bulk would be a coin flip, and approving new products in bulk is what the Create buttons in the header already do in one pass.

Select all matching

Ticking the header checkbox selects everything on the page. When more rows match your filter than fit on the page, a banner offers Select all N matching — the whole filtered set across every page. Accepting it swaps the toolbar for the whole-set buttons, which run server-side against the same filter the list used:

Tab What the banner offers
To approve Approve all matching
Needs a decision → Pick a match / All Reject all matching
Needs a decision → New products Approve all matching and Reject all matching
Flagged Approve all matching and Reject all matching

Editing the search box or toggling a checkbox cancels the selection, so the number in the banner is never stale.

⚠️ Warning: Bulk decisions run in batches of 500 with a running progress line. Keep the tab open until it finishes. If it errors partway, the rows already done stay done — click again to continue from where it stopped.

ℹ️ Note: On the To approve tab, Approve all N can show a smaller number than the tab count. Bulk match-approval only counts rows that have a product to say yes to and something to transfer, so “no content” rows are left out. You can still approve those one at a time.

📷 Screenshot: The review toolbar with a brand filter chip applied and the “Select all N matching” banner open, showing the Approve all matching / Reject all matching buttons. (placeholder — replace with /docs-images/vendors/review-queue-select-all-matching.png)

Applying approved matches

Apply N matches to catalog is the commit for matched rows. It links each approved match to the vendor and hands over content, in a fixed order: it writes the vendor source row (with cost, drop-ship cost, list price and MAP), then the routing flags, then the content.

Routing follows the product feed’s drop-ship mode. Under the default fallback it sets Drop-ship fallback and points the drop-ship vendor at this vendor; under drop-ship it sets the product to drop-ship outright; under none it leaves the product stocked. It never downgrades a product that is already fully drop-ship and never hijacks one already routed to a different vendor. The product’s primary Vendor field is filled only when it is blank.

Content — descriptions, identifiers, weight, title, price, categories, images — is written under the feed’s own update rules, the same policy the Push vendor updates button uses, and per-field locks on the product are respected.

Apply runs in batches of 400 and drives itself to completion, so keep the tab open. When it finishes you get a one-line summary:

Counter Meaning
vendor sources applied Proposals committed — the product is now linked to this vendor
filed into categories Products shelved into your mapped category for the vendor’s node
images linked Vendor images attached to products
products routed to this vendor Routing flags written
fields enriched Empty product fields filled from the vendor’s data
skipped — already sourced from this vendor The product already carries a source from this vendor under another part number
could not be applied Approved rows with no matched product, or the same conflict as above; they stay on the Approved tab

Routing and content are written for every approved row in the batch, not only the ones whose link is new. That is what makes a second click repair a product that got its vendor source on the first pass but lost its routing to an error — rather than skipping past it as already done.

ℹ️ Note: Apply deliberately ignores approved new products — those belong to the create job below. That is why the Apply button’s number can be smaller than the Approved tab’s count.

Creating new products

New products are minted by a background job, not by the page: minting SKUs has to go through your number series, and tens of thousands of creates is hours of writing that no web request can hold open.

Two buttons in the header, depending on how you want to work:

  • Create N approved — only the new-product rows you explicitly approved. The handpicked run.
  • Create all N new products — the whole un-rejected queue: approved rows plus everything still undecided on Needs a decision. It approves-and-creates in one pass. Anything you rejected is left out; anything Flagged is left out too, because the create job never claims flagged rows.

Confirm the prompt and the job is queued. Progress rides the Active tray (the floating button on the dashboard, labelled Vendor create products import), with the full history in the Activity Center. There is no modal and no page-level progress bar — one inline line acknowledges the start and then the tray owns it.

Only one create job per vendor runs at a time. Clicking again while one is running just returns you the running job: “That creation job is already running — watch it in the jobs tray.”

📷 Screenshot: The Active jobs tray showing a running “Vendor create products import” with its progress bar and the “X / Y” and “N ok” counters. (placeholder — replace with /docs-images/vendors/review-queue-create-job-tray.png)

What each new product gets

Every product the job mints is identical to one the importer would have made itself — same code path, same feed settings.

On the product Where it comes from
SKU The feed’s SKU for new products setting: your number series (default), the vendor’s part number, or the manufacturer part number. If the chosen value is blank or already in use, a number is minted instead — a duplicate SKU would send orders to the wrong product
Title The feed’s title template, default {brand} {mpn} {name}
URL slug Generated from the title (falls back to product-<sku>)
Status / Type Active, simple
Purchasable / Track inventory Both on — vendor stock is projected as derived inventory, which only gates sellability on a tracked product
Vendor This vendor, as the primary supplier
Drop-ship routing The feed’s drop-ship mode: fallback (default) sets Drop-ship fallback plus the drop-ship vendor, drop-ship sets the product to drop-ship, none leaves it stocked with no drop-ship routing
Brand The brand the feed’s brand rules resolved, matched to your existing brand or created if you don’t have it
MPN, GTIN, weight, manufacturer description, vendor description The feed row, when present
Price The vendor’s MSRP, when present. Reprice as you like — it is a starting point, not a rule
MAP The vendor’s MAP, when present
Cost Never written to the product. Cost, drop-ship cost, list price and MAP land on the vendor source row, which is where purchasing and drop-ship costing read them
Category Filed into the category you mapped for the vendor’s node, walking up the vendor’s tree until it finds a mapped ancestor. Additive, never the primary category
Attributes Written from the vendor’s spec text, for products this run created
Image Attached per the feed’s Images on new products setting: link the vendor’s URL, copy to the CDN, or don’t import

⚠️ Warning: Drop-ship mode none means this vendor’s availability never reaches your storefront — stock is only projected as sellable for products flagged drop-ship or drop-ship fallback. Choose it only for lines you genuinely stock yourself.

Linking instead of duplicating

Before minting anything, the job checks whether the product already exists, in this order:

  1. Already linked under this exact part number — a previous run wrote the link and died before stamping the row. It finishes the stamp; no second product, no second link.
  2. A UPC match in your catalog.
  3. An unambiguous manufacturer part number + brand match (using the vendor’s brand code, then the brand name). MPN alone is never used — that would merge different manufacturers’ parts — and more than one hit is treated as genuine ambiguity, not a match.

Anything that hits one of those is linked to the existing product rather than duplicated. This is also what protects you against the vendor shipping the same item twice in one file.

Sampling before you commit

There is no “create only the first N” box on the page, and you do not need one — the filters already give you a sample you chose rather than a sample the file’s row order chose:

  1. Narrow the list — on Needs a decision → New products, filter to one brand, or a cost band, or a part-number prefix.
  2. Approve just those — per row, with the checkboxes and Approve N selected, or with Approve all matching from the select-all banner once the filtered set runs past one page.
  3. Run the handpicked set — click Create N approved, which only ever touches rows you explicitly approved.
  4. Inspect what it made — open a few of the new products, check the title, brand, category and image, then come back and run the rest.

The job itself also supports a hard cap on how many products one run may mint. It is not a dashboard setting — if you want a capped run on a very large catalog, ask ILLUMA support to configure it. When a cap is in force the run stops cleanly once it is reached and leaves the rest of the queue exactly where it was, ready for a full run.

What the finish counters mean

When the job completes it records six counters:

Counter Meaning
created New products minted this run
categorised Of those, how many were filed into a mapped category. Zero usually means the vendor’s categories aren’t mapped yet
attributes Attribute values added or corrected on the products this run created. Zero when the feed carries no spec text
aliased Rows that linked to a product that already existed instead of minting a new one — a duplicate in the vendor’s file, or a row a crashed run had already half-finished
skipped Rows the run didn’t action: no vendor part number, a part number or brand that has since been blacklisted on the feed, or a row another worker had already claimed
failed Rows that could not be created. Each is retried up to three times; after that the row is moved to Rejected with the “Create failed” reason so it stops looping

In the tray, the “ok” count is created + aliased — the rows genuinely resolved — and it carries across a resume, so a job that restarts never shows progress running backwards. If any rows failed, the finished job offers a Download errors report: a CSV of each failed row’s vendor part number and the reason it failed.

ℹ️ Note: Blacklists are enforced again at create time, not just during the run that staged the queue. A row you approved last week but blacklisted yesterday is skipped rather than created.

Re-titling what you created

Re-title created appears once this vendor has applied rows. It re-runs the feed’s current title template over the products this vendor created — the backfill after you change the template or a brand rule. It runs as a background job in the tray, touches only products this vendor minted, only where the title actually changes, and never a locked title.

When the feed carries brand rules, the same job re-resolves the brand before it composes the title, and repoints the product’s brand if the rules now produce a different one. That is deliberate: the title’s {brand} and the product’s Brand field come from one answer, so they can never disagree after a rule change.

Starting the queue over

If the queue itself is wrong — you fixed the feed’s column mapping, brand rules or row filter — use Fresh re-analyze from the feed’s ⋯ menu instead of working through bad rows. It clears everything currently waiting (To approve, Needs a decision, Flagged) and rebuilds it from the vendor’s current file. Products you already created and matched are untouched, and your rejects are kept.

Next

  • Wrong matches, empty rows or a queue that won’t clear usually trace back to the feed’s settings — see Product Feeds for column mapping, matching, brand rules and the create-new-products switch.
  • Nothing filing into categories? Map the vendor’s tree under Vendor Categories.
  • For a feed whose job is enriching products you already carry rather than creating new ones, see Enrichment Feeds.
  • Once products exist, Inventory Feeds make their stock sellable, and Purchase Orders buy them.
  • Stuck on a specific symptom? Vendor Troubleshooting.

Applied and created products behave like anything else in your catalog — check a few on Products, confirm their brand landed on Brands, and that the ones you mapped show up under Categories.

← PreviousSpreadsheet UploadsNext →Inventory Feeds