MVPKit
← All guides

Customer contact · How-to

How to stop contact form spam without a CAPTCHA

Put a form on the internet and the bots arrive within days. A CAPTCHA blocks them, but it also annoys every real person who wants to ask you something. For a small product, a few quiet checks usually do the job.

Where the spam comes from

Most form spam is sent by simple scripts. They find a form, fill in every field and submit it, thousands of times, on thousands of sites. They're fast and not very clever. That's why the quiet checks below work.

Some spam is typed by real people paid to post links or sell “SEO services.” No check stops all of it. The goal is to stop the automatic flood and make the rest rare.

1. A honeypot field

Add a field that people never see, hidden with CSS. Real visitors leave it empty. Bots fill in everything, so they fill it too. If it has a value, drop the message.

<div class="hp" aria-hidden="true">
  <label>Leave this empty
    <input name="website" tabindex="-1" autocomplete="off">
  </label>
</div>

.hp { position: absolute; left: -9999px; }

The small details matter:

2. A time check

A person needs at least a few seconds to type an email and a message. A bot sends instantly. Note when the form was shown, and drop anything sent in less than about three seconds.

Do the check on the server, not only in the browser. A bot that posts straight to your endpoint skips the browser part.

3. Rate limits

Limit how many messages one IP address can send in a short time, say five in ten minutes. A real customer never hits that. A script does.

4. Pretend it worked

When you drop a message, still show “Thanks, your message was sent.” An error teaches the bot's author what to change. If it looks like it worked, they move on.

Just make sure your checks don't block real people. Log what you drop, at least at the start, and look at the log now and then.

5. Don't print your email address

A form keeps your address off the page. If you also show it as plain text, bots collect it and the spam simply arrives by email instead.

When to add a CAPTCHA anyway

If spam still gets through after all this, add a challenge. Prefer one that stays invisible and only shows a puzzle when something looks wrong, like Cloudflare Turnstile. Visible puzzles cost you real messages, especially on phones.

Quick rule: Start with a honeypot, a time check and a rate limit. Add a CAPTCHA only if real spam still gets through.

MVPKit's contact, waitlist and ideas forms come with these checks built in: a honeypot field, a minimum time to fill in the form, per-IP limits, and a quiet “sent” reply for blocked bots. There's nothing to set up.

Want a form with spam checks already built in? Try MVPKit.