Construction Estimating With AI: Turn Supplier Quotes Into a Rate Sheet

Coding Liquids tutorial cover featuring Sagnik Bhattacharya for Construction Estimating With AI: Turn Supplier Quotes Into a Rate Sheet.
Coding Liquids tutorial cover featuring Sagnik Bhattacharya for Construction Estimating With AI: Turn Supplier Quotes Into a Rate Sheet.

Give an assistant one supplier quote at a time and ask for one row per priced line: description, unit, unit price, exact source text, validity and exclusions. Convert units with factors printed on the quote, paste the rows into a rate sheet and check them against the quote's total. A rate counts only with its source text beside it.

Takeoff counts what is on the drawing. The rate sheet answers the other half of an estimate: what each unit costs from the suppliers you really use. It is also where small builders leak money, through a price per 1,000 read as a price each, a quote that expired last week or a delivery charge nobody noticed. AI is quick at the typing; the checks below make the output safe to price from. Quantities from drawings are a separate job, covered in the small firm's takeoff test.

Follow me on Instagram@sagnikteaches

Where the rate sheet sits in an estimate

The chain is short. Drawings give quantities through a takeoff. Supplier quotes give rates through the rate sheet. Each estimate line multiplies one by the other, and the quote to the client is built from the estimate lines. Without a rate sheet, rates live in old emails, in last month's job and in memory, and the estimate quietly uses whichever one came to mind first.

Connect on LinkedInSagnik Bhattacharya

A rate sheet has three jobs: hold the current rate for every item you buy regularly, show where each rate came from, and say when it stops being true. That last part, the date, is the one most builders skip.

Subscribe on YouTube@sagnikteaches

The cost of the tooling is small. As of October 2026, the individual plans that handle a handful of quotes a week cost about the same: ChatGPT Plus and Claude Pro at $20 a month, Google AI Pro at $19.99. A free plan works for occasional use, with tighter limits. Supplier quotes are commercially sensitive, so on a personal plan switch model training off in the privacy settings before the first upload; team and business plans keep your content out of training by default.

The Complete Excel Course with AI Integration thumbnail

The Complete Excel Course with AI Integration

From formulas and pivot tables to Power Query, DAX, VBA and AI with Copilot, ChatGPT and Claude — hands-on from the first lesson.

By Sagnik Bhattacharya and Virginia Thorn, Primetime Emmy Award winner

Buy now

Get quotes an assistant can read

The extraction is only as good as the document. A few habits make a large difference:

  • Ask for itemised, written quotes in a digital PDF, one per supplier, with the job reference on each. The RFQ email template tutorial shows wording that gets comparable quotes back.
  • Name files so they sort and trace: supplier, date, quote reference and revision, for example brickmerchant_2026-10-14_Q-A-1043_rev2.pdf. Never rename a file after you have extracted from it.
  • Avoid photos and scans of printed pages when a digital copy exists. If a PDF's text can be selected and searched, it is a digital document. If it cannot, it is an image, and every number needs a human check.

Try Excel before AI for clean digital quotes. In Excel on Windows, Data, Get Data, From File, From PDF opens a navigator that lists the tables Excel detects in the file, and you can load them straight into a sheet. Microsoft's support page describes the steps. It is deterministic, so it cannot misread a digit the way a language model sometimes does, and it is worth a test on your own suppliers' layouts. Where it fails, because a quote is not laid out as a table, the assistant takes over, with the checks below.

The extraction prompt, a messy quote and the row it got wrong

Here is a quote of the kind a merchant sends, with the abbreviations and footer small print that make extraction hard. The figures are illustrative.

QUOTATION  Q-A-1043  rev 2                    14 Oct 2026
Valid 14 days from date above. Prices in USD.

1  Buff multi facing brick, pallet 500 ........ 780.00 per 1000
2  Concrete block 440x215x100 7.3N (pk 96) .... 1.92 ea
3  Cavity insulation bd 100mm 1200x450 ........ 26.40 /sht

Delivery incl. on orders over 1,500.00. Kerbside offload only.
Prices exclude cutting and wastage. Subject to stock at time of order.
Extract every priced line from the supplier quote below into a table with exactly
these columns: Line | Description | Supplier unit | Unit price | Pack size or coverage
(only if printed) | Printed line total (only if printed) | Source text (copy the exact
words and numbers from the quote).
Rules: copy numbers exactly as printed. If a price or unit is unclear, write UNCLEAR.
Do not convert units and do not calculate anything.
After the table, list on separate lines: quote reference and revision, quote date,
validity wording, delivery wording, and anything marked excluding, subject to, POA
or to be confirmed.
[paste the quote text or attach the PDF]

Sample output, with one deliberate fault:

LineDescriptionSupplier unitUnit pricePack or coverageSource text
1Buff multi facing brickeach780.00Pallet 500"780.00 per 1000"
2Concrete block 440x215x100, 7.3Neach1.92Pack 96"1.92 ea"
3Cavity insulation board 100 mm, 1200x450sheet26.40Not printed"26.40 /sht"

Row 1 is wrong. The unit says "each", but the assistant's own source text says "per 1000". Paste that into an estimate and 6,200 bricks cost $4,836,000 instead of $4,836. Nobody would sign that, but the same slip on a smaller scale, a price per 100 read as each, produces a number that looks plausible and quietly loses money. The source-text column is what exposes it: the evidence and the interpretation disagree, and you can see it in two seconds. That is why the prompt demands the exact words, and why a row without them is not allowed into the sheet.

The notes after the table matter just as much. The reply should list Q-A-1043 rev 2, 14 Oct 2026, valid 14 days, delivery included on orders over 1,500.00, and three warnings: kerbside offload only, excludes cutting and wastage, subject to stock at time of order. Those lines go into the rate sheet's notes and the scope-gap review later, because a rate without its conditions is half a rate.

Unit traps: per 1,000, per sheet, per length and per tonne

Suppliers sell in units that estimates cannot use directly. A rate sheet needs one estimating unit for every item, and a factor that converts between the two. The factor comes from the quote or the product datasheet, never from the assistant's memory.

Supplier sellsEstimate needsFactor comes fromRate
Bricks per 1,000 at $780.00Each1,000 per unit, by definition$780.00 ÷ 1,000 = $0.78
Block at $1.92 eachm² of wallSupplier's stated coverage, 9.9 per m²$1.92 × 9.9 = $19.01
Insulation board at $26.40 per sheetm²1.2 m × 0.45 m = 0.54 m² per sheet$26.40 ÷ 0.54 = $48.89
Timber at $31.60 per 4.8 m lengthLinear metreLength printed on the quote$31.60 ÷ 4.8 = $6.58
OSB board at $29.50 per sheetm²2.44 m × 1.22 m = 2.9768 m²$29.50 ÷ 2.9768 = $9.91
Aggregate per tonnem³ placedBulk density from the supplier for that productPrice per tonne × tonnes per m³ (at $30 a tonne and 1.6 t/m³ from the supplier's sheet, $48)
Delivery $65 per dropJob overhead lineNumber of drops planned$65 × drops, unless free over a threshold

The aggregate row is where assistants are most dangerous. Ask for tonnes per cubic metre and you will get a confident, plausible figure, and it will be a generic one, not the density of the product your supplier actually delivers. Put the conversion in your rate sheet only when the supplier has given it to you in writing, and say "UNCLEAR, ask the supplier" in the notes until then. The same rule covers coverage rates for blocks, pack sizes for fixings and the area of a sheet when the quote prints only a nominal size.

The rate sheet layout, and how the estimate pulls from it

Use one Excel table called Rates with these columns: Code, Item, Supplier, QuoteRef, QuoteDate, ValidTo, Price, SupplierUnit, UnitsPer, Rate, EstUnit, Source and Notes. Two points about the design. First, store the supplier's price and the conversion factor separately from the rate, so you can always see how the rate was made. Second, make the rate a formula, not a typed number:

UnitsPer (blocks)   =1/9.9                          (m2 per block, from the quote)
Rate                =ROUND([@Price]/[@UnitsPer],2)
Estimate rate       =INDEX(Rates[Rate],MATCH([@Code],Rates[Code],0))
Estimate total      =ROUND([@Qty]*[@Rate],2)

If your Excel has XLOOKUP, =XLOOKUP([@Code],Rates[Code],Rates[Rate],"NO RATE") does the same job. Either way, do not wrap the lookup in IFERROR returning zero: a missing rate should shout, not become a free item. With the three quotes above, plus a second plasterboard quote, the live part of the sheet looks like this:

CodeItemQuote refValid toRateUnit
BR-01Buff multi facing brickQ-A-1043 rev 22026-10-28$0.78each
BL-01Concrete block 440x215x100, 7.3NQ-A-1043 rev 22026-10-28$19.01m²
IN-01Cavity insulation board, 100 mmQ-A-1043 rev 22026-10-28$48.89m²
TB-01C24 timber 47x150, 4.8 mT-77312026-11-11$6.58lm
OS-01OSB3 18 mm sheetT-77312026-11-11$9.91m²
PB-01Plasterboard 12.5 mm, supplier CPB-55202026-11-12$3.40m²
PB-02Plasterboard 12.5 mm, supplier DD-02182026-11-05$3.55m²

Keep each supplier's rate on its own row with its own code and let the estimate choose on purpose. The comparison is then one line: after converting C's per-sheet price, supplier C is $3.40 per m² and supplier D is $3.55, so D is 4.4% dearer on the same board. Before conversion the two quotes could not be compared at all.

Now the estimate side. Suppose the takeoff, done separately, gives these quantities for the extension. The estimate lines carry only a code and a quantity, and the rate arrives by lookup.

CodeQtyUnitRateTotal
BR-016,200each$0.78$4,836.00
BL-0164m²$19.01$1,216.64
IN-0164m²$48.89$3,128.96
TB-01120lm$6.58$789.60
OS-0138m²$9.91$376.58
PB-01140m²$3.40$476.00
Materials$10,823.78

Wastage, cutting and delivery are not in those rates, because the quotes excluded them. They are separate estimate lines, and that is the point of recording the exclusions. A single sheet that holds both the rate and its conditions stops the same 10% waste being added twice, or not at all.

Five tests before a rate goes live

An extracted rate is a claim. These five tests turn it into something you can price from, and a Checked column holds the date and initials of whoever ran them.

  1. Line test. Where the quote prints line totals, check that quantity times unit price equals the printed total: =ROUND([@Qty]*[@UnitPrice],2)=[@PrintedTotal]. A misread digit fails here.
  2. Total test. The extracted lines, less any discount and plus delivery, should add up to the quote's printed total. If the lines add to $4,150.00 and the quote prints $4,510.00, one row is wrong by $360, and the source-text column tells you which.
  3. Sanity test. Compare each new rate with the one it replaces: =[@NewRate]/[@OldRate]-1, flagged when the absolute change is above a threshold you choose (15% is a sensible start). An ordinary price rise passes, as the bricks' move from $760 to $780 per 1,000, which is 2.6%, would. A unit slip fails loudly, as $780 each would.
  4. Second pass. Run the same quote through a different assistant and compare the two tables. Differences are not errors; they are the rows to look at first. Two assistants are less likely to make the same slip on the same row.
  5. Spot check. Open the PDF and search for the source text of at least one row in ten, and every row above a value you set (say, anything that will make up more than 5% of the estimate). It takes minutes, and it is the only test that catches a quote the assistant read correctly but mis-filed.

The same ideas appear for a different job in checking a quote with ChatGPT, and for plumbers in the tutorial on updating a price book from supplier invoices.

Quotes that arrive as photos, scans or odd number formats

Not every supplier sends a clean PDF. A photo of a printed quote, a scan with a coffee ring across the prices or a handwritten discount scribbled in the margin all go through the same extraction, and all of them raise the odds of a wrong digit. Assistants can misread image digits in the familiar ways of any optical reading: 5 for 6, 1 for 7, a dropped decimal point, a crossed-out figure treated as live. Four habits reduce the damage:

  • Photograph flat and crop to the table. One page per image, good light, no shadow across the figures. A skewed phone shot taken across a van bonnet costs you accuracy for nothing.
  • Make the assistant admit doubt. Add to the prompt: mark every number Clear or Unsure, write each price digit by digit, and treat any crossed-out or handwritten figure as UNCLEAR. Every Unsure row goes to the top of the spot-check list.
  • Watch the number format. Some suppliers print a thousand as 1.000,00 with a decimal comma. Tell the assistant to report prices with a decimal point and to show the original beside it, then check one large figure by eye.
  • Ask for a digital copy on big orders. A scanned quote is fine for $200 of fixings. For the brick or timber package that drives the estimate, a two-minute email to the supplier is cheaper than a mistake.

The total test from the previous section is the safety net here. If the extracted lines do not add up to the printed total, the picture was read wrongly somewhere, whatever the assistant says about its confidence.

Addenda and revised quotes: never overwrite a rate

Rates change in two ways. Suppliers revise a quote, and the tender documents change under you through addenda. Both need a trail, because the question you will one day be asked is "what was the price when you tendered?" Keep a small addenda log beside the rate sheet:

IDDateSourceWhat changedRates affectedActionStatus
ADD-012026-10-14Supplier A, quote rev 2Brick price up, validity cut, delivery threshold raisedBR-01Rev 1 moved to the archive; rev 2 liveClosed
ADD-022026-10-20Tender addendum 1Cavity insulation changes from 100 mm to 125 mmIN-01Re-quote requested from supplier AOpen
ADD-032026-10-24Drawing revision CWindow schedule changes from three windows to fourNone (quantity)Passed to the takeoffOpen

Three rules keep it honest. Never type over a rate: add the new row, move the old one to an Archive sheet and record why. Give the Rates table a Status column (Live, Needs re-quote or Superseded) so an addendum that changes a specification can flag every rate it touches. And let the estimate shout when it uses a stale one, for example =IF(INDEX(Rates[Status],MATCH([@Code],Rates[Code],0))="Needs re-quote","RE-QUOTE","") in a spare column next to each line.

Comparing two versions of a quote is a job an assistant does well, within limits. Attach rev 1 and rev 2 and ask: list every difference between these two quotes, in prices, units, quantities, validity, delivery and exclusions, including the footer small print; show each as old wording, new wording. Sample output lists the two changes in the table and header: line 1 from 760.00 to 780.00 per 1000, and validity from 30 days to 14 days. It misses the footer, where free delivery moved from orders over 1,000.00 to over 1,500.00 and "kerbside offload only" appeared for the first time. You find those by reading the footer yourself, and the lesson is to ask for the diff twice, once in each direction, and to name the footer in the prompt. On 6,200 bricks the price rise alone is $124, but the delivery threshold could move a whole order's cost by more.

Scope-gap review: what each quote leaves out

People read what a quote says and miss what it does not. An assistant is useful here because it can be told to mark absence. Write your own scope list for the materials package first, then ask for a matrix with a third category, Silent:

Below is my scope list for materials supply on a single-storey extension, then three
supplier quotes (A, B, C). For each scope item and each supplier, mark Included,
Excluded or Silent, and quote the words that justify it. Assume nothing a quote does
not say. Finish with a list of questions to send to each supplier.
SCOPE LIST: delivery to site; offloading onto site; cutting to size; fixings and
accessories; wastage allowance; lead time; price validity; minimum order or delivery
charge; packaging or pallet returns.
[paste the three quotes]
Scope itemSupplier ASupplier BSupplier C
DeliveryIncluded over $1,500.00$65.00 per drop, free over $1,000.00Silent
OffloadingKerbside onlySilentSilent
Cutting to sizeExcludedExcludedSilent
Fixings and accessoriesSilentExcludedSilent
Lead timeSilentSilentSilent
Price validity14 days30 daysTo 2026-11-12
Pallet returnsSilentSilentSilent

The grid makes three gaps obvious. Nobody has stated a lead time, so the programme is guesswork. Supplier A offloads kerbside only, so someone has to carry bricks to the rear of the site, which is labour the rates do not include. And supplier C has said nothing about delivery at all, so its low plasterboard rate may not be comparable to D's. The assistant's list of questions becomes a short message to each supplier, with [first name] and [your name] left for you to fill. For the wider job of comparing bids, AI bid levelling and comparing supplier quotes side by side go further.

Keep the sheet alive: validity dates and re-quote triggers

A rate is a statement about a date. Two formulas in the Rates table do most of the policing, and a conditional format can turn the row red:

Expired      =[@ValidTo]<TODAY()
Expiring     =AND([@ValidTo]>=TODAY(),[@ValidTo]<=TODAY()+14)
Age in days  =TODAY()-[@QuoteDate]

Re-quote when any of these happens: the validity date passes, an addendum changes the specification, a supplier announces a price change, a new supplier enters the picture, or the item will make up more than a few per cent of a tender. Treat the shortest validity among your major items as the limit on how long your own quote to a client can hold, or add a clause that lets you adjust for supplier price changes. A client quote valid for 30 days built on a brick price valid for 14 is a promise you cannot keep.

Plan on an hour to set up the sheet and extract the first three quotes while the layout settles. After that, each new quote is a few minutes of extraction and a few more of checking, and the checking is the part to protect. The assistant removes the retyping; the person who knows what a pallet of bricks should cost keeps the final say.

Questions about quote-to-rate-sheet work

Can I upload all the supplier quotes in one go?

One quote per request is safer. Mixing several files makes it easy for an assistant to attach a price to the wrong supplier or merge two units, and a mistake is harder to trace. Extract each quote separately, keep the quote reference on every row, and combine the tables yourself in the rate sheet once each has passed the checks.

Which AI assistant reads supplier quotes best?

Any of the main assistants handles a clean, text-based PDF. The differences show up on scans, photos and odd layouts. Test two on three of your own quotes, compare each result with the printed totals, and choose on the error rate you actually see. Rankings change monthly, so your own test is the only one worth trusting.

Do I need takeoff software for this?

No. A rate sheet is about prices, and takeoff is about quantities from drawings. They meet at the estimate line, where quantity times rate gives the cost. You can build the rate sheet in a plain spreadsheet and fill quantities by hand or from whichever takeoff method you already use.

Further reads

Sources: Microsoft Support page on importing data from a PDF into Excel (Data, Get Data, From File, From PDF); vendor pricing pages for ChatGPT, Claude and Google AI plans; vendor data-control documentation on training defaults for business and consumer plans.

Want a rate sheet your estimates can trust?

On a 1:1 call we'll look at how supplier prices reach your estimates today, set up the extraction and checking steps around your own suppliers and decide how often rates should be refreshed.

Book a 1:1 call with me