Product Catalog Spreadsheet Template
One master row per product and one mapping row per channel listing, so bundles, duplicates and GUID-keyed menu items each have somewhere to live.
Free download · No account needed
SKU Mapping
[Company] — [n] products, [n] channels, [n] listings, built [date]
One row per channel listing rather than one row per product, because a product with two listings on one channel has nowhere to go in a product row, and neither does a bundle.
| Channel | Channel identifier | Channel’s own name | Master SKU | Relationship | How it was matched | Decision |
|---|---|---|---|---|---|---|
| — | — | — | — | — | — | — |
| — | — | — | — | — | — | — |
| — | — | — | — | — | — | — |
| — | — | — | — | — | — | — |
Relationship is a closed list, and every one of the five behaves differently
| One to one | The ordinary case. One listing, one product |
| One to one, quantity n | A two-pack of a single product. Drop the quantity and the velocity reads half |
| One to many | A bundle or kit. Its units belong to the components, and until they are exploded every component reads slow |
| Duplicate | Two listings, one product, one channel. Merge it, or keep it with a reason |
| Channel only | Correctly has no master row. A drink on a till. Mark it once and it stops being an exception |
How it was matched is the other column nobody keeps: exact, normalised, or manual. An exact match can be rebuilt by a script any time. A manual match exists only because somebody wrote it down, and if they did not, it gets made again from nothing next quarter, differently.
Every free product catalogue template is one sheet with one identifier column, which assumes every system agrees on what the identifier is. The platforms say otherwise in their own documentation. Shopify's variant SKU is an optional, case-sensitive string, Square records one only if any was ever typed in, and Toast keys menu items by a generated GUID. So this pack is a join instead: one master row per product, one mapping row per channel listing.
Hollis Row Coffee is an invented roaster with 54 products, 171 listings across those four channels and $458,300 of revenue over 90 days. Matched as literal strings, 103 listings joined. Upper-casing, stripping separators and stripping leading zeros lifted that from 60.2 to 70.2 percent, which is the figure a cleanup pass reports. It fixed 17 rows: a trailing space, an underscore, a zero a spreadsheet added. All cheap, and none of them the problem.
Fifty-one listings remained, and one match rate cannot describe them, because they break a per-product report four ways that never cancel. Fourteen are correct and only look broken. Twenty-one drop rows, understating totals by $53,000. Five split one product across two listings that both sell, so a ranking by revenue puts both halves under the cut. Eight are bundles hiding 4,748 component units, which understated measured velocity by up to 82.5 percent and moved seven reorder points by a quarter or more. Three reused an identifier across a size change.
What's in the pack
SKU Mapping sheet
One row per channel listing, not one row per product. Carries the channel's own identifier and name, the relationship, the quantity per unit, and whether the match was exact, normalised or manual.
Master Catalogue sheet
One row per product with declared net content, a status and an effective date, so a superseded product keeps its own row and last year still joins to the thing it was actually describing.
Discrepancy Register sheet
Every unjoined listing classified, with the direction it pushes a report and the revenue behind it. Understated, split, misattributed or wrong both ways, reported separately rather than summed.
Price Consistency Check sheet
Expected price against actual, per channel, with the fee rule in the row and net proceeds beside the price. Margin after every fee layer is a separate exercise.
Naming Standard
How identifiers are formed, and the rule against putting anything mutable inside one. This is how HR-HOUSE-250 came to name a 340 gram bag and stayed that way on all four channels.
Channel Mapping Note
Per channel: what it keys a listing by, whether the field is required, whether it can be edited after creation, and whether it can be joined by a string rule at all. Two of four here cannot.
Bundle and Kit Note
Components and quantities per bundle, and the measured against true velocity table. Downstream, that is what a reorder point was quietly getting wrong on the top SKU in the catalogue.
How the Mapping Was Built
The whole worked catalogue: both join rates, the 51 residual rows by class, the four directions priced, the bundle explosion, and the referral fee tier that made a price rise cost money.
Eight prompts, one per decision
Build the master, normalise and count what it missed, map each channel, explode the bundles, find the duplicates, mark the channel-only rows, check prices against the policy, and supersede a changed product.
How it works
- 1
Download it or install it
Take the four blank sheets and three notes as CSV and Word files with no account, or install the whole pack into a private Space with the agent primed on the join.
- 2
Send every channel's export
A storefront export, a marketplace listing report, a point of sale item list, a menu export. Ninety days of sales by identifier alongside, since the revenue is what makes a mismatch worth attention.
- 3
Read the residual, not the rate
You get both join rates and then the rows normalising could not reach, split into the five classes, each with a count and the revenue riding on it.
- 4
Decide once, and write it down
Each residual row gets a mapping, a merge, a channel-only flag or a superseded master row, recorded with who decided and when, so it never comes back as a finding.
Frequently asked questions
Is this template free?
Yes. Four sheets, four documents and eight prompts with no signup and no card, and they are the same files the agent works in. Editing with AI is the optional path, where your own channel exports become the mapping and the discrepancy register.
What format are the downloaded files?
CSV for the Master Catalogue, SKU Mapping, Discrepancy Register and Price Consistency Check, and Word for the Naming Standard and the notes, zipped together. Excel, Numbers, Sheets, Word, Pages and Google Docs all open them directly.
Why two sheets instead of one?
Because a channel's identifier is a fact about the relationship, not about the product. Put it in a product row and there is nowhere to hold a bundle, a duplicate listing, a two-pack, or a fifth channel. One mapping row per listing holds all four.
What is wrong with reporting a match rate?
It covers four errors pushing in different directions, so they never cancel and no total shows them. Dropped rows understate, duplicates split, bundles misattribute, and a reused identifier is wrong both ways at once. Report the four, or report nothing.
When does a product change need a new identifier?
When the declared net content, the formulation, the pack count or the unit of sale changes. GS1 is explicit that any change to the declared net content requires a new GTIN, and gives a bag of snacks going from 680 to 794 grams as the example.
Why does the price check need the fee rule?
Because a referral fee is often a step, not a percentage. Amazon charges 8 percent at or below $15.00 and 15 percent above it in Grocery and Gourmet, so $15.01 nets $1.04 less than $15.00 and every price up to $16.23 nets less than the boundary.
Can it just fuzzy-match the names for me?
It will offer candidate pairs for you to confirm, and it will not accept them silently. On a catalogue with sizes in it a fuzzy pass joins the 250 gram bag to the 1 kilogram bag, and a wrong join lands on a revenue report looking correct.
Find out how many of your listings join to nothing
Download the blank pack as Word and CSV files, or open it in River, send every channel's product export, and get the join rate and the rows that need a decision back first.
Edit with AI