Estimates & the Budget Engine
How an estimate is built, how its numbers are actually calculated, and how it becomes a job.
On this page
Creating an estimate
On the Estimates list, the Client, Stage and Sales Rep column filters are picked from a list and match exactly (Sales Rep also offers Unassigned).
- Go to CRM → Estimates → + New Estimate.
- Pick a client. Leads are labeled “(lead)” in the picker so you can tell them apart from active clients at a glance; inactive or cancelled clients don’t show up at all.
- Set the estimate date and a valid-until date — it defaults to 30 days out, but can be pushed further for a bid that needs more runway. The proposal page is honored through the end of that day (in your company’s time zone); see “Valid until” under the proposal link below.
- Assign a sales rep and, if needed, a Sale Type (new sale or renewal) — it decides which commission rate applies and flows through to the job and invoice.
From there you’re in the estimate detail view, where line items, direct costs, and the summary panel all live.
Estimate Builder: drafting line-item text from a transcript
Tools → Estimate Builder is a small AI-assisted writing aid, separate from the estimate detail view itself. It takes a sales-visit transcript and turns it into draft line-item wording you copy into a real estimate — it does not create or touch any estimate record on its own.
- Upload a transcript file (.txt or .vtt) or paste transcript text directly. For a .vtt file, the tool automatically strips the
WEBVTTheader, speaker-id lines, and timestamp lines before showing you the cleaned text. - Click Generate Proposal. The transcript is sent to an AI model that drafts professional, client-ready line-item descriptions — grouped by service type, with locations, quantities, and exclusions called out, and any ambiguous point (like whether weed killer was discussed) flagged inline for you to resolve.
- Click Copy to Clipboard and paste the wording into the appropriate line item on the actual estimate you’re building.
Estimate record — it only produces description text sitting in the browser tab until you manually copy it in. Always check scope, quantities, and pricing against what was actually measured/quoted before pasting it in, and resolve any clarification flags in the output first.Stage vs. approval status
These are two separate fields on the estimate, and they get confused constantly because they both sound like “where is this at.” Stage tracks the sales process. Approval Status is a separate internal sign-off gate that sits on top of it.
| Stage | What sets it |
|---|---|
| Draft | Default stage for a brand-new estimate. Still being built — line items and pricing are in flux. Drafts were never presented to a client, so Close Ratios and win-rate figures leave them out of both counts and amounts. |
| Quote | Set manually once the estimate is ready for internal review — the numbers are considered final pending sign-off. |
| Sent | Set when the estimate is actually delivered to the client (email, PDF, or the client portal). Blocked from actually going out if Approval Status is still Pending — see the callout below. The bulk Mark as Sent action on the estimates list skips any selected estimate whose approval is pending or denied, and says how many it skipped; open those and send from the estimate. A bulk stage change that is blocked for some estimates (for example one with active jobs or invoices) still applies to the rest and reports how many couldn’t be moved. Pipeline dashboards count Sent estimates as open pipeline alongside Draft and Quote. |
| Accepted | Set when the client accepts — in full or via a tiered/partial acceptance, whether you mark it in-app or the client accepts online through the proposal link. Once an estimate is Accepted, a Convert to Job button appears in its header; converting normally happens from here. |
| Lost | Set when the client declines — including a Decline in the client portal, which records the reason “Declined by client via portal” — or when an estimate is manually marked dead. Line items already marked “lost” individually (e.g. a tier the client unchecked when accepting) don’t count toward totals, and the Accepted Estimates by Service reports skip them. Lines still marked “draft” (not yet part of the quote — the proposal hides them too) are left out of totals, the PDF and the client portal the same way. |
| Invoiced | Set once billing has started against the estimate (a deposit, milestone, or the full amount has been invoiced). |
Approval Status runs on its own track: Not Required, Pending, Approved, or Rejected. It exists to hold an estimate back regardless of what stage says. An approval covers the total that was approved: if lines added afterwards push the total above it, Send and Copy link ask for approval again (clicking Send resubmits it), and the estimate can't go out until it is re-approved. On a Good / Better / Best estimate the approval covers the highest option (with its discount and tax), not the “starting at” total, because the client can accept any of them; once the client picks a tier, it’s that tier’s total.
Manual vs. production-rate budgeting
Every service has a configured Budget Method (in service settings), and every estimate line item snapshots that method the moment the line is added:
- Manual — budgeted hours are entered directly on the line, no formula involved.
- Production Rate — budgeted hours are derived:
hours = quantity ÷ the service’s sq ft per man-hour. A service added in Settings or imported from a CSV with a production rate is set to this method automatically; change it per service in the service’s own dialog.
One override applies regardless of method: if the line’s unit type is hr (hourly), the entered quantity is the hours — there’s nothing to derive.
A worked example, start to finish
Say a “Mulch Installation” service is configured with Budget Method = Production Rate and a production rate of 1,000 sq ft per man-hour. A property’s Mulch Bed Sq Ft measurement is 8,000.
- Budgeted hours: 8,000 sq ft ÷ 1,000 sq ft/man-hour = 8 budgeted hours for one visit. With a single visit, total budgeted hours is also 8.
- Cost: the org’s breakeven (fully-burdened) labor rate is, say, $45.00/hr. Because the line’s Cost field is still at its never-set default of $0, it auto-fills the first time the line is added: 8 hrs × $45.00 = $360.00 total cost.
- Rate (price to the client): say the line is priced at $0.12/sq ft, quantity-based (calc type ×): 8,000 sq ft × $0.12 = $960.00 total.
- Margin: ($960.00 − $360.00) ÷ $960.00 = 37.5% gross margin — comfortably in the green band (30%+) on the line-item grid.
- Overhead: at the estimate level, that $360.00 in modeled line-item cost is bucketed as Labor cost and run through the org’s configured Labor overhead + Labor Burden percentages (set separately from the per-line breakeven rate) to arrive at the estimate’s overhead cost, which nets against gross profit to produce the estimate’s net profit figure in the summary panel.
Edit the Cost field directly at any point and that override sticks — the breakeven-rate auto-fill only ever applies while Cost is still exactly $0.
The B.Hrs cell has its own calculator popover for building that number up instead of guessing: enter Men and Hrs:Min to compose budgeted hours (e.g. 2 men for 2:30 = 5.0 hrs), or give it a target man-hour rate — defaulting to the org’s breakeven labor rate — and it solves for whichever of Cost or B.Hrs you leave it to fill in.
Why budget method is snapshotted per-line
It would be simpler for a line item to just read its service’s current Budget Method live, every time. The engine deliberately doesn’t do that: the method (and, for production-rate lines, the rate itself) is copied onto the line item at the moment it’s added, and stays there.
The reason is historical integrity. Say “Mulch Installation” is switched from Production Rate to Manual six months from now, or its production rate is retuned from 1,000 to 1,200 sq ft/man-hour after a crew turns out to be faster than assumed. Every estimate written before that change already has real budgeted-hours numbers baked into it — numbers a job may have been scheduled and costed against, or a client may have already accepted a price built on. If line items re-read the service live, changing one service setting would silently rewrite the economics of every past estimate that used it, with no record that anything changed. Snapshotting means an old estimate keeps meaning exactly what it meant when it was sent, and a service’s settings can be tuned going forward without touching history.
Complexity multiplier & Rate Matrix pricing
Two more inputs can override the plain manual/production-rate math above. Both are snapshotted onto the line item the moment it’s added or adjusted — same historical-integrity reasoning as budget method, above.
Complexity multiplier. Every line item has a Complexity popover (the icon next to the line’s notes button) set from 50% to 200%, defaulting to 100% (no adjustment). It scales the line’s Rate and Cost together, which is why it doesn’t move GM% — a harder job costs and prices proportionally more without silently changing margin. It also scales the effective hours used for cost, dashboards, and the total-hours column. Critically, the hours you see and edit on the line (“B.Hrs”) always stay the plain, unscaled number you typed or that production rate derived — complexity is applied fresh every time something re-reads the line, never baked back into the stored hours. That matters in practice: dial complexity up to 150%, then back down to 100%, and the line returns exactly to where it started instead of drifting.
Rate Matrix. A service can have banded pricing rows configured against one of a property’s custom fields (e.g. price breaks by Turf Sq Ft ranges). If the estimate has a value for the field a service’s matrix is keyed on, adding that service looks up the matching band and uses its rate, budgeted hours, and cost instead of the service’s flat production rate. The value is read from the property first (a built-in measurement such as Turf Sq Ft, or a custom field), then from the client, so an estimate with no property still prices from a client-level value. A line priced from a band is recorded as Manual budget method going forward, since its hours came from the matrix rather than a formula (a per-unit band on an area line is the exception and stays on the production rate). No value anywhere, or no matrix rows configured on the service, and the line falls through to the ordinary manual/production-rate behavior with nothing different. Like everything else here, the match is looked up once at add-time, not re-resolved later if the property’s field value or the matrix rows change.
Past the last band, the service’s overflow rule (“every Y over X adds $R”, set on the Rate Matrix tab) steps the price up from the last band instead of falling back to the flat rate. See Rate Matrix in the Services & Pricing guide.
Reading the line-item grid
The GM% column color-codes each line’s gross margin, calculated from Rate, Cost, and Adjusted Rate:
- Green — 30% or higher.
- Gray — 10% up to 30%.
- Red — below 10%.
Each line also has a Calc Type toggle between per-unit pricing (× — rate × qty × visits) and a fixed total ($ — the entered rate is the line’s total, regardless of quantity). A fixed line with several visits is the same work repeated: its price covers every visit, and its budgeted hours and auto-calculated cost both count every visit, so the margin isn’t overstated.
An estimate-level flat discount keeps the amount you typed. If the subtotal is smaller than the discount, only the subtotal’s worth applies (a note under the field says so), and the rest comes back automatically when lines are added. On a Good / Better / Best estimate each option is discounted against its own subtotal.
Overhead on the estimate as a whole is either one flat percentage applied to total cost, or — when the org has configured any per-type overhead rate — broken out by cost type instead:
| Cost type | Overhead setting used | Where it comes from |
|---|---|---|
| Labor | Labor Overhead + Labor Burden | Line items’ modeled cost (totalCostCents) is bucketed here, alongside any Direct Cost rows typed as Labor. |
| Sub-Contract | Contract Overhead | Subcontracted work entered as a Direct Cost. |
| Product/Material | Materials Overhead | Materials entered as a Direct Cost. |
| Asset/Equipment | Equipment Overhead | Equipment costs entered as a Direct Cost. |
| Service/Other | Other Overhead | Direct Costs typed as Service or Other — there’s no dedicated bucket for “Service,” so it shares Other’s rate. |
Both the breakeven labor rate and the per-cost-type overhead percentages are org-wide settings, not per-estimate — the breakeven rate is set from Equipt’s Job Costing bid-rate calculator (“Set as project rates”), and overhead percentages live in the org’s overhead settings.
Service bundles and sub-items
A service bundle is a saved set of line items you can drop onto an estimate. Manage them under Settings → Estimates → Service Bundles. In the bundle editor, click + Add sub-item under any bundle item to attach a product or a subservice to it. Search finds your products (not maintenance parts) and your subservices; each sub-item has its own quantity (default 1) and rate, and a delete icon when you hover the row. When you apply the bundle to an estimate, its sub-items come with it, including when you pick it from Apply bundle… on an estimate that already exists.
The bundle editor has two tabs. Details holds Show when creating, the Estimate document and the line items. Display Settings holds the client-view toggles (visits, quantities, prices and so on) that are copied to the estimate when the bundle is used. Choosing an Estimate document links the bundle to one of your estimate-type documents: estimates built from it remember that document, and Send pre-selects it (otherwise your default estimate document is used).
- Print or hide on the estimate. On an estimate line, a printer icon beside each sub-item toggles whether it is printed under the line on the client's PDF, the preview and the emailed copy. New sub-items print by default; sub-items that existed before this feature stay hidden so old estimates look the same.
- On the job. When the estimate converts to a job, each service's sub-items copy to the job with their names and quantities only (no prices). The office sees them under the service on the job, and the crew sees them on the stop as the products to bring and the tasks to do. They don't bill and don't change inventory; the sub-item dollars are already inside the service price.
- Equipment cost. A line can also carry internal equipment cost, which lowers its margin but is never shown to the client. See Equipment costs in the Services & Pricing guide.
Packages on an estimate
Use Add Package (next to Add Item) to quote a package program such as a 5-Step Fertilization & Weed Control plan. It adds a section header named after the package and one line per package service, in package order. Each line keeps the package’s visit count and per-visit price (the package’s own rate, or the service’s default if the package sets none). Quantity, tier, discounts and the estimate totals work exactly as they do on any other line. The package’s Description on Estimate, set in Settings → Packages, becomes the package’s wording on the proposal, and you can edit it on the estimate by clicking the description box under the package header.
If a package service has a Rate Matrix keyed off a property field (such as Turf Sq. Ft.) and the estimate’s property has a value for it, the matching band prices that visit instead of the package’s flat price; the visit's quantity is the client's measurement, and if there is none the package's own price is kept. A package step's price is per visit and is never multiplied by the client's square footage. To copy the first visit’s Qty, Rate, B.Hr, Cost or Adj Rate down to every other visit, use the copy buttons on the package header. Deleting the package header asks for confirmation, then deletes all of its visits, including any hidden by the status tab. A line you add after a package is its own line, priced and accepted separately, not part of the package. Adding the same package a second time is refused.
Each package ends with a Package subtotal row for its visits. To skip a step, set that visit’s status to Draft; Draft and Lost visits are left out of the subtotal, the estimate total and the proposal. Package visits are indented under the header.
Bulk actions. Tick lines in the grid (the header checkbox selects every line, not section headers) and a bar appears above it with Change Status, Rate Increase and Delete. Delete asks for confirmation first. The actions apply only to ticked lines that are showing on the current status tab (switching tabs clears the ticks), and lines already converted to a job are skipped with a note saying how many. A +$ rate increase raises each line's total by that amount per visit, whatever its unit; on a per-unit line too small to carry the amount in whole cents, use a percentage instead.
What the client sees
- A package shows as one main line — name, wording and total — with one checkbox. A package is all or nothing: the client accepts the whole package or none of it, whatever they tick, and the server enforces it.
- The Package visits toggle in the estimate’s “What the client sees” settings (off by default) lists each visit under the main line as plain rows. Leave it off to show only the name, wording and total. It applies to the proposal page, the client portal, the PDF and the
[estimategrid]table in emails. - Packages added before the toggle existed, or whose section header was removed, print as an ordinary section.
Converting
Converting an accepted package creates a Package job, not a plain job. See Jobs & Packages for the details. Package lines convert one package at a time, and never in the same pass as ordinary lines; the convert window offers a button per package. Duplicating an estimate keeps the package tags. The convert window lists each step's planned visit date: if the package's dates are already in the past the Program Start Date defaults to today, and a package with no dated steps can't be converted until its steps have dates. A package service that includes several visits becomes a single step with one visit on the job, billed at that line's full price when the visit is completed.
Where zone measurements come from
Production-rate lines need a quantity to divide by the service’s rate — that quantity usually comes from a property’s zone measurements: Turf Sq Ft, Mulch Bed Sq Ft, Gross Sq Ft, Parking Lot / Hardscape Sq Ft, Linear Ft Perimeter/Edging, Yards of Mulch.
The client-facing proposal link
Every estimate has a public proposal page — the same page a client lands on from the “View Your Proposal” button in the estimate email, where they can review the line items and accept, decline, or request changes online. You don’t have to send an email to get at it:
- Get link / Copy link in the estimate header puts the proposal URL on your clipboard. It reads Get link when no live link exists yet (clicking it creates one) and Copy link once there is. Handing out the link counts as sending it: a draft or quote estimate moves to Sent (the client can only accept a proposal that is Sent), the same as emailing it.
- Open opens that same proposal page in a new tab — handy for checking exactly what the client will see before you send, or for walking a client through it on a call.
- The “N links sent” strip under the header offers the same Copy link / Open shortcuts once at least one link has gone out.
There is one live link per estimate. It’s minted the first time you ask for it (Get link / Open) or the first time the estimate is emailed, and every later copy, open, or send reuses that same URL instead of minting a fresh one — so a link you texted a client last week and the one in this week’s reminder email land on the same page. A link is good for 30 days; after it expires (or the client accepts through it) the next request creates a new one.
When you email an estimate, the subject line shows names and merge fields as plain text (a client called “Smith & Sons” reads exactly that). CC addresses are checked before sending, and the link-expiry setting must be a number of days between 0 and 3650.
The link shows the last version you sent, not your live edits. Emailing the estimate, or using Get link / Copy link / Open, publishes the estimate as it stands right then as a numbered version, and that is what the client sees and can accept. You can keep editing a sent estimate without the client seeing a half-finished revision. Once you’ve edited past it, an amber banner reads “Edited since Version N was sent” and the client still sees Version N — and can’t accept, with a message that an updated version is coming — until you send it again (Send, or Copy link). The client portal’s Estimates page shows the same last-sent version. The version history lists each send, marks links that were shared by link rather than email (“Shared via link”), and tags the version that was accepted with who accepted it and whether it was through the proposal link or the portal.
Lines already agreed. If you re-send an estimate the client has already partly accepted (for example after adding more work), the lines they accepted before appear under Already agreed on the proposal page and in the client portal. They can’t be unticked, and they’re included in the total, so the total on the page is what accepting records.
Choosing a tier. On a Good / Better / Best proposal only the options that have lines are shown, the first one is selected to start with, and each option’s price is its full total (line and estimate discounts, sub-items and tax) — the same figure as the totals box when it’s selected. The client portal’s Selected Total follows the same rules.
Valid until. The proposal page shows the Valid until date. Through the end of that day it can be accepted; after it, the page reads “Expired,” the Accept controls are replaced by a notice, and acceptance (by link or portal) is refused. The client can still decline or use Request changes to ask for an updated proposal. Extend the Valid until date and re-send to reopen it.
Expiry reminders. About three days before an open estimate’s Valid until date, the person who created it gets an email and an in-app reminder. An estimate with no creator (one that came in through the API, an import or an automation) reminds its sales rep instead, provided that rep has a login.
What the client sees. The page shows the client’s billing address and the service address, has a Download PDF button, and a Request changes box. In the estimate’s display settings, Visits, Quantities, and Units are now three separate toggles for what shows on each line, on the page and the PDF.
Where an estimate’s toggles come from. They are copied onto the estimate when it is created or when you pick an Estimate Document or apply a bundle: the document’s toggles win over the bundle’s, and the bundle’s win over the org default. If you changed the toggles on the Client View tab yourself and then switch document or apply a bundle, you are asked whether to Replace toggles or Keep mine. See Documents & Email Templates for the full rules.
Taking a deposit on acceptance
Set Deposit Required on the estimate header and the client is asked for it as part of accepting the proposal, before the acceptance is recorded. If the client unticks lines or picks a cheaper option so the accepted total comes in below the deposit, the deposit is capped at the accepted total rather than blocking acceptance.
- Pay by card charges the deposit through Stripe there and then. It appears once your organisation has finished Stripe Connect setup; the amount always comes from the estimate, so the client can’t change what they’re charged. Your card processing fee applies on the same terms as an invoice payment (only above your threshold), and the client sees the split — deposit, fee, total — before confirming. They are credited the deposit; the fee is yours.
- Pay by bank transfer (ACH) appears if you have ACH turned on. No processing fee. A bank debit takes a few business days to clear, and the proposal is accepted straight away rather than waiting on it — see below.
- The manual methods (check, cash, ACH, credit card, other) do not charge anything. They only record that the client says they’re sending it, so you know to expect it — and reconcile it as a normal payment when it lands.
- Skip for now accepts the proposal with no deposit at all. A deposit never blocks acceptance.
Using it on the first invoice is a manual step — nothing is applied for you, because a converted job invoices its full amount with the deposit not deducted. The invoice tells you when there’s money waiting:
- Open the invoice. If the client has unapplied money, a blue bar reads “$2,000.00 of unapplied payments on this client (including a deposit) — $2,000.00 can go to this invoice”.
- Click Apply to this invoice. It uses the oldest money first, so a deposit is consumed before a later overpayment, and never applies more than the invoice still owes.
- The balance drops and the unapplied figure drops to match. Anything left over stays available for the next invoice. You can still do it the long way — open the payment and edit its allocation — if you want to split it differently.
If the deposit fails — a returned bank transfer (insufficient funds, closed account, a mistyped routing number) or a declined card — the proposal stays accepted. Only the money failed; nothing needs signing again. Three things happen:
- The estimate shows a red payment failed badge with the amount, the date, and the bank’s own reason on hover. That reason is the useful part — “insufficient funds” means ask them to try again, “account closed” means pick up the phone.
- You’re notified — a Deposit failed bell notification and an email, to whoever already receives proposal-decision notifications, plus the estimate’s sales rep. Both can be turned off individually under Notification Preferences.
- The client’s original proposal link re-opens itself so they can pay it again. Re-visiting it shows a “your deposit didn’t go through” screen with the reason and the card / bank-transfer buttons, instead of the usual thank-you. They can’t change the amount, and there’s no Skip button this time — skipping is a choice made before accepting, and by now the deposit is owed.
What a new estimate starts with
- Tax rate. A new estimate starts at the client’s default tax rate, or at no tax if the client is marked tax-exempt (Client is taxable unchecked). You can change it on the estimate.
- Good / Better / Best. Before the client chooses a tier, the estimate total, tax and pipeline value use the lowest-priced tier (“starting at”). That comparison now includes each tier’s priced sub-items, so a tier with large sub-items is no longer mistaken for the cheapest.
- Photos. iPhone HEIC photos are accepted on an estimate’s Photos tab and converted to JPEG on upload, so they also show in the PDF and the emailed proposal.
Rate and probability limits
The estimate’s tax rate, overhead rate, and win probability are percentages limited to 0–100%. A value outside that range is clamped when you leave the field, so a typo like 825 can’t multiply through the totals.
Converting an estimate to a job
Once an estimate is Accepted — whether you set the stage yourself or the client accepted online through the proposal link — a Convert to Job button appears in the estimate header. After a job has been created from the estimate, that same button reads View Job and jumps straight to it, so an estimate is never converted twice by accident.
- From the accepted estimate, click Convert to Job.
- Choose which line items to include — not every accepted line has to become part of the job. Lines that net out to $0 start unchecked so they don’t land on the job (and its invoice) as empty rows; tick them if you really want them. Lines the client declined (a tier or option they unchecked) and lines still marked Draft, which were never part of the quote, are not offered at all, and Draft lines are also left out when you create an invoice from the estimate.
- Pick a Job Type: One Time, Recurring, Project, or Waiting List. An estimate that already bills on its own converts only as a Project (the Job Type is locked and the window says why): one with a live invoice created from it (“This estimate has already been invoiced (#N)”), or one set to bill by milestones. Project jobs aren’t invoiced per visit and take over the estimate’s milestones when you link a project, so the client isn’t billed twice. Void the invoice first if you really want a regular job.
- Set the scheduled date, assign a crew, and enter a Crew Size (men). The crew size is written onto the job and its first visit, so the Dispatch Board’s Men column is right from day one instead of reading 0.
- Confirm. The job is created and a “Job created” entry is logged on the client’s Activity timeline.
Good to know
- Package totals on the proposal. A package's printed total includes its visits' sub-items and line discounts, so it matches the estimate total.
- Client-view toggles. Picking an Estimate Document or applying a bundle only asks whether to replace the client-view toggles when someone actually changed them on this estimate.
- Estimate emails. Client documents used as the Estimate Email or Confirmation Email offer the estimate merge tags and a “View proposal” button link. If the confirmation document linked to an estimate document is deleted, the picker says so; until you choose another, the company's Accepted Email (or the built-in one) is sent.