Insights · Getting forms right · 5 minutes
Stopping Spam Without CAPTCHAs
CAPTCHAs tax the humans and barely slow the professionals. The quiet alternative: a honeypot, a clock, a rate limit, and a content check that flags instead of blocking, all on the server where the visitor never sees any of it.
The toll booth faces the wrong way
A CAPTCHA is your form telling every visitor: we've had trouble with bots, so before we read your message, prove you're a person. The organization's problem has been made the visitor's chore. Some visitors pay the toll lightly, with one click. Some pay heavily, through three rounds of hydrants and crosswalks. And some can't pay at all: the visual puzzles assume sight, the audio alternatives are famously miserable, and time limits punish anyone slower on a keyboard. Those costs land hardest on exactly the people public institutions exist to serve.
What does the toll buy? Less than advertised. Solving services will pass a CAPTCHA for fractions of a cent, and modern bots increasingly pass them without help. Meanwhile the widget itself is usually a third-party script observing your visitors, on a page that may belong to a government agency or a member institution, which is a privacy and procurement conversation nobody scheduled. The puzzle taxes the humans, mildly inconveniences the professionals, and mostly performs security rather than providing it.
Spam is prolific because it's lazy
Form spam runs on volume economics. A bot that submits to a million forms cannot afford to study yours, so it behaves in recognizably lazy ways. It fills in every field it can find, including fields no human can see. It submits instantly, within a second or two of loading a page a person needs half a minute to read. It often skips the page entirely and posts straight to the endpoint. And it repeats itself from the same address at a pace no confused human could match.
That laziness is the design opening. You don't need to out-think spam in general. You need to quietly decline the automated 99 percent, which announces itself, and then make a calmer decision about the human-typed remainder.
Three checks the visitor never meets
The honeypot: one extra field, hidden from everyone. Sighted visitors don't see it, screen readers are told to skip it, it's removed from the tab order, and autofill is disabled on it. No human ever touches it. A bot working faithfully through the fields fills it in, and the submission convicts itself. The whole trick lives in the word everyone: hide the field with visual CSS alone and a screen reader will still announce it, and your spam trap is now catching blind visitors. Hidden means hidden from assistive technology too.
The clock: note when the form was served and how quickly the submission came back. A contact form completed two seconds after the page loaded was not completed by someone with a question. Keep the floor low, since autofill makes real people fast, and it stays invisible to humans while filtering machines. And rate limits: the same address submitting thirty times a minute is not thirty constituents. All three checks run on the server, cost the visitor nothing, ask nothing of anyone, and between them end the automated traffic almost entirely.
What's left is a judgment call
What survives the nets was typed by a person: the link-building offer, the guest-post pitch, the urgent business proposal. Telling those from a real inquiry is a content question, and content screening obeys two iron rules. First, flag, don't block: label the suspect and route it for review, but deliver everything, because a false positive here is a real person's message silently lost, and one lost lead costs more than a hundred read-and-deleted spams. Second, fail open: when the screening breaks, messages flow through unscreened. A spam filter that can lose mail has failed at a more important job than the one it was hired for.
One rule covers both layers: never announce a verdict. A form that tells a bot it was caught is providing free quality assurance to the bot's operator, who will adjust and return. The suspect submission gets the same thank-you screen as everyone else. The difference happens entirely on your side, in which pile it lands and with what label.
How the forms on this site do it
Every public form on this site (contact, booking, the newsletter, the talent pool) runs the deterministic stack exactly as described: the honeypot accepts a bot's submission with a straight face and discards it, and rate limits cap volume at the edge and again at the origin. What gets through is read by a person, which at our size is the honest answer. There is no CAPTCHA anywhere on the domain, and the running total of puzzles our visitors have been asked to solve is zero.
So the message has been accepted, filtered, and stored. Somebody still has to answer it. The series finishes with what happens after the submit button, where forms stop being an interface question and become an operations one.