Most "websites as a service" are $3K setup plus a monthly retainer. Mine is $250 once, live in 24 hours, and the customer drives every edit by sending a plain-English email.
That's not a pitch. That's literally how the system works. I want to show you the architecture, because I think more people should build things like this.
The problem
A local plumber in Atlanta needs a website. Their options:
- Wix / Squarespace — $300 for a year of hosting, pick a template, hope it looks different from the other 40 plumber sites using the same template.
- Agency — $5,000, eight weeks, three rounds of revisions, still feels like a template underneath.
- Fiverr — $250, maybe, but good luck iterating.
The plumber doesn't want options. They want a working site, live tomorrow, so they can point their Google Ads at it and start getting leads. Revisions happen via phone calls with their nephew who "knows computers."
I wanted to build the thing between those options.
The bet
If AI can write code, it can also maintain a simple static website. The hard part isn't the code generation — Claude does that fine. The hard part is the harness around it: payment, provisioning, customer communication, deployment safety. That's all plumbing. And plumbing I can build.
So I built it.
The architecture
Here's the full flow, end to end:
Customer sees ad Customer buys Customer gets site
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Landing page│ ────────▶ │ Stripe Payment │ ───▶ │ Welcome email │
│ with pixel │ │ Link ($250) │ │ (HTML, branded) │
└─────────────┘ └──────────────────┘ └─────────┬────────┘
│ │
│ webhook │ customer replies
▼ │ with plain-English
┌──────────────────┐ │ changes
│ Pipeline service │ │
│ (FastAPI + git) │ │
└──────┬───────────┘ │
│ │
build + provision + deploy │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ Customer's site │ ◀─── │ Email reactor │
│ on its own git │ │ (Claude + tools) │
│ repo + subdomain │ └─────────┬────────┘
└──────────────────┘ │
reactor edits files,
commits, pushes, deploys,
emails the customer back
Six pieces, one flow. Let me walk each one.
1. The landing page
Plain HTML. No frameworks. Hero video showing the end-to-end flow in 55 seconds. One CTA: a Stripe Payment Link. Meta Pixel + Google Ads tag firing PageView → InitiateCheckout → Purchase events across the funnel so paid traffic can optimize.
Why plain HTML? Because every customer site I build is also plain HTML. Eating my own dog food means when something weird breaks, I find it on my own page first.
2. Stripe Payment Link
The fastest "get money in" primitive Stripe offers. No checkout page to build, no PCI scope, no JavaScript to maintain. You click a link, you pay, Stripe redirects to a /thanks/<sku>/ page on my side and POSTs a checkout.session.completed webhook.
Payment Links also have "After payment" metadata fields — customer name, business name, phone. Those come through on the webhook payload, which is exactly what I need to render their first site.
3. The pipeline service
A small FastAPI service listening on a private port. The webhook handler does five things:
- Verifies the Stripe signature.
- Parses the customer's order (email, business name, phone, package).
- Inserts a row into a SQLite orders table.
- Copies a starter template into a new directory named after the business slug.
- String-substitutes
{{BUSINESS_NAME}},{{PHONE}}, etc. into the template's HTML files.
Nothing fancy. A template directory and shutil.copytree plus a replacement loop.
Then it spawns a background task that:
- Creates a private Gitea repo for that customer (
client-<slug>.git). - Runs
git init+ initial commit +git pushin the customer's site directory. The customer's site is now a proper tracked repo, not a loose folder. - Clones the repo to a separate authoring host, so future edits happen on a dev machine instead of on the production box.
- Writes the resulting git URL and commit SHA back onto the order row.
At this point the site is live on a staging subdomain like plumbingco.primeautomationsolutions.com, behind SSL, indexed-ready.
4. The welcome email
SES, not Gmail. Branded HTML. One clear ask at the top:
Send us your logo, 2-3 sites whose look you like, and a short description of what you do. Reply to this email with whatever you have — rough notes, a napkin sketch, a photo on your phone. No forms, no portals, no logins.
The customer's first "real" interaction with the service is an email they can answer on their phone in 30 seconds. Not a dashboard with a 14-field intake form.
5. The email reactor
This is the magic piece.
When the customer hits reply, an email-receiver service picks up the message (I use a catchall domain + a small webhook endpoint) and publishes an event on an internal message bus. A separate reactor service subscribes to those events, looks up the sender in a client_profiles table, classifies the email (is this a website change? an off-topic question? a support request?), and — if it's a site change — spawns a fresh Claude session pointed at the customer's git repo.
The Claude session has access to a short list of tools: read files, edit files, write files, run a restricted set of shell commands, grep and glob. Not much more. It reads the customer's email, understands what they're asking for, navigates the site's files, makes the edits, and reports what it changed.
Then a deploy step takes over:
- Create a timestamped feature branch.
-
git add + committhe changes on that branch. - Fast-forward-merge back to master.
-
git push origin master.
The customer-site repo's master is now advanced. Nginx serves the updated file immediately (same working tree, changes already on disk).
Finally, the reactor sends the customer a second branded HTML email:
"Your updates are live. Here's what changed: [bulleted summary from Claude's session output]. View your site: [link]."
End-to-end, the loop takes about 43 seconds in practice. I know because I sat there watching it happen with a test purchase running through as a fake plumbing company ("RapidFlow Plumbing") on Saturday.
6. The safety nets
The part that nobody writes about when they post their "I built an AI agent" architecture:
- No direct commits to master. A git hook on every clone blocks direct commits; the reactor's deploy step uses a throwaway feature branch specifically to bypass the hook legitimately. (This was a bug I had to fix. See below.)
-
Refuse to spawn Claude on a dirty tree. Before any session launches, the executor runs
git status --porcelain. If the tree has uncommitted or untracked state, it refuses — no Claude run. This saved me from a 131-file mega-commit in an earlier session. -
Signature verification on every webhook. A naked
POST /api/webhook/stripereturns 400 without a Stripe signature. The whole service assumes all traffic is hostile until proven otherwise. -
Email authentication. The reactor verifies the sender is an active client before touching their repo. Forging the
From:header on an email doesn't get you a site rewrite. - Pre-commit secret scanner. API keys and credentials in code would kill the business if any customer site leaked them. A hook runs on every commit.
None of these were in the first version. I added each one after something almost went sideways. The fact that the whole flow works today is because those nets are all in place.
Three things that surprised me
1. The git hook was the hardest part.
A pre-commit hook that blocks direct commits to master is the right safety policy — except it also blocks the very first commit in an empty repo, which is exactly what happens when you're provisioning a new customer site. My first customer order failed at git commit with "BLOCKED: Direct commits to master are not allowed." Took me a beat to realize the hook needs an "allow if HEAD doesn't exist yet" short-circuit.
Small bug, huge impact. Without that guard, the whole pipeline is dead on arrival.
2. Python's scoping rules bit me.
Somewhere deep in the reactor, I had an inner from deployer import deploy statement that shadowed a module-level import. On one code path the inner import never ran, and Python's "function-level from X import Y makes Y local everywhere in that function" rule produced an UnboundLocalError. The customer flow reached the Claude session, got the edits, and crashed at the deploy step. Silently.
The fix was one line. Finding it took an hour because the traceback pointed at a reference to deploy that looked fine.
3. Cloudflare caches 404s.
I pushed a new logo asset, referenced it in nav across 86 pages, deployed. Every visitor saw a 404 for the logo. Direct curl to the origin returned 200. The file was on disk, tracked in git, mode 664, served by nginx. Cloudflare had cached a 404 from an earlier probe before the file existed and was serving that 404 at the edge.
Solution: purge the URL in the Cloudflare dashboard. Five seconds. But I burned twenty minutes chasing ghosts.
What I'm keeping private
I'm not going to paste the exact prompt I send to Claude. I'm not going to show you the reactor's classification code. I'm not going to publish the customer-email templates.
Not because they're clever — they mostly aren't. But because the real moat on a business like this isn't the architecture. It's the six months of debugging and a thousand small judgment calls that separate a working system from a demo. I've written enough here for you to see the shape. If you want to build something like it, you can. You'll just have to find the bugs yourself.
What's next
The obvious upgrades:
- Industry starter templates. Right now every customer gets the same generic starter until they email in changes. Three or four industry variants (local service, restaurant, consultant, ecommerce) would make the first impression much stronger.
- Pre-purchase brief. A one-question form on the thanks page ("Which industry fits you?") would let the first render pick a better template.
- Abandoned-cart recovery. Stripe has it built in. I haven't turned it on yet. Easy win.
And the less-obvious ones:
- Customer-facing dashboard. Not for editing — the email loop is the editing interface. But for viewing status, history of changes, upcoming renewals.
- Referral loop. Every happy customer gets a link that discounts a friend's first site. Small-business-to-small-business is the highest-converting traffic in this space.
Try it
If you're a small-business owner in Atlanta (or anywhere, really) and you want a real website built by a human-plus-AI team in under a day: primeautomationsolutions.com/websites.
If you're a builder and you want to build something like this yourself: the pattern is right here. The primitives are Stripe + SES + Git + Claude. Everything else is plumbing. Happy building.
I'm Erik Anderson. I run Prime Automation Solutions out of Atlanta, GA. I'm a US military veteran and an engineer. This whole site is proof of the architecture described above — every update to this blog post was made by the same reactor loop.
Top comments (0)