splitforms.com
guide · captcha & spam

Stop Form Spam Bots — Honeypot + Server-Side Filter Strategy

Two layers stop most form spam without CAPTCHA: a honeypot field (catches 40-60%) and server-side filtering — time-trap, rate limits, content heuristics — for the rest. Working code below; no third-party JS, no user friction, no privacy concerns.

html
<!-- The whole anti-spam strategy, in one form -->
<form action="https://splitforms.com/api/submit" method="POST">
  <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />

  <!-- Real fields the user fills out -->
  <input name="name" required />
  <input name="email" type="email" required />
  <textarea name="message" required></textarea>

  <!-- Layer 1: Honeypot. Bots fill it, humans never see it.
       splitforms recognizes 'botcheck' and several other names. -->
  <input type="checkbox"
         name="botcheck"
         style="display:none"
         tabindex="-1"
         autocomplete="off"
         aria-hidden="true" />

  <!-- Layer 2: Time-trap. Submissions in < 3 seconds are flagged.
       (splitforms handles this server-side automatically.) -->

  <button type="submit">Send</button>
</form>

<!--
On the splitforms side:
  Layer 3: Content heuristics flag link-stuffed and boilerplate spam.
  Layer 4: Rate limiting per IP and per access key.
  Layer 5: Origin checks against your allowed domains.

Combined, this catches the vast majority of automated spam with zero
user friction and zero third-party JavaScript on your page.
-->

Most form spam comes from cheap automated bots that scrape the web for forms and submit garbage to all of them. The bots don't render JavaScript, don't read CSS, and don't follow CAPTCHA puzzles — they parse the HTML, fill every input, and POST. That's the spam profile to defend against, and the defense is cheaper than CAPTCHA.

Layer 1: a honeypot field. Add an `<input>` that's visually hidden via CSS but present in the HTML. Bots that fill every input will fill it; real users won't (they don't see it). splitforms recognizes several common honeypot field names (`botcheck`, `_gotcha`, `hp`, `honey`, `trap`, `do_not_fill`, `leave-blank`, `fax`, `website`, `url`) — any submission where one of these is non-empty gets flagged as spam.

Layer 2: server-side filtering on the backend. splitforms runs rule-based checks on every submission: a time-trap (a form completed faster than a human can type gets flagged), per-IP and per-access-key rate limits, origin checks against your allowed domains, and content heuristics that catch link-stuffed and boilerplate spam the honeypot misses.

Together, honeypot + server-side filtering catches the vast majority of automated spam. No third-party JavaScript, no Google or hCaptcha tracking, no user-facing friction, no accessibility tax. Reach for CAPTCHA only if you're seeing human-driven abuse that the filters miss — which is rare for a contact form. The spam-free contact form page ships this exact setup as a copy-paste snippet.

How to set this up

Step 01

Add a honeypot field

Hidden input that bots fill but humans don't see. splitforms recognizes it automatically.

Step 02

Use server-side spam filtering

splitforms ships it — time-trap, rate limits, content heuristics on every submission; spam routed to a separate folder.

Step 03

Configure rate limits

Per-IP and per-access-key. Sliding window with burst allowance. splitforms handles this server-side.

Step 04

(Only if needed) Add CAPTCHA

If the above isn't catching your specific spam, then add reCAPTCHA or hCaptcha. Honest, but rare.

Honeypot + time-trap + rate limits + content heuristics. No CAPTCHA.

Frequently asked questions

How do I stop email spam bots from filling out my contact form?

Two layers. (1) Honeypot — a hidden form field bots fill but humans don't see; backend recognizes non-empty submissions as spam. (2) Server-side filters — a time-trap, rate limits, and content heuristics check every submission; flagged submissions are routed to a separate folder. splitforms ships both on every plan including free.

Why don't I need CAPTCHA for most forms?

Most form spam is cheap automated bots that don't render JS or solve puzzles. They parse HTML, fill inputs, POST. A honeypot catches them (bots fill every input; humans skip hidden ones). The time-trap and content heuristics catch the smarter ones. Combined, the vast majority of automated spam is blocked with zero user friction.

What's a honeypot field?

A form input that's visually hidden via CSS (display:none, or position:absolute off-screen). Bots fill it because they parse HTML and fill every input. Real users never see it. Submissions with a non-empty honeypot get classified as spam server-side.

How does splitforms detect spam?

Three layers. (1) Honeypot recognition — common honeypot field names are flagged if non-empty. (2) Time-trap and content heuristics — submissions completed faster than a human can type, or stuffed with links and boilerplate, get flagged. (3) Rate limits and origin checks. Combined they catch the vast majority of automated spam with zero user friction.

When should I add CAPTCHA?

Only when honeypot + server-side filtering isn't catching your specific spam pattern. Usually that means human-driven abuse, not automated spam. CAPTCHA hurts conversion, breaks accessibility, and adds third-party JS — only worth it when the simpler layers genuinely fail.

Related guides

Ship the form, not the backend.

Free for 500 submissions/month. Owner email delivery, spam filtering, and a real dashboard are included on Free. Starter adds signed webhooks. No credit card.

Get a free access key →