Why we push products from a CSV
Products live in three places — HubSpot, QuickBooks, and a CSV file — and it's natural to ask why we don't just use HubSpot or QuickBooks directly. Here's why, and why it's safe.
Scope note: this is about the product catalog and the chart of accounts (account numbers, types, descriptions) — not accounting transactions. The CSV is never the source of truth for journal entries, invoices, or any other financial transaction. Those stay exactly where they've always been, in QuickBooks.
Why not QuickBooks alone
QuickBooks is the real accounting record — costs, income accounts, tax codes. But it has no dedicated place to store things like "this product is a bundle of these three parts" or "this price changes at 25 units." QuickBooks is stingy with custom fields, so this app piggybacks that information on the product's own Description field instead. (We do the same thing for invoice line items, to track shipping status — it's a consistent pattern, not a one-off hack.) Because that data lives in a place QuickBooks itself doesn't understand, the app needs to be the one reliably writing and reading it — that's the main reason the catalog needs one clear owner rather than being edited freely from both sides.
Why not HubSpot alone
HubSpot is the CRM — it doesn't have accounting authority. It shouldn't be deciding what an item costs or which account its revenue belongs to.
So why a CSV
The CSV is the one file that can hold everything both systems need — pricing, bundle contents, tier rules, and the plain accounting facts — in one place. When you upload it, both QuickBooks and HubSpot get updated from that same file, at the same time, so they can't drift apart or disagree with each other.
It also means changing a batch of products or accounts is easier, not harder — edit the CSV once and push it, instead of clicking through dozens of records one at a time in the UI. The UI is still there if you'd rather make a change that way; the CSV is just the better tool when you're touching more than a handful of things at once.
There's also a practical reason this isn't optional: standing up a brand new QuickBooks company from scratch means there's no product catalog there at all yet. Pushing the CSV is how that catalog gets created in the first place — it's the bootstrap step, not just an ongoing convenience.
One more reason this matters: invoices need to look like MOM's
HubSpot and QuickBooks split the bundle/breakout work between them deliberately, so that a finished invoice still looks like the MOM invoices Sales and Shipping have always worked from — that's a hard requirement from both teams, not a technical preference. Getting that shape right depends on the same bundle/tier metadata this section is about, carried through the CSV. Between that, QuickBooks' field limitations, and needing to bootstrap a brand new company, there's more than one independent reason this control plane isn't optional.
Will this mess up what I've already got set up?
No — and here's specifically why:
- Anything already on an invoice or deal is frozen and stays that way. HubSpot stores a line item's price and name directly on that line item the moment it's created — it doesn't look back at the product record later. Correcting a product afterward never changes an invoice that already used it. Checked directly against real production data: dozens of open invoices and deals share SKUs with the CSV, and none of them are affected by catalog corrections.
- The CSV only changes the columns it contains. A column you leave out of the sheet, or a blank cell, is left exactly as it is in both systems. A column you include is written as-is, in both systems, for every row in the sheet. So a small sheet can only make a small change.
- QuickBooks and the HubSpot product library are both kept in agreement with the CSV, on purpose — so a wrong name or price doesn't stay wrong forever just because it was manually typed in once. This only affects the live product entry, never anything already on an invoice or deal (see above).
- It only ever touches products actually listed in the CSV. Anything outside it is left completely alone — confirmed directly: a real correction pass touched every product the CSV covered and nothing else. Nothing is ever deleted or hidden by a CSV push; taking a product out of use is a deliberate value (Active = false) on a row you include.
The short version
If you need a product to look or behave the same way everywhere, put the change in the CSV and push it. If you need a fast, one-off tweak somewhere, that's fine too — just know the HubSpot product library will snap back to whatever the CSV says the next time it's pushed.
For how this fits into going live and handing the system off, see rollout and handoff.