The biggest deals were the slowest to quote. Now they are one document.
Indivd sells store analytics to retail chains where no two stores buy the same setup. Quoting a forty-store network meant several documents assembled by hand and kept in sync by hand. Today the seller configures once and the quote prices every store on its own terms, inside HubSpot, on a licence with no CPQ in it.
stores in one quote. The size of the network stops deciding how fast you can sell to it.
document per deal instead of a folder. One number, one signature, nothing kept in sync by hand.
licence upgrades and no second tool. It runs on the Sales Professional seat already paid for.
Live with real customers since 3 August 2026.
Five things a sales leader gets that did not exist before.
Same catalogue, same sellers, same licence. What changed is how many documents a deal needs, and how much of it anyone has to type.
One document per deal
A network of two hundred stores is one quote, not a folder of them.
Describe it once
The seller configures a product once and picks the stores. The system writes every line after that.
Nothing can disagree
Price, scope and rollout plan are generated from the same rows, so the document cannot contradict itself.
Terms the CEO owns
Version, date and link to the general terms come from one record. No seller can edit them on a quote.
No licence upgrade
No Revenue Hub, no second tool, and every configuration stays in the CRM for reporting and renewals.
One configuration in. Forty line items out.
The real card, rebuilt in the page and running on a loop. One product is configured, the stores are picked, and the deal fills itself. Saving a second time reconciles instead of duplicating.
A seller opens the deal, picks a product, sets the tier, the phase and the hardware setup, and selects the stores it applies to. Saving writes one line item per store. Saving again does not duplicate anything: it creates what is missing, archives what was removed, and leaves the rest untouched.
The rule that makes saving safe to repeatcard_id, and the diff behind it
Every line item carries the identifier of the configuration that produced it. Saving again is a reconciliation, not an insert: the backend creates what is missing, archives what was removed and leaves the rest untouched. Add three stores in week six and the quote absorbs them.
Why it matters commercially: a seller can renegotiate a live deal without anyone rebuilding the quote by hand, and without the silent duplicates that make a total wrong.
What the card refuses to savefour validations, mirrored in the engine
At least one store. A phase, whenever the deal contains a subscription. Quantity locked at one for anything counted per store, with a single approved exception. Discounts inside 0 to 100, and an explicit volume discount on every recurring line, where zero is a valid answer.
/* Non hardware products are locked at quantity 1 because they are counted per location: quantity 2 would charge the same store twice. Enterprise is the one approved exception, matched by id and by name so it survives a rename and a recreation of the product. */ const QUANTITY_FREE_PRODUCT_IDS = ['47257531981']; const QUANTITY_FREE_PRODUCT_NAMES = ['enterprise'];
That lock covered 193 of the 198 products in the library, and it lived in two places: the card refuses to save, and the engine raises the same warning. Fixing only the front end would have produced a quote that saved cleanly and then complained about itself.
Two hundred stores is not forty stores five times over.
Two inputs, and the rest is arithmetic rather than a promise. It sweeps by itself; drag the slider if you want your own number.
A setup is a distinct way of buying: new cameras and installation, existing cameras, hardware only, a deeper service tier. A real catalogue carries dozens of them.
The document builds itself, and drops what does not apply.
Change the shape of the deal and the quote rebuilds. Nothing is written twice, and no heading ever renders without its value.
Pick one. The list of sections on the right rebuilds.
- Header, quote number and validitygenerated
- Prepared for, and fromgenerated
- Executive summarygenerated
- What Indivd enablesgenerated
- Scopegenerated
- What you getgenerated
- Pricing summary, all storesgenerated
- Pricing details, per storegenerated
- Deployment plangenerated
- Billing detailsgenerated
- Questions your team may askgenerated
- What our customers saygenerated
- Where Indivd runs todaygenerated
- Next stepsgenerated
- Acceptance and general termsgenerated
- Appendix, optional hardwaregenerated
Recurring and one-time kept apart
Discounts shown as a line rather than buried in a total, inside each phase.
Generated from the same rows
Country, bundle, phase, hardware setup and store count, produced from the rows that make the prices.
Bound at a named version
Signature binds this quote, the supplementary terms and the general terms at a named version and date.
How the template gets its contentand the HubSpot limit that forced it
A quote template can only read what is associated with the quote, and custom properties on the Quote object itself arrive empty. So the deal became the rendering surface: the engine writes finished blocks of HTML into 14 deal properties, and the template injects them. The template holds layout and typography, and no business logic at all.
{% if DEAL.render_pricing_html %}
<div class="ey">PRICING DETAILS
{% if DEAL.flag_hardware_only != "true" %} · PER LOCATION {% endif %}
</div>
{{ DEAL.render_pricing_html|safe }}
{% endif %}
Where the legal terms livea settings table with no database
HubDB was not on the licence, so the general terms version, date and link sit on a single dedicated Company record used as a settings table. It is not a customer. The CEO edits it in HubSpot, every quote in every deal picks it up, and no seller can change the terms on their own document.
Every product HubSpot sells for this needed a licence that portal does not have.
Six closed doors, and the six things built instead. They resolve one at a time. Click any door to drive it yourself.
Coded quote modules
Went generally available in June 2026, and require Revenue Hub Professional.
A quote template inside a child theme, fed entirely by deal properties.
Properties on the quote
Custom properties on the Quote object never reach the rendered document.
All variable content moved to the deal, which is associated and does reach it.
HubDB
Not contracted, and it was the natural home for the legal terms.
One dedicated Company record acting as the global settings table.
Serverless functions
Not available on this platform version or this licence tier.
A small Python service on a dedicated server, doing arithmetic and nothing else.
Buyer-editable fields
The new CPQ supports them but not coded templates. The two are mutually exclusive.
Editing happens in the CRM, where it is recorded, and never in the document.
Line items on a store
Line items belong to deals in HubSpot’s model and cannot hang off a location record.
One line item per product per store, each tagged with the store it belongs to.
How the four layers fit togetherone diagram, in words
Locations are CRM records, archived and never deleted, so historical reporting keeps its ground. Configurations are line items. Terms are a record the CEO owns. The only thing living outside HubSpot is the arithmetic, which is the one part nobody needs to search, filter or report on.
The quote is not a PDF. It is a row per store.
Everything the document prints stays in the CRM as structured data. That is the part that keeps paying after the signature.
How much of the network is actually live?
Coverage is a filter on the deal, not a question for the account manager.
What does this network bill every month?
Forecasting stops depending on someone opening the PDF.
When does each store renew?
Every store carries its own term and billing start, so the renewal date is a field rather than a memory. Expansion is the same row with a later phase.
The easy answer was to build the quote tool outside HubSpot.
That produces a beautiful PDF and a dead deal record: nothing to report on, nothing to renew from, nothing the next person can pick up. Everything here stayed where it mattered, and only the arithmetic moved out.
Build your own configurable quote in HubSpot.
- Priced per store, per site, per branch or per seat, on the objects you already have
- No Revenue Hub and no second tool: this runs on Sales Professional
- Live with real customers, not a prototype
Thirty minutes, your deal on the screen, no slides.