Twenty One Media
automationJuly 8, 2026

A Prospect Audit Is a Commit, Not a Feature

Last week we built an ops audit for a medspa prospect, committed it to main, and watched it auto-deploy to the live site. This week we deleted it. Both steps were intentional.

Here's how the cycle works and why we built it this way.

What an Audit Looks Like in the Repo

An audit is a JSON file in content/audits/. It holds the business name, the contact we prepared it for, a snapshot paragraph, and a list of workflows with estimated hours and dollar ranges per year. The JSON drives a Next.js page at /audit/[slug]. The slug includes a short random suffix so it isn't guessable.

{
  "business": "Acme HVAC",
  "slug": "acme-hvac-x0x0",
  "preparedFor": "Jane Owner",
  "date": "2026-07-01",
  "snapshot": "Acme runs residential service and install crews...",
  "workflows": [...]
}

When we commit that file, Vercel deploys it. The page lives at twenty1-media.com/audit/acme-hvac-x0x0. It carries noindex in the metadata and is blocked in robots.txt, so it won't rank for anything. We send the URL to the prospect before the call.

What They Get Before the Call

The audit page reads like a short operations report: a snapshot of what we observed, a list of manual workflows with time and cost estimates, and a total at the bottom. Each estimate shows its assumption inline: "assumes 20 quotes per month at 15 minutes each." If an assumption is wrong, the prospect corrects it on the call. That's useful friction. It moves the conversation from "what do you do" to "is this estimate right."

A Playwright script renders the same page to a PDF for attachment:

node scripts/render-audit-pdf.mjs acme-hvac-x0x0

Both the URL and the PDF come from one HTML file. We don't maintain two templates.

Why We Delete It

When the sales window closes, we delete the JSON file and push. One commit, one changed file. The page is gone.

We do this for three reasons.

First, the audit is a sales artifact with a finite purpose. Once the prospect converts or doesn't, there's nothing for the page to do. A page that exists serves no one but occupies space in the content directory and the site's file tree.

Second, deletion keeps the audit list clean. We have one directory for active audits. If we didn't delete after the window, that directory would accumulate every prospect we've ever contacted. Filtering by active vs. closed audits would require additional tooling or convention. Deletion is the convention.

Third, git history is the record. The commit that added the file shows when the audit was created. The commit that removed it shows when the window closed. If we need to pull up an old audit, we can check out the JSON at that commit and re-render the page locally. Nothing is lost. The deletion just signals that the page is no longer live.

The Build Is About 50 Lines

The audit page component is under 160 lines of JSX. The PDF script is under 60 lines. The JSON schema is simple enough to fill in by hand in about 20 minutes when we've done the research.

That's the point. The time cost of building a prospect-specific audit should be low enough that we can do it for any serious inbound lead, not just large deals. The infrastructure makes that possible. The research is the work.

What makes the audit useful isn't the technology. It's the specificity. A generic "you could save time with automation" page closes no one. A page with a named workflow, a range, and a stated assumption gets a response.