I should not be giving this away.
A buy box viability analysis is the first thing I'd want if I were buying a business. It answers one question before you spend a year of your life: how many companies actually match what you say you want, and is that enough to run a search against?
Most buyers never do it. They write a buy box, start emailing, and eighteen months later find out the box only ever contained forty companies.
You can do the whole thing in an afternoon with Claude Cowork or ChatGPT Codex and free government data. Below is the complete method: the data sources, the API calls, the math, the scoring, and a prompt you can paste in as-is.
What you're building
Six outputs. In order:
- The universe. Every business establishment in your industries and geography.
- The size filter. The slice of that universe whose revenue and earnings land inside your band.
- The screens. What survives ownership, quality, and reachability filters.
- The addressable number. What's left. This is the one that matters.
- A score and a verdict. Is this box workable, too tight, or too crowded.
- The sensitivity table. What happens to the number if you widen geography, drop the EBITDA floor, or add an adjacent industry.
Before you start: get the key
Every Census data request now requires a free API key. Metadata pages are open, data queries are not.
Sign up at census.gov/data/key_signup.html. It's instant. You pass it as &key=YOUR_KEY on every call.
The data layer
Four free sources. Each does one thing well and none of them does everything.
County Business Patterns (CBP) is the workhorse. Establishment counts by 6-digit NAICS, by geography, broken out by employment size class. That size breakout is what makes buy-box filtering possible, and no other free source has it at this granularity. Base URL: api.census.gov/data/2023/cbp.
Latest vintage as of September 2026 is 2023, released June 2025. CBP runs about a two-year lag.
The single biggest gotcha: 2023 CBP uses the variable NAICS2017, not NAICS2022. Nonemployer Statistics and the Economic Census use NAICS2022. Copy a parameter name across datasets and your call fails. For most trade and service codes the actual numbers are identical between the two NAICS revisions, so this is a naming problem, not a data problem. But it will stop your script cold.
A real call, every county in Texas, HVAC and plumbing contractors, all size classes: api.census.gov/data/2023/cbp?get=NAME,ESTAB,EMP,EMPSZES_LABEL&for=county:*&in=state:48&NAICS2017=238220&key=YOUR_KEY.
Metro-level is where most searchers actually live, and the geography predicate is ugly enough that it's the most common error people hit. It is not cbsa: api.census.gov/data/2023/cbp?get=NAME,ESTAB,EMP&for=metropolitan%20statistical%20area/micropolitan%20statistical%20area:19100&NAICS2017=238220&key=YOUR_KEY.
The spaces become %20. The forward slash inside the value stays as-is. ZIP is for=zip%20code:84041, with a space, not zipcode.
The employment size codes you'll use, by EMPSZES code and range:
- 001, all establishments
- 210, under 5 employees
- 220, 5 to 9
- 230, 10 to 19
- 241, 20 to 49
- 242, 50 to 99
- 251, 100 to 249
Codes above 250 employees exist but I could not confirm them against a Census source, and no searcher's buy box needs them anyway.
BLS QCEW is three years fresher than CBP, needs no key at all, and returns plain CSV, county by 6-digit NAICS, current through 2026 Q1. No size classes and no revenue, so use it to true up your current establishment count after you've pulled the size distribution from CBP.
Statistics of U.S. Businesses (SUSB) has no API. Download only, from census.gov/programs-surveys/susb/data/datasets.html. Latest is 2022. What it gives you that nothing else does: firm counts, not establishment counts, plus receipts. Receipts only publish in years ending in 2 and 7, so 2022 is current and the next one is 2027. Six-digit NAICS exists at U.S. and state level only. County and metro tables stop at 3-digit.
If you want firm counts with an actual API, Business Dynamics Statistics has them, at api.census.gov/data/timeseries/bds.
Economic Census, at api.census.gov/data/2022/ecnbasic, is the only free source with RCPTOT, total receipts, at sub-state geography. RCPTOT / ESTAB is your cleanest revenue-per-establishment benchmark.
Nonemployer Statistics, at api.census.gov/data/2023/nonemp, counts businesses with no payroll. You will not buy these. Use them as a denominator correction so you can say "of the 4,100 HVAC businesses in this metro, 3,000 are one-truck operators."
Four things that will make your number wrong
Establishments are not companies. Census counts physical locations. A twelve-branch HVAC company is twelve establishments. This inflates your target count, and it inflates it most in exactly the industries that roll up: dental, veterinary, home services. Correct it with an establishment-to-firm ratio from SUSB at state level.
Missing rows are not zeros. Since 2017, Census does not publish cells with fewer than three establishments. In a small county, a narrow 6-digit industry can be absent from the response entirely. Your parser must treat that as "one or two, maybe zero," never as zero. This is the failure that silently breaks county-level scripts.
Wildcard NAICS double-counts. NAICS2017=* returns 2-digit, 3-digit, 4-digit, 5-digit and 6-digit rows as siblings. Sum them and you've counted the same establishment five times. Request explicit codes or filter on INDLEVEL.
PAYANN is in thousands of dollars. Multiply by 1,000. People publish charts off by three orders of magnitude on this one.
And one that will surprise you: NAICS 238220 is "Plumbing, Heating, and Air-Conditioning Contractors." One code. There is no way to isolate HVAC from plumbing in Census data, and no commercial-versus-residential split anywhere in construction NAICS. Anyone sizing "the HVAC market" from public data is sizing HVAC plus plumbing. Say so in your output instead of pretending otherwise.
The math
Here's the whole chain.
Step 1. Universe. Establishments in your NAICS list, in your geography, summed across your target size bands.
Step 2. Map earnings to headcount. You have a buy box in EBITDA or SDE. Census has employees. Bridge them: revenue per employee equals RCPTOT divided by EMP from the Economic Census for your NAICS, implied revenue equals employees times revenue per employee, and implied earnings equals implied revenue times margin.
Worked example, illustrative numbers you should replace with your own pulls. Say 238220 runs roughly $200K revenue per employee at a 10% owner's-earnings margin. A $500K EBITDA target implies about $5M revenue, which is about 25 employees. A $1.5M target implies about $15M and 75 employees. So a $500K to $1.5M box maps to roughly the 20-to-49 and 50-to-99 bands, EMPSZES 241 and 242.
Derive those two constants from Economic Census for your actual industry. Do not use mine.
Step 3. Screens. Multiply the size-band universe by each screen you can defend:
- Ownership. Strip out anything owned by a PE platform, a strategic, a franchise system, or a public parent. In consolidating industries this cuts hard.
- Reachable and verifiable. Working website, findable owner, current phone. Call it 60 to 70 percent of a clean list.
- Quality. Years in operation, owner tenure, signs of life.
Each screen is a number under one, and they compound. Write every one of them down as an adjustable assumption. The value of this analysis is not the final count. It's that someone can argue with your assumptions and rerun it.
Step 4. Addressable. Universe times size band times ownership times reachability times quality. That's the number you take into a search decision.
A real one, from a Northern California healthcare buy box: 1,216 practices in the universe, 763 survived the ownership screen, about 40 cleared a $2M EBITDA floor, about 24 survived quality screening, and 16 were inside the buyer's preferred geography. Sixteen. That buy box needed to change before that buyer spent a dollar on outreach, and the fix was dropping the EBITDA floor to $1M, which took the field to about 84.
Step 5. Score it. Raw count alone is a bad verdict, because too many is as much a problem as too few. Score on distance from a target count on a log scale, then apply modifiers. The formula: base score equals the greater of zero or 100 times one minus the absolute value of log-base-10 of count divided by target, divided by two. Score equals base score times the earnings modifier, times the experience modifier, times the funding modifier, times the competition modifier, times the geography modifier.
Target is the count where a search runs well. Somewhere around 800 works for a one-person search: enough volume to survive the funnel, narrow enough to write something specific to. Set your own and say what it is.
The modifiers all sit between 0 and 1 and each one is a haircut for a real risk:
- Earnings fit. Does the size band you want actually exist in that industry at that scale.
- Experience. First-time buyer or operator with a track record.
- Funding. Committed, in process, or still sourcing. Sourcing takes the biggest cut.
- Competition. PE and roll-up crowding in that industry. Dental gets hammered. Logistics barely moves.
- Geography. A tight metro where a personal network means something scores higher than a national search, where your edge dilutes across the whole country.
Calibrate the values yourself against searches you've watched succeed and fail. Anyone publishing a universal table for these is guessing.
Then set thresholds and give a verdict. Something like: 35 and up, run it. 18 to 34, refine the box first. Under 18, this box doesn't work and no amount of outreach fixes that.
The prompt
Paste this into Claude Cowork or Codex. Fill the bracketed fields first, and treat it as a starting point, not a script to follow word for word.
Open with the framing: you are building a buy box viability analysis, a market sizing for an acquisition buyer. Work in Python. Show your work and label every estimate as an estimate.
Buyer inputs to fill in
- Geography: metro, state, or region, and how flexible.
- Industries: a plain-language list.
- Size metric and range: EBITDA, SDE, or revenue, low to high.
- Financing: SBA, cash, or sponsor equity.
- Exclusions: what they won't buy.
The task, in order
- Map each industry to 6-digit NAICS 2022 codes using the Census NAICS structure file. State plainly where a code is broader than what the buyer described (for example, 238220 covers plumbing and HVAC together, and NAICS has no commercial-versus-residential split in construction).
- Resolve geography to FIPS or CBSA codes using the Census national county file and the July 2023 CBSA delineation file.
- Pull establishment counts from County Business Patterns 2023. Use NAICS2017 as the parameter, not NAICS2022, since it doesn't exist in this vintage. Request EMPSZES to get size classes. Handle three things correctly: a missing row means fewer than 3 establishments, not zero; never sum across NAICS levels without filtering on INDLEVEL; and PAYANN is in thousands of dollars.
- Pull revenue benchmarks from Economic Census 2022 (variable RCPTOT, parameter NAICS2022) and compute revenue per employee and revenue per establishment for each NAICS.
- Bridge the buyer's earnings range to employment size bands: implied revenue equals employees times revenue per employee, implied earnings equals implied revenue times margin. State the margin you used and where it came from.
- Apply screens as explicit, adjustable assumptions: ownership (exclude PE, franchise, public, or strategic-owned), reachability, and quality. Show each as a percentage in its own variable so it can be changed.
- Report the universe count, the count inside the size band, the addressable count after screens, a score and verdict using the formula supplied below, and a sensitivity table showing what the addressable count becomes if geography widens one step, the earnings floor drops 30%, or one adjacent NAICS is added.
Scoring formula to give it
Base score equals the greater of zero or 100 times one minus the absolute value of log-base-10 of count divided by target, divided by two. Score equals base score times the earnings, experience, funding, competition, and geography modifiers. Target is your target count, for example 800. Set each modifier between 0 and 1 and state the value chosen and why. Verdict: 35 or up is workable, 18 to 34 needs refinement, under 18 is not viable.
Rules to hold it to
- Cite the source and vintage of every number.
- Label anything estimated rather than pulled.
- If an API call fails, show the failing URL. Do not silently substitute a guess.
- Output a table that can be handed to someone else, plus the Python.
Add web search and file tools if your setup has them, and give it your API key. It'll build the whole thing, and more importantly it'll show you the assumptions so you can fight with them.
What the number is actually for
The output isn't a business plan. It's a decision.
If your addressable count is 16, you don't have a search, and finding that out in an afternoon instead of a year is the entire point. If it's 4,000, your box is so broad that your outreach will read like everyone else's and you'll get everyone else's response rate.
Run it before you write your first email. Not after.
Data vintages, API behavior, and code lists stated as of September 9, 2026. Census updates vintages annually and geography definitions periodically. Confirm both before you rely on a figure. Employment size codes above 250 employees, and the SUSB enterprise size-class codes, were not verified against a primary Census source.