Check out the Build Series. Part 1 | Part 2 | Part 3 | Part 4 | Part 5
Every creator on DraftKit gets a public booking page at draftkit.app/[their-username]. No login required. Anyone can browse to it, fill out a collaboration request form, and the submission lands directly in that creator’s queue.
My own booking page is a good example. Take a look at it: https://draftkit.app/elenacalvillo
That is the product. The problem is that bots do not write newsletters.
Three weeks after launching the public booking pages, a creator messaged me asking why her Collabs tab had 2 pending requests from names she didn’t recognize, with newsletter URLs that returned 404s. I pulled the collab_requests rows and found the pattern immediately: six from addresses ending in .ru, four with placeholder text in the message field, one that used test123 as the Substack URL. None of them had triggered the SMART Match AI step, which was the tell. The bot had skipped the JavaScript-heavy portion of the form.
That same week I checked two other active booking pages for testing. One had 2 suspicious submissions, one had 1. I had shipped a public form with zero bot protection, and it took a creator complaint to find out.
If you have a public-facing form in your product, and especially if you built it with Lovable or a similar AI builder, you have likely shipped the same gap. AI builders scaffold the happy path. They do not add bot protection because they do not know your form will be indexed by every spam crawler running in 2026.
If you want someone to review where your public endpoints are exposed before a user notices, reach out at hello@elenacalvillo.com. Finding open insert paths on public tables is the first thing I check in a product audit.
Bots Now Generate More HTML Traffic Than Humans. Your Form Is in That Traffic.
Cloudflare’s Radar data from 2025 showed bots generating the majority of HTML web traffic across their network, and the share has grown every quarter since. That measurement covers HTML requests: pages, forms, APIs. For publicly indexed booking forms that accept a name, an email, and a message with no authentication gate, the exposure is direct.
The SaaS products I audit are handling this in exactly two ways. Either they added bot protection before launch (rare), or they added it after the first creator or customer complaint (almost always). The cleanup cost is the same either way, but the trust damage only happens in the second scenario.
✅ Adding Turnstile before launch takes 30 minutes and costs nothing below one million monthly requests.
✅ Adding it after a creator goes public about spam in their queue takes longer and costs more than the dev time.
✅ The verification step that actually matters is server-side, not client-side. Most first implementations miss this.
Every AI-Built Product Has This Window
The pattern is predictable. The form is scaffolded by an AI builder, which produces a React component that submits correctly, validates the email format, and inserts a row. Bot protection is not part of the happy path. The form goes live. It gets indexed. The spam arrives.
The window is not a failure of the AI builder. The threat model belongs to the product builder, and it was mine to add before launch.
Why This Layer Gets Skipped
When you build with Lovable, the AI generates the booking form, the submission handler, and the database insert. What it does not generate is the server-side step that confirms the submission came from a real browser rather than a script. Knowing that a form is public is not the same as modeling the downstream risk of that exposure.
The result is a functional product that passes every test you ran during development and then receives its first bot submission 72 hours after the domain goes live.
The Approach I Follow
✅ Add Cloudflare Turnstile to every public form before launch. Turnstile is free up to one million requests monthly, invisible to real users, and requires only a script tag and a hidden response field in the form. It is the lowest-friction bot protection available in a Lovable-built product without a third-party subscription.
✅ Verify the token server-side, in the edge function, before every database insert. A client-side Turnstile check is bypassed by any bot that generates a valid-looking token string. The verification must happen in your Supabase edge function against Cloudflare’s siteverify endpoint. This is the step most first implementations skip, and it is the only step that actually confirms the token is real.
✅ Add a second validation layer at the database level. Triggers run regardless of how a row arrives, including direct API calls that bypass your edge function entirely. DraftKit’s validate_requester_substack_url() trigger rejects any submission with a non-publication URL. It is the last line of defense before any spam reaches the host’s queue.
✅ Log every failed bot check. When a Turnstile verification fails, write a row to your analytics_events table with the IP, timestamp, and which booking page was targeted. You want this data when a bot campaign targets a specific creator.
✅ Audit every public endpoint before launch. List every route that does not require authentication. For each one, ask whether it accepts user input that lands in your database. If yes, Turnstile goes on it before the domain is live.
If you want me to walk through your public endpoint map before the next feature ships, reach out at hello@elenacalvillo.com.



