Colts Neck Interactive
All posts

I built a system that finds local businesses, rebuilds their website, and pitches them

Most AI-agent demos fall apart at the same place: the model produces something plausible, nobody checks it, and it ships. I spent the last few months building a system that generates websites. Most of the code reviews what it produces before anyone sees it.

It's called the Prototype Engine. It runs on my desk and it's behind the free website preview we offer on this site. This is how it works, including the parts I'd change.

The daily loop

Every morning at 8:00, a scheduled job picks one of New Jersey's 21 counties on a deterministic rotation. It queries Google Places across six trade verticals, drops any business without a website, and de-duplicates the rest against every lead the system has seen. It balances the survivors across verticals so one category can't dominate the day, then emails me ten candidates.

De-duplication runs at four layers. Results are collapsed by place ID and then by hostname. Candidates are checked against every prior run, candidate, and skipped lead. Inserting a business that's already in the table does nothing, and hostnames are normalized before comparison. A business I declined in April cannot reappear in August.

That loop is fully automated. Everything downstream is human-approved on purpose: builds, publishing, and the first email to a prospect.

The one decision that matters most

When I approve a lead, the pipeline crawls their existing site and generates a complete replacement — copy, structure, service pages, imagery, brand colors.

The first step is not an AI call. It's a check for whether the business has a findable, publishable email address. If there's no reachable contact, the run stops and spends nothing. A prototype I can't send is wasted work, so one HTTP crawl gates the most expensive step in the run.

The email resolver walks five tiers, from the business's own site down to its Facebook page, and deliberately refuses to guess at info@ or office@. An unverifiable guess risks a bounce, and bounces degrade sending reputation permanently. I'd rather skip the lead.

Making the model's output trustworthy

Generation uses Claude with forced tool use — the model is structurally unable to return prose, only a JSON object conforming to a strict schema of 22 sub-schemas. When validation fails, the retry prompt carries the specific field-level errors, not a generic "try again." Three attempts, then it fails loudly.

A few refinements came from watching it break. Validation runs in two phases, relaxed then strict, because the service pages are generated in a second pass. Failed service-page generations fall back to a placeholder page with the right fields filled in, so the pass always returns as many pages as expected. Returning fewer would make the whole generation step run again. And when the only validation errors are over-length SEO fields, the system truncates at a word boundary and re-validates instead of making another call to the model.

Prompts are config objects per vertical, not edited strings. Unknown verticals throw; there is no fallback. A silent fallback to the roofing config is what once produced a dental practice with a roof leak. A unit test now asserts that a dental prompt never contains the word "roofer."

Vision, and why one model call wasn't enough

Image selection is a two-stage judge. A multi-image call picks the best candidate, then a separate single-image call re-judges it strictly against the page topic. The second stage exists because the first one grades on a curve. Asked to choose the best image for a storm-damage page, it returned another flood. The flood was the best of the candidates and wrong for the page.

A second vision pass curates the client's real photo gallery in batches, rejecting logos, social icons, screenshots, maps, and pricing flyers. That check exists because a gallery once shipped with a Google logo, a Facebook logo, and a pricing flyer classified as photos. The flyer became the hero image.

Every vision path fails open. If the model is unavailable, selection degrades to the first candidate. Image ranking is never allowed to break a build.

The quality gate

Before anything reaches a prospect, over twenty deterministic checks run over the build. Every navigation link resolves to a real route, the client's actual logo is present, and every service page has a real photograph. No image is reused more than twice, no low-resolution placeholders slipped through, and the extracted brand colors clear a 3:1 contrast ratio against the theme.

The rule I wrote at the top of that file: each check comes from a defect we shipped once and fixed. New defects found in review get a check here first. The send endpoint enforces the gate — emailing a prospect a build that carries a blocking flag returns an error and requires an explicit override.

A separate system diffs what the crawler found against what the build shipped and flags any regression in team bios, reviews, galleries, or video. A prototype must never look like a downgrade from the prospect's current site. One practice went from 8 service pages to 21.

What it has actually done

As of early August 2026: 139 businesses sourced and triaged, 44 pipeline runs, and 30 prototypes live on the public internet. Also 24 pitches sent with 26 automated follow-ups behind them, and 441 generated service pages across 11 site themes. Themes are assigned least-used-first so their conversion rates stay comparable. The codebase carries seventy-plus test files with roughly six hundred assertions.

Recent builds also track their own token usage per run, with prompt caching live on the newest runs.

What I'd change, and what I wouldn't

The scheduler is laptop-resident. It fires only when my machine is awake, and there are honest gaps in the data that prove it. Moving it to a hosted runner is the obvious next step.

And the system is deliberately half-automated. It could send pitches unattended; it doesn't, because I review every prototype and every email before a human being receives one.

The free website preview we offer on this site is built by this system. If you want to see what it builds for your business, ask.

Let's build yours.

We'll build a preview of your new website for free — see it before you decide anything.

Get my free preview

Or call (732) 784-7902