Skip to main content
Any form with a public URL gets found. Scrapers crawl for <form> tags and POST endpoints, and once yours is on a list it stays there — most spam arriving at a small site’s contact form is automated, indiscriminate, and has nothing to do with your business. The instinct is to make submitting harder. That is the wrong trade: every extra step costs you real enquiries too, and the bots are scripts that do not mind a puzzle. What works is filtering server-side, after the submission arrives — so the visitor experience never changes and the bot never learns why it failed. Crunchforms runs three checks on every submission, on every plan including Free. None of them is gated behind a paid tier.

Pick your layer

Honeypot field

A hidden field a human never sees and a bot fills in anyway. One line of markup, no third-party script, nothing for visitors to do. Start here.

Cloudflare Turnstile

Invisible bot detection. Most visitors are never challenged; Crunchforms validates the token server-side before the submission is stored.

reCAPTCHA v3

Score-based, no visitor interaction. You set the threshold per form and Crunchforms enforces it.

Which one should you use?

Honeypot alone. It takes one hidden input and one setting, loads no third-party script, and stops the majority of drive-by spam — which is the bulk of what a small site receives. Nothing to configure with an external provider, and no privacy notice implications.
Add Turnstile on top of the honeypot. The two are independent checks and both run, so a bot that has learned to skip your hidden field still has a token to produce. Turnstile is invisible to most visitors, so this costs you almost nothing in conversion.
reCAPTCHA v3. It returns a score from 0.0 to 1.0 and you choose the cutoff per form, so you can start permissive and tighten it while watching what gets through. Turnstile is a pass/fail verdict by comparison — simpler, but less adjustable.
Yes. All three run on every submission and each can reject independently, so enabling two or three is genuinely additive rather than redundant.

What happens to a rejected submission

The checks run before the submission is stored, so a rejected one never appears in your dashboard and never triggers a notification email. It counts against a separate blocked- submission tally rather than your monthly quota, so spam cannot burn through your plan limit. What the sender sees depends on the form’s response type:
The visitor goes to the form’s failure URL, or gets a bare 400 if none is set. No detail about which check rejected them is exposed.
The response body carries a generic status of "Invalid Submission" plus an errors array naming the specific check that fired — for example "turnstile validation failed". That detail is what makes a failing integration debuggable, so keep it in mind if you surface raw error text in your own UI: show your own message to visitors rather than passing the array straight through.
If you enable Turnstile or reCAPTCHA on a form, submissions without a valid token are rejected — including your own tests from a copy of the form that has not had the widget added. Use Send Test Submission in the dashboard to exercise the pipeline instead.

How to see what was blocked

The bot never learns why it failed. You do. Open a form and look above the Inbox / Archived tabs — the same panel also sits inside Spam protection on the form’s settings page. It shows:
  • how many submissions were blocked this month, and the running total since the form was created
  • a breakdown by reason, as a bar and a legend
  • when the last block arrived
A form that has never blocked anything says so, rather than showing you an empty chart.

What the reasons mean

One submission can trip two checks at once — a bot that fills the honeypot and sends no captcha token counts once in the total and once against each reason, so the reasons add up to slightly more than the total on a form catching a lot of traffic.
This is a tally, not an inbox. Crunchforms does not keep rejected submissions where you can read them: a blocked submission is spam by definition, and storing the payloads and IP addresses of everyone your form turned away is not something we hand back to you. You get the counts and the reasons.

When a captcha starts rejecting everyone

A mistyped secret key does not announce itself. The form keeps returning a failure to every visitor, real ones included, and from the outside it just looks like nobody is getting in touch. That is the case this panel exists for. If your captcha is blocking almost everything, blocks are still arriving, and nothing has been accepted for a week, the panel says so and points at the setting to check:
Nothing is getting through to this form — 40 of the 42 submissions blocked this month were rejected by reCAPTCHA (95%), and nothing has been accepted since Jul 21. If you were expecting submissions, check the secret key and threshold in Spam protection — a wrong key rejects real visitors too.
It reports what it can see and leaves the conclusion to you, deliberately. A quiet month on a low-traffic form with a working captcha produces the same four readings as a broken key, and nothing in the numbers tells them apart — only you know whether you were expecting to hear from anyone. If you were not, the panel is describing a normal month. A healthy form looks different: the honeypot doing most of the work, a captcha catching the rest, and submissions still arriving. That mix is the protection working — it is the only evidence you get that switching it on achieved anything.

Form configuration

Response types, notification emails, and the per-form settings these checks live in

What is a form backend?

Why a static site needs somewhere to send form submissions in the first place

Need Help?

Get Support

Send us a note