Quotes and proposals

Quotes and proposals for MSPs in your brand: your own numbering, a layout you preview live, letterhead built from your details, priced from your price books.

Quotes and proposals

A normal CRM emails a PDF with someone else’s name on it.

The proposal is the one document in this entire product a customer of yours actually reads. So it goes out in your brand: your logo, your colours, your bands, held as a per-tenant setting rather than a per-document upload somebody forgets. Behind it sit price books with their own entries, bundles for the things you always sell together, and price resolution pinned to your tenant — so a lookup can only ever return your pricing.

How it works

From line item to sent document

Three parts, and the last one is where most CRMs stop caring.

Price books and bundles

Products carry price-book entries rather than a single price, so the same product can be sold at different prices to different books, and a price lookup resolves inside your own tenant by construction. Bundles group the things that always go out together so nobody rebuilds the same five lines by hand.

A quote you can start from a template

Quote templates mean the standard shape of your commercial offer is a starting point rather than folklore. Bulk operations and exports work here like everywhere else in the product.

A proposal that looks like you

Branding is configured once for the tenant and applied at render, and the PDF is produced by a real browser engine so the document a customer opens is the document you laid out. That render is rate-limited on purpose: it is genuine work, and a proposal is worth waiting a moment for.

In the product

Your brand on the document that leaves the building.

branding_scope: per tenant price_resolution: tenant-pinned render: headless browser Sample data — illustrative product UI, not a performance claim.

The mechanism

What a quote is underneath, and what it does to the deal

A quote is not a document with numbers typed into it. It is a structure the server owns, priced from books pinned to your tenant, and its acceptance is the moment a deal stops guessing at its own value.

Sections and lines, with the ordering taken out of your hands

A quote is sections, each holding lines, each line carrying its own billing frequency. There is exactly one sanctioned way to write that content, and both creating and editing a quote go through it, so section normalisation, per-line frequency resolution and the recalculation of totals happen in one place rather than three that drift. Which section a line belongs to and what order things appear in are assigned by the server and never read from what the browser sent — a submitted ordering is an instruction the client has no business giving.

Two totals, because a monthly figure and a one-off are not the same money

Totals are computed by grouping the lines on their billing frequency, so a quote carries a recurring total and a one-time total, and the subtotal is their sum by construction rather than by a separate calculation that could disagree with them.

That distinction survives into the deal. Accepting a quote syncs its value onto the deal, and what gets synced is the recurring figure where there is one — a quote that is entirely one-off pushes the one-off total instead, so a real quote can never make a deal worth nothing. Acceptance runs through a single path whichever way it was triggered, and accepting an already-accepted quote does nothing, so a duplicate signature is absorbed rather than counted.

The pricing pin, and the leak it closed

A price lookup can only ever return your pricing, and it is built so that this holds however the lookup was reached. Every lookup takes the workspace as an explicit argument rather than inferring it from whoever happens to be logged in — which matters because prices are also resolved by background jobs and the metric engine, where there is no logged-in user to infer from. A price book belonging to another workspace matches nothing and falls through to your own default. That guarantee is a property of how the lookup is written, not of the context it runs in.

The document

Numbering, layout and letterhead, set once

Everything about how a proposal looks is a workspace setting rather than something re-done on each quote, and each setting shows you the result before you save it.

Quote numbers in your format

Build the numbering pattern from literal text and tokens — a prefix, the year, the month, the day, and a sequence padded to the width you choose — so a number can read Q-00001, or carry the year and the date ahead of a counter that keeps climbing. Date tokens roll over at your workspace’s midnight rather than the server’s, and the preview on the settings screen is produced by the same code that issues real numbers, so what you see is what the next quote gets.

A layout picker with a live preview

Choose from a set of proposal layouts and see a full-size PDF preview of each before you commit, rendered by the same engine and the same templates as a real quote — with your own logo, name, contact details and accent applied, not sample branding. Half of what distinguishes one layout from another is how it treats your letterhead, so previewing it with somebody else’s would answer the wrong question.

Letterhead derived from your details

Nobody designs a letterhead per document. The header and footer bands, the cover mark, the contact line and the name above the signature are all built from your workspace’s brand details, and blanks are dropped cleanly so a missing phone number never leaves a stray separator. With nothing uploaded at all, the layout still renders as a finished design rather than an empty frame.

Branding researched in one click, approved by you

Rather than filling in brand settings by hand, an administrator can ask MADDOX to read your own company website and propose a brand identity — name, contact details, colours and the rest. The result is a proposal waiting for review; it never writes your brand settings by itself, and nothing changes on a quote until somebody accepts it.

Page X of Y, on every PDF

Every exported PDF carries “Page X of Y”, including the exports produced by a different rendering engine from the proposal’s. A twelve-page proposal printed and stapled by a buyer should still tell them whether a page is missing.

Who it is for

For businesses whose proposal is part of the sale

If the document is doing work for you, it should not be advertising your CRM.

  • An agency or equipment dealer whose proposal is a considered, designed document.
  • A business with several price books — by region, by segment, by agreement.
  • A sales operations lead standardising what a quote is allowed to look like.
  • Anyone who has sent a customer a PDF with the wrong logo on it.

Questions

The things people actually ask.

Whose brand is on the proposal?

Yours. Branding is a per-tenant setting — logo, colours, bands — applied when the document renders. Your customer should not be able to tell which CRM produced it.

Can different customers get different prices?

Yes, through price books and their entries, and a lookup resolves within your tenant so one company’s pricing can never surface in another’s quote.

Can quote numbers follow our own format?

Yes. You build the pattern from text and tokens — year, month, day and a padded sequence — and the settings screen previews the next number using the same code that will issue it.

Why is PDF rendering rate-limited?

Because each render launches a real browser engine. That is what makes the output match the layout, and it is also why the endpoint is throttled rather than pretending the work is free.

Does it push a signed quote into my accounting system?

No, and we are not going to imply it does. Accounting integration is not something this product ships today; the quote, its versions and its status live here.

Put your logo on it and render one.

Then send it to yourself and see whose product it looks like.