Why I Built SpamFlip
2 min read
Why I Built SpamFlip
Every contact form I've ever shipped has gotten spammed.
Not sometimes. Every one. Usually within a few days of launch. Bots are faster than users, and they don't care that your landing page has forty legitimate customers who filled it out the normal way.
The solutions that exist are mostly bad. CAPTCHA adds friction for real users. Full services are priced for enterprise and come with their own SDKs that phone home. Rolling your own honeypot works for about a week until the bots learn to ignore it. reCAPTCHA v3 assigns invisible scores and sometimes decides your most loyal customers are suspicious.
SpamFlip is a one-liner. Add one script tag to your form page. That's it.
The script instruments the form, watches for signals—timing, mouse movement, honeypot presence, IP reputation—scores the submission, and either forwards it to your real endpoint or quietly quarantines it. If the proxy fails for any reason, the form falls back to its original action. It never breaks.
The design principle I wouldn't compromise on: the form has to keep working no matter what. If my script has a bug, if the proxy is down, if the network is slow—the user submits their data and it gets through. SpamFlip is protection, not a dependency.
I also made it honest about scope. It's not a tarpit. It's not going to auto-report attackers anywhere. It looks at a submission, makes a call, and either forwards it or doesn't. Clear, contained, replaceable.
The hardest part of building it was evasion resistance. If you publish exactly which signals you look at and what thresholds trigger a block, you've given bots a checklist. So the response envelope is uniform (you can't tell from the response whether you were blocked or passed), per-site field names are derived from a secret so learning one site's defenses doesn't transfer to another, and the client script ships minified with comments stripped.
It's a small tool that solves a problem I got tired of solving manually every time I launched something.