Work leadpipe
Finding my own clients: 445 local businesses audited, 43 sites mocked, five pitches sent
Webcraft builds websites, local SEO and ad tracking for small businesses in Minnesota and Wisconsin, and it needed a steady way to find clients. leadpipe searches Google Places and OpenStreetMap town by town, audits each business's site and listing, rules out chains and strong sites, and has Claude judge who needs help and which kind. The best leads get a one-page concept site built from their own words, logo and brand color, plus an email that cites what the audit found. Every email waits in a queue until I read it and type send.
$ leadpipe statsbusinesses 445audited 436with email 109screened 436 (324 pass) $ leadpipe send --confirm send5 sent, 0 held
- Role
- Sole author, and its first user
- Stack
- TypeScript · Node 22 · SQLite · Claude Code · Google Places API · Resend · Vercel
- Links
- Live site · Source on GitHub
Every claim in a pitch is something the audit saw
A cold email that gets one fact wrong about someone's business is finished. So the audit records each finding as a fact with an id: no HTTPS, no mobile layout, an analytics tag that stopped collecting in 2023, a PageSpeed score, no hours on the Google listing. Claude can only build its pitch on those ids, and code rejects any number in an email or a concept site that isn't in the audit or on the business's own site.
That rule exists because of a real miss. Early on, the judge wrote that a dental office had a move coming up. It had read that in a patient review that said "if they ever move, we're going with them."
Unknown is not the same as missing
A map listing without a website usually means nobody added one, not that the business has no site. So leadpipe treats it as unknown, never as a pitch. A site that blocks automated checks is marked blocked, not down. Leads whose site really looks broken wait in the queue until I've checked them by hand. Telling an owner their site is down when it isn't would end the conversation before it starts.
A concept site that looks like theirs, not a template
Each strong lead gets a one-page site written from what their own site says, in their logo and main brand color, with stock photography for their industry. A bar across the top says plainly that it's a concept, not their live site, and it's hidden from search engines.
Getting the branding right took a few rounds. The first color picks included the default blues WordPress, Wix and web browsers use, and two of the logos turned out to be a Facebook icon and an oil-company partner badge. Both now have blocklists. I also check every stock photo by eye before a concept site can use it, after one free photo library returned explicit public-domain art for "chiropractor."
Built to land in the inbox and never send by accident
Emails go out through Resend from a separate subdomain, so a cold email can never hurt the address my clients use. They're plain text with no tracking. My first test landed in Gmail's Promotions tab, because of a header that's only required of bulk senders. Removing it moved the next one to Primary. A warmup caps new mail at five a day, then twelve, then twenty-five.
Claude writes the middle of each email. Code adds the greeting, signature, postal address and opt-out, so the parts the law requires never depend on a model. Nothing leaves until I type send. A separate review before launch found nine bugs, including one where a typo in a flag could have sent the real queue when I meant to send a test. Each one is now pinned by a test.
What it moved
- Local businesses found and audited
- 445
- Concept sites built in each business's own colors
- 43
- Claims in a pitch the audit didn't observe
- 0
- Tests, including one for every bug a review found
- 64