Data & research

Boomer

Finds small businesses whose owners are likely approaching a sale or retirement, by aggregating public directory data and scoring it.

Public records Missouri + 8 states robots.txt gated Claude Code agents

See it work

Boomer — live demo Open full screen ↗

The problem

Nobody publishes a list of business owners who are ready to sell or about to retire. That signal has to be inferred from directory data scattered across hundreds of small, inconsistent sources, each with its own markup and its own rules about what a scraper may touch.

Missouri and its eight neighbours means hundreds of separate chamber-of-commerce and business directories, each one its own scraping problem, and each one liable to change its front-end without notice.

The harder problem isn't finding the data — it's trusting it. A wrong phone number or a falsely merged business record is worse than an empty field, and at this scale nobody can check every row by hand.

What it does

Business index
Every business found across Missouri and its eight neighbours — IA, IL, KY, TN, AR, OK, KS, NE — filterable by state, category and succession score.
Owner candidates
Candidates surfaced by agents as likely nearing a sale or retirement, each one carrying a source and a confidence grade.
Provenance on every row
Click a business and see field-by-field provenance — where a phone number, an address or an owner name actually came from. A missing field shows NULL rather than a guess.
Collection agents
Six Claude Code subagents cover the collection phases — among them chamber-scraper, source-discovery, entity-resolver and tos-reviewer — parallelizing within a stage, deliberately not across stages.

How it's built

The data discipline is the actual product. A selector that returns nothing leaves the column NULL — Boomer never writes a guessed field value, because a wrong phone number is worse than a missing one.

Two business records are never auto-merged. Likely duplicates go to a review table with a pending status for a human to confirm, because a false merge silently drops a business from the pipeline and nobody notices — that checkpoint is deliberate, not a gap.

Collection is gated on robots.txt, and only on robots.txt. 43 of the first 91 chamber sources publish a blanket Disallow: / and are never scraped.

Two different directory front-ends get detected per source, because they share almost no markup. One publishes its own result count, so parsed-versus-reported can be verified exactly; the other doesn't, and a category returning exactly 50 rows gets logged as a count mismatch rather than assumed complete. Every load is checked against a scrape-run log.

The numbers

56,655

Businesses

Source: businesses table

37,059

Business contacts

Source: business_contacts table

4,986

Distinct industry categories

Source: business_categories table

191

Registered data sources

Source: data_sources table

4,861

Owner candidates surfaced by agents

Source: agent_owner_candidates table

6,583

State business registrations matched

Source: business_registrations table

What we'd do next

The review table for likely-duplicate records keeps growing faster than a human can clear it by hand. That queue, and widening coverage past the 43 chambers that currently block scraping under robots.txt, is where the next stretch of work goes.

See what this could look like for you

Every project on this site is real software, built the same way. Tell us what's slow or manual right now.

Start a conversation