Build Notes6 min read

How I Built an AI Lead System for My Own Studio

I built a lead system for my own studio, then found a security control that looked enforced but was not. Here's the architecture and the fix.

What You'll Learn

The six-stage order that makes a small-business lead system work: capture, verify, store, notify, draft, and send. Also the one-line difference between a security control that looks enforced and one that actually is.

What is an agent-assisted lead system? A lead system where software handles capture, verification, storage, and notification, and an AI agent drafts the response while a person still reads and sends it. The agent handles the recall and the typing; the judgment on what actually gets sent stays with the owner.

I run a media production studio (weddings, corporate work, portraits) alongside DeployLabs. For most of its life, a booking inquiry arrived the way it arrives for most small businesses: an email from a contact form, sitting in an inbox, waiting for someone to remember it.

That works at two inquiries a month. It breaks quietly as volume grows. A Harvard Business School study that audited how 2,241 companies responded to submitted web leads found that firms making contact within an hour were nearly seven times more likely to qualify the lead than slower responders, and more than sixty times more likely than firms that waited a day or more (Oldroyd, McElheran & Elkington, Harvard Business Review, March 2011). That study measured B2B sales leads, not wedding inquiries, but the mechanism travels: a couple comparing studios is comparing response time as much as portfolios.

An intake pipeline like this used to require a developer and a support engineer on retainer. A gated page, a verification widget, a database with automations, and an agent that can read a record and draft a reply are now things one person can wire together in a weekend, and the response-time advantage that used to require a dispatcher is now available to a business of one.

In August I rebuilt the intake path, because it needed to hold up on a Saturday when I am shooting a wedding and not looking at my phone.

The old path

Someone filled in the contact form. I got an email. Later, sometimes much later, I read it, checked the calendar for the date, tried to recall whether they had mentioned a venue, and wrote a reply from memory.

Three costs came out of that, in order of size: replies arrived slowly at the exact stage of the funnel where speed decides the most; replies were generic, because reconstructing context from memory before every reply is tiring; and nothing was tracked, so there was no way to tell which channel a lead had come from.

What I built

What it is: a six-stage pipeline that takes a lead from form submission to a sent, personalized reply, with a person approving the send.

How it works

StageWhat handles it
VerificationCloudflare Turnstile, checked server-side, plus rate limiting
StorageA Notion database, one row per lead, tagged with source and status
NotificationA Notion automation fires when the row is created
ResponseAn agent reads the row and drafts a reply
SendA person reads it and sends it

The gated guide went in first (`61c6a97`). Instead of a bare contact form, there is a real pricing guide behind it, and the form is the toll. The reasoning: someone who trades an email address for pricing has already decided they are shopping, a different lead than someone who wants to browse (per Chris, the conversion effect itself is unconfirmed; no before/after comparison was run).

Every lead now lands in Notion as a structured record with its source attached, which changed how reviewing leads feels: checking the week means reading a table instead of scrolling an inbox.

Notification runs on the event rather than a clock. Notion's own database automations fire on a "page added" trigger, not on a timer. For a business receiving leads in the tens per month (per Chris, unconfirmed exact figure), a scheduled check would burn cycles waiting for something that rarely happens.

People expect the response stage to run without a person. An agent reads the lead row and drafts a reply with the date and venue already in it, then a person reads that draft and presses send. Someone should read anything a couple receives before their wedding, so the agent's job stops at removing the blank page.

💡

The agent's real contribution is recall: reconstructing who this person is and what they have already said, before a draft can start.

Pros: no new subscriptions, no scheduled polling cost, a structured record instead of an inbox archive, and a draft that starts from context instead of a blank page.

Cons: the send step still needs a person every time, the design assumes low-to-moderate volume, and none of it protects against the assumption that a visible security control is actually enforced. That assumption is the next part.

How to win: the order matters more than the tools. Capture behind something worth trading an email for, verify on the server, structure the record, notify on the event, draft with context, and leave a person on the send.

Not sure where AI fits in your operations?

Take the Free AI Readiness Scorecard

The part I got wrong

Nine minutes after the gated guide went live (`61c6a97` to `deb6684`), I checked what was actually reaching the endpoint. The Turnstile widget rendered correctly on the page. The API accepted submissions that arrived with no Turnstile token attached. Anything that hit the endpoint directly, skipping the page and the widget, went straight into the database. All three forms on the site had the same gap.

Cloudflare's own Turnstile documentation explains why: Turnstile issues a clearance token after a passed challenge on the client side, and that token has to be validated through the server-side Siteverify API before the submission is trusted. My server skipped that validation step.

Result

The fix was one change, reject any submission without a valid Turnstile token, checked server-side, applied across all three forms in a single commit (`deb6684`).

I had verified the widget by using the form like a person would. A bot posts straight to the endpoint, skipping the browser, the widget, and the check I thought was there.

What it actually cost

Cloudflare Turnstile carries no charge at any traffic volume on its standard plan: unlimited sitekeys, unlimited requests, no credit card required. Notion was already part of the business's stack before this build (per Chris), so nothing new was purchased to run it. The build itself was one working session, a follow-up commit for the security fix, and a third pass (`a74178f`) that propagated an unrelated price change across the site and the internal pricing canon at the same time. That third commit is its own small argument for keeping one source of truth for pricing.

The honest limit: this handles a business receiving leads in the tens per month (per Chris, unconfirmed exact figure), not thousands. It would need a real queue and a real CRM at meaningfully higher volume, and that has not been tested.

The same order, a different channel

In September the studio added two-way SMS as an inquiry channel. The build followed the same order rather than a new one. An inbound text hits a webhook verified with Ed25519 signatures (`edae58a`) instead of a Turnstile widget, and gets written to one Notion thread per phone number instead of one row per form submission (`c83264f`), with outbound replies appending to that same thread and to the lead's Inquiry Entries profile (`d745964`, `2949eec`).

That is the actual claim in this article. The six stages are not specific to one channel or one vendor. Swap the capture surface, swap the verification method, and the order still holds.

What transfers

The tools are interchangeable: Notion could be Airtable, Turnstile could be any verification layer, the agent could be any model with access to the lead record. The order is not. Capture behind something worth trading contact details for, verify on the server, structure the record, notify on the event, draft with context, and leave a person on the send.

If inquiries reach your business as unstructured email or text and get answered from memory, that sequence is the upgrade path. It took one working session for the form and a second for SMS, with no new subscriptions for either.

💡

Test your own intake form the same way. Send a POST straight to the endpoint with curl and no token attached. If the record still saves, nothing server-side is actually checking that token.

For a faster starting point than a full build, the AI Readiness Scorecard scores your own workflows in about ten minutes.

Frequently Asked Questions

Does the AI send the emails?
No. It drafts a reply using the lead's details and prior replies as reference, and a person reads every draft before it goes out. For a purchase this personal, someone should read anything the customer receives before it is sent.
What does a system like this cost to run?
Cloudflare Turnstile has no charge at any traffic volume on its standard plan (Cloudflare). Notion was already part of the business's stack before this build (per Chris). Cost enters at higher lead volume or if paid enrichment tools get added.
Why event-driven instead of a scheduled check?
A scheduled check burns cycles waiting for something that rarely happens and adds delay between a lead arriving and someone knowing about it. Notion's database automations fire when a new row is added, so the notification goes out the moment the lead lands.
Is a gated lead magnet worth the friction it adds?
Gating trades raw form-fill volume for leads who have already decided they are shopping, though that conversion effect has not been separately measured here (per Chris, unconfirmed). Whether the trade is worth it depends on whether the goal is volume or conversations worth having.