Thirteen sealed bids to paint an apartment, priced per a square foot nobody defined
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 interior painting calculator →
Repainting a house needs no permit almost anywhere, so unlike our other price records this one could not start at a permit counter. There is no public file of what homeowners paid a painter. What there is, is what public agencies pay — and a housing authority buying apartment repaints is the closest thing in the public record to the job our interior calculator prices. So we went and got two of those tabulations. They record thirteen sealed bids, all quoted in dollars per square foot, running from $0.24 to $6.51. Then we tried to put our own band on the same axis and could not, for a reason worth the whole page: the solicitation asks for a price per square foot and never once says which square foot.
1. What this record is
Two one-page tabulations of bids published by the Housing Authority of the City of Pittsburgh (HACP) for the same contract, opened five weeks apart. IFB #300-34-21, "Vacant Unit Painting Authority-Wide," was opened on October 7, 2021 and drew eight bids; HACP's procurement page marks it CLOSED, To Be Rebid. IFB #300-34-21-REBID was opened on November 9, 2021, drew five bids, and is marked Awarded. Behind them sits a 76-page solicitation whose scope of work covers patching, washing, priming and then two finish coats on walls, ceilings, risers, railings, trim and doors, in apartments across what the solicitation calls "over 2500 units of rental housing."
The records
Housing Authority of the City of Pittsburgh, Procurement Department — "Tabulation of Bids," IFB #300-34-21 Vacant Unit Painting Authority-Wide (opened October 7, 2021), Signed-Bid-Tab.pdf, one page, 42,301 bytes, SHA-256 539e6891540c8048fbfc5061c903c9fdde3e808a664db22a61b748ae95c9d688; and "Tabulation of Bids," IFB #300-34-21-REBID (opened November 9, 2021), tabulation-of-Bids.pdf, one page, 79,256 bytes, SHA-256 b1d1497c8a1dac90388af127384026dfd7ea69324430eca47c9ed6569bd61137. Both retrieved 2026-08-11 (HTTP 200). Each file's Last-Modified header is the day of its own bid opening. License unconfirmed — HACP publishes no terms-of-use or copyright page we could find and neither PDF carries a reuse notice, so we quote the figures and link to the originals rather than reproduce the pages. If a link dies, the digests tell you whether the file you found is the file we read.
There is no database query here — these are PDFs, so the reproduction is a shell session. The interesting commands are the ones that fail to find something.
# 1. the two tabulations, keeping headers so you can see the 200 and the dates
curl -sS -D h1.txt -o r1_tab.pdf -L \
"https://hacp.org/app/uploads/2021/09/Signed-Bid-Tab.pdf"
curl -sS -D h2.txt -o r2_tab.pdf -L \
"https://hacp.org/app/uploads/2021/10/tabulation-of-Bids.pdf"
grep -i "last-modified" h1.txt h2.txt
# h1: Thu, 07 Oct 2021 19:37:32 GMT <- round 1 bid opening day
# h2: Tue, 09 Nov 2021 16:39:27 GMT <- rebid bid opening day
# 2. confirm you are reading the same bytes we read
shasum -a 256 r1_tab.pdf r2_tab.pdf
# 539e6891540c8048fbfc5061c903c9fdde3e808a664db22a61b748ae95c9d688 r1_tab.pdf
# b1d1497c8a1dac90388af127384026dfd7ea69324430eca47c9ed6569bd61137 r2_tab.pdf
pdfinfo r1_tab.pdf | grep Pages # Pages: 1
pdfinfo r2_tab.pdf | grep Pages # Pages: 1
# 3. round 1 is a signed scan, not text. this returns one byte.
pdftotext -layout r1_tab.pdf - | wc -c # 1
pdftoppm -png -r 160 r1_tab.pdf r1 # read the eight rows by eye
# 4. the rebid tabulation is real text
pdftotext -layout r2_tab.pdf -
# 5. now the solicitation, and the search that decides this page
curl -sS -o ifb.pdf -L \
"https://hacp.org/app/uploads/2021/09/IFB-300-34-21-Vacant-Unit-Painting-Authority-Wide-revised.pdf"
pdfinfo ifb.pdf | grep Pages # Pages: 76
pdftotext -layout ifb.pdf ifb.txt
# every mention of the unit, in all 76 pages: 19 of them, in two places only
grep -ioE "square foot|square feet|sq\.? ?ft|sqft" ifb.txt | sort | uniq -c
# 10 Sq. Ft <- the average-apartment-size table, printed twice
# 5 Square Foot <- the table heading (x2) and the bid form (x3)
# 2 Sq Ft <- "Pr/Sq Ft" on the bid form
# 2 sqft <- "price to paint/sqft" on the bid form
# and every phrase that would have defined it. none.
grep -icE "wall (surface|area)|painted surface|floor area|square feet of wall" ifb.txt
# 0
# 6. the Authority's own answer, Addendum 2, Item 1
curl -sS -o add2.pdf -L \
"https://hacp.org/app/uploads/2021/09/Addendum-2-IFB-300-34-21-Vacant-Unit-Painting-Authority-Wide.pdf"
pdftotext -layout add2.pdf - | sed -n '15,25p'
# Q: What was the sqft of the last award contract for this contract?
# A: Each job was independently measured. There was not a tracking of the
# overall sqft.
# 7. the spread, from the thirteen figures
python3 -c "
r1=[0.24,0.27,0.30,0.36,0.40,1.98,4.14,6.51]; r2=[0.27,0.31,0.55,4.00,4.75]
med=lambda v:(sorted(v)[len(v)//2] if len(v)%2 else sum(sorted(v)[len(v)//2-1:len(v)//2+1])/2)
for n,v in (('r1',r1),('r2',r2)):
print(n, 'n=%d min=%.2f max=%.2f ratio=%.2fx median=%.2f'
% (len(v), min(v), max(v), max(v)/min(v), med(v)))
print('pooled:', sorted(r1+r2))"
# r1 n=8 min=0.24 max=6.51 ratio=27.13x median=0.38
# r2 n=5 min=0.27 max=4.75 ratio=17.59x median=0.55
# pooled: [0.24, 0.27, 0.27, 0.3, 0.31, 0.36, 0.4, 0.55, 1.98, 4.0, 4.14, 4.75, 6.51]
# 8. our side, computed by this site's own calculator rather than by hand.
# the two script paths are the files this page's calculator ships to you;
# view-source on /calculators/interior-painting/ to find them.
node -e '
const fs=require("fs"); globalThis.window={};
eval(fs.readFileSync("assets/js/cost.js","utf8"));
eval(fs.readFileSync("assets/js/calc/interior-painting.js","utf8"));
const d=JSON.parse(fs.readFileSync("data/painting-interior.json","utf8"));
const r=window.CALC_INTERIOR_PAINTING.estimate({mode:"house",floorSqft:700,
ceilingHeightFt:8,includeCeiling:true,trimLinFt:0,doorCount:0,
grade:"economy",coats:2},d);
const surface=r.wallSqft+r.ceilingSqft;
console.log(d.asOf, r.wallSqft, r.ceilingSqft, surface, r.low, r.typical, r.high);
console.log("per floor ", r.perFloorSqft);
console.log("per painted", ["low","typical","high"].map(k=>(r[k]/surface).toFixed(2)));'
# 2026-07 1750 700 2450 2450 3850 5775
# per floor { low: 3.5, typical: 5.5, high: 8.25 }
# per painted [ '1.00', '1.57', '2.36' ]
2. What it measures — and what it quietly does not
This decides whether anything below is worth putting next to our band, so it comes first.
- The denominator is never stated. Command 5 is the whole finding. Across 76 pages the unit appears nineteen times and in only two places: a table of average apartment floor areas (2 bedroom 700 sq ft, 3 bedroom 850, 4 bedroom 1,200, 5 bedroom 1,550, 6 bedroom 1,700) and a bid form headed "price to paint/sqft." Not one line says whether the square foot being priced is the floor the table describes, the wall and ceiling area actually painted, or something else. The rebid solicitation carries the same two places, word for word.
- The Authority confirms it does not know either. A bidder asked what square footage the previous contract had run to. The written answer: "Each job was independently measured. There was not a tracking of the overall sqft." Nobody on either side of the table was holding the denominator.
- The paint is free to the bidder. "Unless otherwise specified, the Authority shall provide all paint." Our band buys the paint. On our own coverage rule — two coats at about 350 sq ft per gallon, builder-grade at roughly $20 a gallon — that is about $0.12 per sq ft of painted surface, some 12% of our low band. It moves our side down; it does not move it far.
- The scope is heavier than ours in one direction. Every surface is primed before the two finish coats, and the work covers risers and railings as well as walls, ceilings, trim and doors. Our band prices two coats with light prep and no full priming coat. Where the scopes differ, they differ against us.
- And lighter in another. The apartments are vacant: no furniture to move, no householder, no colour to match, and the Authority chooses the product. Spray application is barred, so the method is the brush and roller a house gets. Addendum 2 also states plainly, in answer to a bidder, that "this is not a prevailing wage contract" — so these are market labour rates, not a public-works premium.
- Common areas are inside the same price. Hallways, stairwells and lobbies are in the scope alongside dwelling interiors, and no apartment-size table describes those.
- These are 2021 dollars, and opening amounts. Neither tabulation records an award, a quantity or a contract value. Round 1 was not awarded at all.
3. The cohort: thirteen rows, no filters
n = 13, the entire content of both tabulations. Every printed row is in the numbers below and nothing was excluded — in records this small an exclusion rule would be indistinguishable from choosing a result. Round 1 has eight rows, the rebid five.
The two documents are not equally legible. Round 1 is a signed scan with one byte of extractable text (command 3), so its eight figures were read off a rendered image, and each row carries the words "Per Square Foot" beside the number. The rebid tabulation is real text, and prints its five figures bare — "$0.31", with no unit anywhere on the page. The unit for those five comes from the bid form, not from the tabulation.
Two names appear in both rounds and a third nearly does, which is the closest thing here to a repeated measurement. Jarren Enterprises bid $0.36 then $0.27, a 25.0% cut. National Painting Contractors bid $4.14 then $4.00, down 3.4%. The third pair is "White Water Renovation" at $0.30 and "White Water Painting" at $0.31, up 3.3% — the names are not identical and nothing in either document says they are the same firm, so read that one as a resemblance rather than a repeat. What none of them did was cross the gap between the two price levels. Addendum 2 also names the incumbent at the time — J & S Handyman Services, which bid $0.24 in round 1, the lowest figure on either page.
4. The distribution, and the two axes our band could sit on
| Round 1 bidder, as printed — opened 2021-10-07 | Bid | Rebid bidder — opened 2021-11-09 | Bid |
|---|---|---|---|
| J & S Handyman | $0.24 | Jarren Enterprises | $0.27 |
| Dream Chaser painting | $0.27 | White Water Painting | $0.31 |
| White Water Renovation | $0.30 | Better Maintenance and Cleaning | $0.55 |
| Jarren Enterprises | $0.36 | National Painting Contractors | $4.00 |
| Merkaba Construction | $0.40 | Crown Field | $4.75 |
| Shelly T Contracting | $1.98 | — | — |
| National Painting Contractors | $4.14 | — | — |
| United Field Services | $6.51 | — | — |
Those thirteen figures are printed in the two documents. The ascending sort is ours: round 1 lists its bidders in the order Jarren, Shelly T, United Field, White Water, National Painting, J & S Handyman, Merkaba, Dream Chaser, and the rebid lists White Water, Better Maintenance, National Painting, Jarren, Crown Field. Everything in the next table is also ours, derived from the same thirteen numbers — neither tabulation carries a summary statistic of any kind.
| Derived from the thirteen amounts | Round 1, n 8 | Rebid, n 5 |
|---|---|---|
| Lowest | $0.24 | $0.27 |
| Highest | $6.51 | $4.75 |
| Highest divided by lowest | 27.13× | 17.59× |
| Median | $0.38 | $0.55 |
| Widest empty gap inside the range | $0.40 to $1.98, 4.95× | $0.55 to $4.00, 7.27× |
| Bids at or below $0.55 / at or above $1.98 | 5 / 3 | 3 / 2 |
Pooled and sorted, the thirteen bids read $0.24, $0.27, $0.27, $0.30, $0.31, $0.36, $0.40, $0.55, then $1.98, then $4.00, $4.14, $4.75, $6.51. Eight of them sit at or below $0.55 and four at or above $4.00, with a single bid in between. A price this bimodal, on a specification fixed in writing and bid twice, is not a market disagreeing about labour rates. It is bidders answering different questions.
Now our side, and the reason this record cannot settle anything. Take the 2 bedroom apartment in HACP's own table: 700 sq ft. Our interior calculator, at economy grade, two coats, 8 ft ceilings, walls and ceilings only, on painting-interior.json as of 2026-07, reads that as 1,750 sq ft of wall plus a 700 sq ft ceiling — 2,450 sq ft of paint — and prices it at $2,450 low, $3,850 typical, $5,775 high. One estimate. Two ways to divide it:
| The same $2,450–$5,775 estimate, divided by… | Low | Typical | High |
|---|---|---|---|
| The apartment's floor area, 700 sq ft | $3.50 | $5.50 | $8.25 |
| The area actually painted, 2,450 sq ft | $1.00 | $1.57 | $2.36 |
The two rows are 3.5× apart and do not overlap, and both are honest readings of the same words. That ratio is not a coincidence: our wall factor of 2.5 plus one ceiling makes the painted surface 3.5 times the floor, for every apartment in HACP's table, which is why our per-square-foot band is identical at 700, 850, 1,200, 1,550 and 1,700 sq ft.
Set the bids against each row and neither reading explains the document. Under the floor reading, all four of the high bids — $4.00, $4.14, $4.75 and $6.51 — fall inside our $3.50–$8.25 band, and the eight low bids fall between 6.4 and 14.6 times below its floor. Under the painted-surface reading, the eight low bids are still 1.8 to 4.2 times below our $1.00 low, and the four high ones are 1.7 to 2.8 times above our $2.36 high. Stripping the paint we buy and they do not — 12% of our low band — moves our painted-surface floor only to $0.88, still above every one of the eight. And the vintage does not rescue it either: multiplying the 2021 bids by the CPI-U's own November 2021 to June 2026 ratio of 1.2015 lifts $0.24 to $0.29 and $6.51 to $7.82, changing nothing about which side of our bands anything lands on.
5. Verdict
Verdict
(C) Comparison rejected — the unit price is per a square foot the document never defines.
This is the first painting record we have opened, and it fails in the most instructive way available. The figures are real unit prices in the exact unit our calculator publishes, from an outside party with no interest in this site, on a scope of work that is genuinely close to a house interior: brush and roller, two coats over primer, walls, ceilings, trim and doors, and — the Authority put this in writing — not a prevailing wage contract. Everything that usually blocks a comparison is absent. What blocks this one is a single missing sentence.
Because "per square foot" is undefined, our own band occupies two places on the same axis, $3.50–$8.25 and $1.00–$2.36, and we would be choosing which one to print. Choosing the floor reading would let us report that every one of the four highest bids lands inside our band. That would be a true sentence and a worthless one: we would have picked the denominator that produced it, from a document that supplies none, after seeing the numbers. The other choice is equally available and says the opposite. A test whose result we select afterwards is not a test.
So the band stands where it stood — fixed at the 2026-07 stamp on our interior painting data, which predates the 2026-08-11 retrieval above — and it stands on the sources in our methodology, not on anything here. Nothing in painting-interior.json was changed by this record.
The record still earns its place, and not only as a warning. Round one came back 27.13× apart and was not awarded; the rebid, run on an identical specification with the same undefined unit, came back 17.59× apart and was. The Authority never states why the first round was closed to be rebid, and we are not going to supply a reason it did not give — what the two pages establish between them is narrower and enough: thirteen professional painters reading one written specification could not agree within an order of magnitude on what they were being asked to price, and five weeks and a second opening did not close the gap. If that can happen inside a written public procurement with a question period and two addenda, a per-square-foot rate quoted on your doorstep carries the same ambiguity with none of the paperwork.
6. If you are collecting painting quotes
Four questions come straight out of the gaps in these documents, each asking a bidder to supply what the public record did not.
- "Per square foot of what?" This is the question the whole page exists to hand you. Floor area and painted area differ by roughly 3.5× in a normal room, so a rate quoted without its denominator is not a price. Make every bidder answer in the same unit before you compare two numbers.
- "How many square feet did you measure, and where did you write it down?" HACP could not answer this about its own contract. If your quote states a rate but no quantity, it states no total either — and the multiplication happens after you have signed.
- "Who buys the paint, and how much of it?" The Authority supplying all paint is about 12% of our low band. A quote that excludes material is not comparable to one that includes it, and "customer supplies paint" also hands you the risk of running out mid-job.
- "Is there a primer coat, and on what?" This specification primes every surface before its two finish coats. Most residential quotes do not, and the two are different jobs at the same headline rate.
The temptation with a spread like this is to read the low cluster as the real price and the high one as padding, or the reverse. This record supports neither: it never says who was right, and round one never awarded anybody. What it supports is narrower and more useful — the words "per square foot" did not survive contact with thirteen professionals reading the same page, and they will not survive contact with your driveway either unless you pin them down.
Frequently asked questions
Why can't a price per square foot be compared to another price per square foot?
Because "square foot" is not one unit in painting. A 700 sq ft apartment has about 1,750 sq ft of wall and 700 sq ft of ceiling, so the area you paint is roughly 3.5 times the area you walk on. Dividing the same job by the floor gives one number and by the painted surface gives another 3.5 times smaller. Our own band shows this: the identical estimate reads $3.50–$8.25 per floor sq ft and $1.00–$2.36 per painted sq ft. Unless the document says which denominator it used, the number is a ratio with an unknown bottom.
Does repainting a house need a permit?
Almost nowhere, and that is why this record is a bid tabulation rather than permit data. Our other price records open permit files because re-roofing, panel upgrades and water heaters are permitted work that leaves a public trail with a declared cost on it. Ordinary repainting leaves no such trail, so the only public painting prices with a written scope attached are the ones public agencies buy from contractors.
What does a public housing authority pay to paint an apartment?
This record cannot tell you, which is the finding. The Housing Authority of the City of Pittsburgh took thirteen sealed bids across two rounds at $0.24 to $6.51 per square foot, did not award the first round, and ran the second on an identical specification. Nothing in the public file states the square footage those prices were multiplied by, and the Authority answered a bidder's question about it with "there was not a tracking of the overall sqft."
Is public agency painting priced like painting a house?
Partly, and the differences run both ways. This contract is closer to residential work than most public jobs — real apartments, brush and roll, no spray permitted, two coats over primer on walls, ceilings, trim and doors. But the Authority supplies all the paint, the apartments are empty, and there is no colour to match or furniture to move. The specification is also not prevailing wage, which the Authority confirmed in writing during the question period.
Sources
Outside records: Housing Authority of the City of Pittsburgh, tabulations of bids for IFB #300-34-21 Vacant Unit Painting Authority-Wide (opened October 7, 2021) and IFB #300-34-21-REBID (opened November 9, 2021), with the 76-page revised solicitation and its Addendum No. 2 of September 29, 2021; all four PDFs retrieved from hacp.org on 2026-08-11 and digested above. Public procurement records of a federally funded housing authority, quoted and cited here, not reproduced. We did not file a Right-to-Know request, so who was awarded the rebid and at what figure is not established here. Vintage adjustment: BLS CPI-U, series CUUR0000SA0, November 2021 = 277.948 and June 2026 = 333.952, pulled from the BLS Public Data API on 2026-08-11. Our band: data/painting-interior.json, economy wall and ceiling rates as of 2026-07, computed by the calculator's own code. Figures on this page are planning ranges, not quotes.