CostCandor

= published prices × your house

Price record

  • bid tabulations
  • sealed openings
  • square count
  • verdict

Twenty-five sealed openings on one roofing specification

Published 2026-08-11 · records retrieved 2026-08-11 · our band fixed as of 2026-07 · how we build these numbers

Run your own numbers in the roof replacement calculator →

Our first bid tabulation was a Texas school roof: four sealed envelopes, opened on one morning in 2019, 2.39 times apart. It was one opening, and one opening is an anecdote with a paper trail. This page is the same question asked twenty-five times, on houses rather than schools. The City of Jackson, Michigan bids its housing rehabilitation work out house by house, on a written specification the city reuses, and publishes every tabulation on one page. We read 25 of them covering 102 sealed bids for the same line item — strip and replace the roof of the house — and then tried to put a price per square on it and could not, for two reasons that are the point of the page.

1. What this record is

Twenty-five bid tabulations published by the City of Jackson Purchasing Department, opened between December 2022 and March 2026. Each is one house. Contractors are invited to a pre-bid walkthrough at the property, bid on the city's forms, and the envelopes are opened publicly; the tabulation is then posted as a PDF. The scope is broken into standard coded items — R05 for a strip-and-install roof, G08 for gutterwork, S17 for concrete steps — so the roof line can be read on its own instead of being buried in a lump sum. The specification behind R05 is printed in full inside one of the tabulations and is quoted below.

Two things follow from the program rather than the paperwork. The contract is signed between the winning bidder and the homeowner, not the city: the packet's Instructions to Bidders say the successful bidder "will be required to enter into a contract with the property owner by executing a Construction Contract Rehabilitation of Residential Property." And the money is federal, which brings clauses discussed in section 2.

The records, and a note on addresses

City of Jackson, Michigan, Purchasing Department — Bid Tabulations, an index of 836 documents. The 25 tabulations used here, plus the one full solicitation packet quoted for its federal clauses, are listed with byte size and SHA-256 in section 3. Retrieved 2026-08-11, all HTTP 200; the server returns no Last-Modified header for these files, so the digest is the only version handle there is. License unconfirmed — the city publishes no terms-of-use or copyright page we could find and none of the PDFs carries a reuse notice, so we quote figures and link to the originals rather than reproduce the pages.

We cite every document by its numeric DocumentCenter id rather than its filename, and no street address appears anywhere on this page. The filenames spell out the addresses of private houses whose owners qualified for a low-income rehabilitation grant, and one solicitation packet we opened prints the homeowner's name on its cover. The city chose to publish those; we are not going to amplify them next to a paragraph about household income. The numeric URLs return byte-identical files — verified by digest — so nothing about reproducibility is lost.

These are PDFs, so the reproduction is a shell session rather than a query.

# 1. the index, then one tabulation by its numeric id. no slug, no address.
curl -sS -o bidtabs.html -L "https://www.cityofjackson.org/238/Bid-Tabulations"
grep -c "DocumentCenter/View/" bidtabs.html      # 853 matching lines,
                                                 # 836 unique document ids

curl -sS -D h.txt -o 11654.pdf -L \
  "https://www.cityofjackson.org/DocumentCenter/View/11654"
grep -iE "^HTTP|content-length|last-modified" h.txt
# HTTP/2 301 -> HTTP/2 200
# content-length: 117206
# (no last-modified header is sent)

shasum -a 256 11654.pdf
# 23804abac9365260dc24e8e6684cab87b3b863232bd748feef1f92775cb83b99

# 2. the R05 specification, printed inside this one tabulation
pdftotext -layout 11654.pdf - | sed -n '9,22p'

# 3. the search that decides this page: which tabulations state an area?
#    (over all 25 files in the cohort)
for f in *.pdf; do
  pdftotext -layout "$f" - | grep -qi "squares" && echo "$f"
done
# 11654.pdf        <- one file out of twenty-five

pdftotext -layout 11654.pdf - | grep -oE "Approximately +[0-9_]+ +squares"
# Approximately 13 squares           <- what the lower bidder wrote in
# Approximately 13 squares           <- and the higher bidder
# Approximately __________ squares   <- the blank, as the form prints it

# 4. the federal clauses, from the one full solicitation packet in the index
curl -sS -o packet.pdf -L \
  "https://www.cityofjackson.org/DocumentCenter/View/8087"
shasum -a 256 packet.pdf
# 9cffd831e6f2c2941489939845cdff9c329550a928c9699eeff11940c7640aa6
pdftotext -layout packet.pdf - | grep -n -A2 "Davis-Bacon"
# 220:6. Davis-Bacon Act. For all contracts in excess of $2,000, Contractor
#     must comply with the Davis-Bacon Act (40 USC 276a to 276a-7), as
#     supplemented by Department of Labor regulations (29 CFR 5).
pdftotext -layout packet.pdf - | grep -ic "wage determination"
# 0        <- no wage schedule is attached to the public packet

# 5. our own side, from this site's data rather than by hand
python3 -c "
import json; d=json.load(open('data/roofing.json'))
m=d['materials']['asphalt_arch']; t=d['tearOffPerSquare']
print(d['asOf'], {k: m[k]+t[k] for k in ('low','typical','high')})"
# 2026-07 {'low': 550, 'typical': 735, 'high': 1000}

# 6. vintage. BLS CPI-U, all items, US city average.
curl -sS -X POST -H "Content-Type: application/json" \
  -d '{"seriesid":["CUUR0000SA0"],"startyear":"2021","endyear":"2026"}' \
  "https://api.bls.gov/publicAPI/v2/timeseries/data/"
# 2023 M10 307.671 ... 2026 M06 333.952   -> factor 1.0854
# 2025 M10 returns "-": that month carries no published index. The two
# October 2025 openings are deflated with September 2025 instead.

2. What it measures — and what it quietly does not

This decides whether anything below can be set against our band, so it comes first.

  • Twenty-four of the twenty-five state no area. The city's own bid form asks for one — "Approximately __________ squares on__________", printed with the blanks — and exactly one published tabulation reproduces a bidder's filled-in answer. On that one, both bidders wrote 13 squares. Everywhere else the denominator that would turn a price into a rate is simply absent from the public record.
  • The specification buys a new roof deck. R05 reads, verbatim: "Strip existing roof, removing all shingles and felt. Make repairs to the existing roof framing where required to provide adequate strength and a true and level surface. Install 7/16” oriented-strand board sheathing to cover all areas of roof deck." Our band does not price that. This site's own quote checklist treats decking as an extra, billed per sheet, on the sheets that turn out to be rotten — and our calculator publishes $75–150 installed per 4x8 sheet for exactly that. Here every roof gets a full new skin of sheathing before the shingles go on. It is the single largest scope difference on this page and it runs against us.
  • The federal clauses are real and unpriced. The solicitation packet's Special Provisions state that HUD funds are involved and, at item 6, that "For all contracts in excess of $2,000, Contractor must comply with the Davis-Bacon Act." No wage determination is attached to the public packet and we did not find one elsewhere in the index, so whether a prevailing wage was actually enforced on a one-house rehabilitation is a question this record does not answer — and we are not going to answer it from outside. What is certain is that the bidders read that clause before pricing, along with Section 3 reporting and a SAM.gov registration requirement: one bid in this file is annotated "Incomplete Bid - missing sam.gov info."
  • Opening amounts are not contract amounts. None of the 25 tabulations records an award, a change order, or a final payment. The packet says the award goes to the lowest responsible bidder but reserves the right to reject any bid, and even to award to a non-lowest bidder if the owner pays the difference.
  • The contractor pool is small and repeats. One firm bid in 22 of the 25 openings; three others bid in 14, 15 and 16 of them. These are not 102 independent draws from a national market; they are 102 draws from a handful of firms working one small Michigan city, most of them headquartered somewhere else in the state.
  • Bundled scopes are excluded here, not absent there. Most of these houses also bought gutters, steps, masonry or appliances in the same envelope. Those lines are priced separately on the tabulation and are left out of every number below, which is only possible because the city itemises. A lump-sum tabulation would have made this page impossible.

3. The cohort: twenty-five openings, and what was left out

The rule, fixed before the arithmetic: every tabulation on the city's public index, opened 2022-01-01 or later, that prints a line for stripping and replacing the roof of the house and shows a price from at least two bidders. Every printed price for that line is included. Two bids carry the city's own annotation that the bidder's paperwork was incomplete; their prices are still in, because a price a contractor wrote and sealed is a price, and dropping the ones we disliked would be indistinguishable from choosing a result.

What that rule excludes, and why. Garage roofs and low-pitch roofs. The city prices a garage as its own line and uses a separate code, R02, whose expanded label in one tabulation reads "ROOF – LOW PITCH STRIP AND INSTALL HOME"; both are different jobs from a pitched house roof and neither is in the numbers. Four openings in the same period priced the house roof under R02 or under an explicit low-pitch label, and are out on that basis alone. Single-bidder openings. Two openings drew one responsive bid; with nothing to compare, they contribute nothing to a spread. One unreadable tabulation. In one file the itemised columns do not align with the bidders — a gutterwork line reads $17,039 against a $2,305 roof — and rather than guess we dropped it. Everything before 2022. Four openings from 2020–2021 exist and are left out to keep the vintage adjustment short. Their spreads run 1.84× to 2.28×, which is to say including them would have widened the finding below rather than narrowed it.

Then the check that makes the transcription trustworthy. Twenty-two of the 25 tabulations print a total for each bidder alongside the itemised lines. We added every bidder's itemised lines back up and compared: 90 bidder totals, zero mismatches, to the cent. The other three print no total row, and that is stated rather than papered over. The reconciliation is the reason we are willing to publish a table this long transcribed by hand from ragged PDF layouts.

OpenedDocumentBidsLowestMedianHighestHigh ÷ low
2022-12-08110492$8,400.00$9,100.00$9,800.001.17×
2023-05-10112564$15,260.74$17,525.50$24,499.701.61×
2023-10-02116542$11,100.00$11,287.50$11,475.001.03×
2023-10-26117662$16,490.29$17,245.15$18,000.001.09×
2023-11-13117582$15,380.00$17,267.00$19,154.001.25×
2024-02-27122305$7,700.00$13,377.00$15,330.001.99×
2024-03-20123374$11,561.54$12,542.50$14,424.651.25×
2024-04-09123533$10,500.00$10,717.98$11,352.601.08×
2024-04-16123775$11,275.00$13,093.40$15,518.401.38×
2024-05-07124564$11,128.37$11,900.00$12,469.001.12×
2024-05-08124576$8,500.00$9,243.00$14,021.501.65×
2024-06-12125705$8,895.00$12,406.09$15,041.281.69×
2024-06-12125712$11,226.51$11,726.76$12,227.001.09×
2024-08-01127614$12,180.00$13,024.68$19,500.001.60×
2024-09-05128465$9,200.00$12,500.00$14,600.001.59×
2024-10-03129875$11,360.92$12,500.00$14,600.001.29×
2024-10-04129996$11,400.00$14,355.18$26,200.002.30×
2024-10-16130424$9,800.00$12,473.50$13,126.001.34×
2024-10-16130443$10,000.00$13,420.00$14,400.001.44×
2024-11-12131064$11,200.00$13,655.00$16,701.001.49×
2024-11-14131174$7,725.00$9,485.00$10,900.001.41×
2025-01-08132715$7,500.00$9,400.00$12,550.001.67×
2025-10-03140046$7,800.00$12,566.56$16,500.002.12×
2025-10-03140056$6,500.00$12,072.10$16,900.002.60×
2026-03-03143594$12,200.00$17,194.50$21,591.821.77×

Document digests, in the order above, all 25 retrieved 2026-08-11 at HTTP 200 from https://www.cityofjackson.org/DocumentCenter/View/<id>: 11049 16,914 bytes f7177fcb76d87c03be0c329a254498787dabae616c9d3be0794ee56c7d1ea5d3; 11256 16,768 8d6849ef7ba5b91e54b89403092695293b04944851423a8616d007edae21b508; 11654 117,206 23804abac9365260dc24e8e6684cab87b3b863232bd748feef1f92775cb83b99; 11766 15,538 3114fcc886a7c5f4199adb0d8c96af74d2fccef29ebecad0697c5e0b323cd1cf; 11758 104,276 11d456bfd5d841b035909db61ab404739cc1762902c9a30c2a9d84962e1bfbb5; 12230 16,278 bed9a2bbc4944bb40307e930d804b2135f2b8c5d652a0043402bceb5eba7179a; 12337 16,674 5c927694cfe3a2d7b6c040a9e381d959dc0628cda6d98d82d287dfa268703dfc; 12353 12,816 bb5abc765a0a879fb9eeef2102ee14481e93c7e239003563100c976013d40e82; 12377 13,834 9f697acb847d51fdeb41fd5091fc7f56d89e01146631068af2393eb472f06f3d; 12456 18,734 ad4869a13eef1e747671635b7d1b93129cbbb57e1d539194458d12d700b40f64; 12457 19,368 de57fcb6035bf7b001d0c2c2e1a6f23d45fe98946247ec737cab7545ae567a74; 12570 20,950 21d26a160dad9b0a367722d81cf8bf9daf96e8ed479f262621815766f1d058a0; 12571 20,492 5c5e6a6bb0dd3a0ca1d92c05a219e34aee6469b79ebcc479a332c54df1e60848; 12761 21,742 f570b9f4555dd3c4f614dcbfea4901e09c12e8702c63e1d2170c98e29d4b25d9; 12846 24,798 75762691a5c146938e6915131d8b2e2b647e149179baf5a1de536682ec0188d3; 12987 25,322 98cc46f7dd8eec466e69d4e9511aa434820e3a3711991c05527436a526cb96d2; 12999 22,880 e905bfaddd20f809cb797573656b288536577d8b4b74ae56e9b977c85f46121b; 13042 22,847 52008a9241d5be4d22f41dab09823d6f04c318bdc43821a6f4a942c08bb6360f; 13044 22,294 adb2f7eac7301fc7e3af352f683646c1d3d885e66a1a0a8015e99957cdec1f82; 13106 22,536 1897f980c84b74b82db85d708d0633c5f42baa80c4634e6eb5100b3debf33608; 13117 22,880 e6b037ad0bce8ba31a948a2611bd63ca7b7ba122f6b982f50fe19932daaefc59; 13271 23,194 c9c56da714ddd3c5c0ed827199e0ecefeef80067fe0e23dec12ecbe29a2ad2be; 14004 128,675 6201f8c487932e5ae93a2e452327d2d17d18c1910b5c45791598bec4c457693f; 14005 131,898 d6f4637f1a2d2c20d2213c8a7a206bc1168f452b5ce21421ee8204fb5fa4a4f5; 14359 124,773 7190156374ce78da4bb2936f3e4defd16a88df848b106274f7c344adb2e630ef. The solicitation packet quoted in section 2 is document 8087, 519,674 bytes, 9cffd831e6f2c2941489939845cdff9c329550a928c9699eeff11940c7640aa6.

4. What the file establishes, and the one number it will not yield

Start with what does not need a denominator. Across the 25 openings the highest bid divided by the lowest runs from 1.03× to 2.60×, with a median of 1.44× and a mean of 1.52×; the quartiles are 1.21× and 1.68×. Seventeen of the 25 came back at least 25% apart, eleven at least 50% apart, and three at least twice apart. Within each opening the lowest bid was a median 86.1% of that opening's median, and the median distance from lowest to second-lowest was 13.4%.

That is the "get three bids" line from our checklist, measured. One opening at 2.39× was an anecdote. Twenty-five openings on a specification a city wrote once, walked every bidder through on site, and bid out to the same handful of firms, with a median gap of 44% between the cheapest and dearest envelope, is something you can plan around.

Across the 25 openingsValue
Openings / sealed bids on the house-roof line25 / 102
Highest ÷ lowest — median1.44×
Highest ÷ lowest — mean1.52×
Highest ÷ lowest — range1.03× to 2.60×
Openings at least 25% / 50% / 100% apart17 / 11 / 3
Lowest bid as a share of its opening's median86.1%
Lowest to second-lowest, median gap13.4%
All 102 bids in June 2026 dollars — median$13,057.89
Lowest bid per opening in June 2026 dollars — median$11,832.88

Now the number the file will not yield. Our roof replacement calculator prices in dollars per square — 100 square feet of roof surface — and on roofing.json at its 2026-07 stamp, architectural asphalt plus tear-off is $550 low, $735 typical, $1,000 high per square. To meet it, these bids need an area, and one tabulation out of 25 has one: two bidders, both writing 13 squares, at $11,100.00 and $11,475.00 in October 2023.

Divide and you get $853.85 and $882.69 per square; carried to June 2026 dollars on the CPI-U factor of 1.0854, $926.78 and $958.09. Both sit inside our band, near the top. We are not going to bank that, and the reason is not sample size — though n is two bids on one house, which would be reason enough.

The reason is the deck. This specification puts new 7/16” sheathing over the entire roof, and our band prices no sheathing at all. On our own published figure of $75–150 installed per 4x8 sheet, a 13-square roof is 1,300 square feet, or 41 sheets, or $3,075 to $6,150 — $236.54 to $473.08 per square. Subtract it and the same two bids read $453.70–$690.24 and $485.01–$721.55 per square. Depending on which end of our own decking band you pick, the roofing inside these bids either sits in the middle of our range or falls straight through its floor. One estimate, two answers, and we would be choosing which to print after seeing the numbers.

Two sealed bids to re-roof one Michigan house, the only opening of twenty-five that records the roof's size, drawn against our own band on one axis of dollars per square. As tabulated the bids read $926.78 and $958.09 in June 2026 dollars, both inside our $550 to $1,000 band and near its top. The specification also buys a complete new sheathing deck, which our band does not include; subtracting it at our own published $75 to $150 per sheet leaves $453.70 to $690.24 and $485.01 to $721.55. Those two dashed rows straddle the bottom of our band, so the same two bids either sit in the middle of our range or fall through its floor depending on a figure the document never supplies.
The one bid with an area, before and after its new deckDollars per square, carried to June 2026. City of Jackson opening of October 2, 2023 — the only tabulation of twenty-five that states how big the roof was.† The two dashed rows are ours. The specification sheathes the whole deck in new board, which our band never prices, so our own published per-sheet figure is subtracted over 41 sheets.Whether the residual lands inside our band or under its floor is decided entirely by which end of that decking band you pick. That is the reason this record is a rejection.City of Jackson, Michigan bid tabulation opened October 2, 2023, two bidders, both writing 13 squares on the city's bid form. Nominal amounts carried to June 2026 on CPI-U. Our row is architectural asphalt plus tear-off from roofing.json (pricing as of 2026-07).

Two honest caveats point in opposite directions and neither rescues the comparison. Our per-sheet band prices swapping a rotted sheet, which includes tearing the old one out; this specification appears to overlay new board on the existing deck, which should cost less per sheet. Against that, the specification also carries framing repair, ice shield to 24 inches inside the wall line, two layers of 90# roll valley, chimney and wall reflashing, and full-ridge ventilation — a heavier scope than our band assumes on all four counts. We can say the two jobs differ. We cannot say by how much, which is the same thing as saying the check fails.

5. Verdict

Verdict

(C) Comparison rejected — one opening in twenty-five states an area, and the specification buys a roof deck our band does not price.

This is the richest public roofing record we have opened and it still cannot check a per-square band. The blank on the city's bid form is the whole story: the form asks for the square count, the bidders sometimes write it in, and the published tabulation reproduces it once in twenty-five. Where the number does survive, a second problem is waiting — the job includes a complete new sheathing skin, and stripping that out at our own published per-sheet rate moves the answer from the middle of our band to below its floor. A test whose result we pick afterwards is not a test.

So the band stands where it stood, fixed at the 2026-07 stamp on roofing.json, which predates the 2026-08-11 retrieval above. Nothing in that file was changed by this record, and nothing in it should be: this is one small Michigan city, on federal money, buying a heavier roof than the one our calculator prices.

What the record does establish needs no denominator, and it is the reason the page exists. Twenty-five times, a city wrote a specification, walked contractors through the actual house, and opened sealed envelopes. Twenty-five times the envelopes disagreed — by a median of 44%, by more than half in eleven cases, by more than double in three. That happened with a written scope, a site visit, and a public opening. Our quote checklist has told readers to collect at least three bids on one specification since before we had any evidence for it. This is the evidence, and it is stronger than the advice: the third bid is not insurance against a rogue quote, it is the only way to find out where the middle of your own market is.

6. If you are collecting roof quotes

Four questions, each one a gap in these documents.

  • "How many squares, and will you write it on the quote?" A city with a printed blank for this got an answer it published once in twenty-five tries. You will do better, because you can refuse to accept a price without one — and two bidders whose square counts disagree have told you something before you compare a single dollar.
  • "Is new sheathing in this price, or priced per sheet?" The gap between those two answers is $236 to $473 per square on our own numbers, which on a 13-square roof is $3,000 to $6,000. It is the largest single scope difference on this page, and on your driveway it is the line that decides whether the cheap bid stays cheap after tear-off.
  • "What is the ice shield, the valley, and the ventilation?" This specification names all three explicitly — shield 24 inches inside the wall line, two layers of 90# roll or metal valley, ridge venting the full length of the ridge. Quotes that name none of them are not cheaper jobs, they are less specified ones.
  • "How far apart are my bids, and is the low one alone down there?" In this file the low bid sat a median 13.4% below the next one up. A gap much wider than that is worth a question rather than a signature — not because the low bidder is wrong, but because in these tabulations the isolated outlier is as often the one who read the scope differently as the one who sharpened the pencil.

The tempting reading of a 2.60× spread is that somebody is cheating. This record supports nothing of the kind: it never says who won, never says what was finally paid, and never says whether the low bidder finished the job. What it supports is narrower and more useful. On roofs, a written specification and a walkthrough do not converge prices. They only make the disagreement legible.

Frequently asked questions

How much do roofing bids on the same house actually differ?

In this file, by half again. Across 25 separate sealed openings on one written specification, the median opening's highest bid was 1.44 times its lowest and the average was 1.52 times; the tightest was 1.03 times and the widest 2.60 times. Two-thirds of the openings came back at least 25% apart and eleven of the 25 came back at least 50% apart. These are ordinary houses in one Michigan city, bid by a small pool of the same contractors, on a specification the city wrote once.

Does the lowest roofing bid mean you are leaving quality on the table?

The record cannot say, and neither can we. What it does show is where the low bid sits: across the 25 openings, the lowest bid was a median 86.1% of that opening's median bid, and the gap from lowest to second-lowest was a median 13.4%. A single low outlier is common in this file. So is a tight cluster with one high outlier. Reading either pattern as proof of padding or of corner-cutting goes well past what a tabulation records.

Why can't you work out a price per square from these bids?

Because 24 of the 25 tabulations never state the roof's size. The city's bid form has a line reading "Approximately ____ squares on ____" for the bidder to fill in, and exactly one published tabulation reproduces a filled-in answer. Without the area there is no denominator, and importing a roof size from anywhere else would describe that other source rather than this one.

Is public rehabilitation work priced like a private re-roof?

Not quite, and this specification is the reason. It requires new oriented-strand board sheathing over the whole roof deck, which an ordinary residential quote treats as an extra billed per sheet only where the old decking is rotten. It also carries HUD contract clauses: the packet's Special Provisions apply the Davis-Bacon Act to contracts over $2,000, and one bid in this file was marked incomplete for missing SAM.gov registration. Those are costs a homeowner phoning a roofer does not impose.

Sources

Outside records: City of Jackson, Michigan, Purchasing Department bid tabulations, 25 documents opened 2022-12-08 to 2026-03-03, plus solicitation packet 8087 of 2020-11-18; all retrieved from cityofjackson.org on 2026-08-11 and digested in section 3. Public procurement records of a Michigan municipality administering a HUD-funded residential rehabilitation program, quoted and cited here, not reproduced; addresses and owner names deliberately omitted. We filed no records request, so awards, final contract amounts and any wage determination are not established here. Vintage adjustment: BLS CPI-U, series CUUR0000SA0, pulled from the BLS Public Data API on 2026-08-11; June 2026 = 333.952. Our band: data/roofing.json, architectural asphalt plus tear-off as of 2026-07; the per-sheet decking figure is the $75–150 band published on our roof replacement calculator. Figures on this page are planning ranges, not quotes.

Cost math by CostCandor