The most effective way to stop contact form spam is to layer invisible checks — a honeypot field, a time-to-submit check, content filtering and rate limiting — and add a captcha only if spam still gets through. This blocks the vast majority of bots without making real visitors solve puzzles. FormSubmit applies these layers on every plan; here's how to use each one.
Layer 1: the honeypot
Bots tend to fill every field they find. A honeypot is an input that's hidden from people, so any value in it means a bot:
<input type="text" name="_gotcha" style="display:none" tabindex="-1" autocomplete="off">FormSubmit silently discards honeypot submissions and returns a normal success response, so the bot doesn't learn it was caught. tabindex="-1" keeps keyboard users out; autocomplete="off" stops browsers autofilling it.
Layer 2: time-to-submit
Humans take several seconds to fill a form; bots take milliseconds. Record when the form rendered:
<input type="hidden" name="_ts" id="fs-ts">
<script>document.getElementById("fs-ts").value = Date.now();</script>Submissions faster than your threshold (default 2 seconds, configurable) are scored as spam. Every JavaScript export from the form generator includes this.
Layer 3: content filtering
FormSubmit scores the content itself: number of links, HTML/BBCode links, known spam phrases, URLs in name fields and all-caps text. Choose low, medium or high sensitivity per form. Add your own blocked keywords for recurring pitches ("SEO services", "guest post", a competitor's name).
Suspicious submissions go to a Spam folder instead of your inbox; they don't trigger emails or integrations and don't count toward your quota. Review it occasionally and mark false positives as not spam.
Layer 4: rate limits and duplicates
Each IP can submit to a form at most 20 times a minute, and identical submissions within 10 minutes are flagged. Nothing to configure.
Layer 5: domain allowlist
Add your domain to the form's allowlist so browser-based submissions from other sites are rejected. It won't stop a determined script (headers can be forged) but it cuts off a lot of drive-by abuse.
Layer 6: captcha (only if needed)
If a form is specifically targeted, add a captcha. FormSubmit supports Cloudflare Turnstile, reCAPTCHA v2/v3 and hCaptcha with your own keys. Prefer invisible options — Turnstile or reCAPTCHA v3 — to protect conversion rates.
What not to do
- Don't publish your email address in a
mailto:link or form action — scrapers harvest it. With FormSubmit your address never appears in your HTML. - Don't rely on JavaScript-only validation — bots post directly to endpoints.
- Don't put a captcha on every form by default — start invisible, escalate only when needed.