Spam protection

Most forms don't need to make a visitor prove they're human. Form Plume layers a few lightweight, invisible checks that catch almost all bot traffic on their own.

Add a honeypot and a time-trap token and you're covered for the vast majority of forms. Everything else here is either automatic or for the rare form that gets targeted by an actual person.

If you want an extra layer, or your form already uses one, add CAPTCHA. Form Plume supports Cloudflare Turnstile, hCaptcha, and Google reCAPTCHA.

Honeypot

Add a hidden input named _gotcha to your form:

<input
  type="text"
  name="_gotcha"
  tabindex="-1"
  autocomplete="off"
  style="position:absolute; left:-9999px"
>

Real visitors never see or fill this in, it's off-screen and skipped in tab order. Bots that blindly fill every input on the page usually fill it in anyway.

If _gotcha arrives non-empty, Form Plume responds exactly as if the submission succeeded, so the bot gets no signal that anything went wrong. The submission itself is dropped before it reaches your inbox or triggers a webhook.

Time-trap token

Bots that skip the honeypot trick still tend to submit fast, often under a second after the page loads. A time-trap token catches that.

Fetch a token right before you render the form:

const res = await fetch("https://api.formplume.com/f/{public_slug}/time-trap");
const { field, token } = await res.json();
// field === "_fp_ts"

Then put it in a hidden field named by the response:

<input type="hidden" name="_fp_ts" value="TOKEN_GOES_HERE">

The token is signed (HMAC-SHA256) and encodes when it was issued, so the server can check timing without keeping any session state. A submission comes back validation_failed if the token is:

  • Used less than 3 seconds after it was issued, too fast for a human to have actually read the form
  • Older than an hour (see expires_in_seconds in the response)
  • Reused, each token is good for one submission only

Rotating the signing secret on your end doesn't break anything mid-flight. Tokens issued before the rotation keep working for a grace period.

Rate limiting

Rate limiting is on by default, no setup needed:

WindowLimit
Strict1 submission every 30 seconds
Burst20 submissions every 10 minutes

Limits are keyed per form, per submitter (IP address plus user agent), so one visitor hammering refresh can't take a form down for everyone else.

Going over either limit returns 429 Too Many Requests with a Retry-After header telling you how long to wait. Both windows are configurable per form if the defaults don't fit your traffic.

Email hygiene

Configure this per form under Settings → Spam. Email hygiene checks that the submitter's email field looks real: valid syntax, a domain you haven't blocked, and optionally a working mail server (MX record) and no disposable addresses.

Failed checks can either flag the submission (it still arrives, marked for the spam scorer) or block it outright with email_rejected. Flagging is available on every plan; blocking, MX checks, and disposable-address blocking are Pro features.

Blocked keywords

Blocked keywords let you add words or phrases under Settings → Spam → Blocked keywords, one per line. Any submission containing one of them anywhere in its content goes straight to the spam folder, no matter what the spam score says. Matching is case-insensitive and works on multi-word phrases like backlink packages.

Quarantined submissions land in the spam folder rather than being deleted, so a false positive is always recoverable, and marking it "not spam" also trains your form's filter.

CAPTCHA, if you need it

For the small number of forms that attract targeted, human-operated spam rather than simple bots, you can add CAPTCHA verification as an extra layer. Create keys with the provider of your choice, then your page renders the widget with the site key and Form Plume verifies the submitted token with the encrypted secret key before accepting the submission.

The secret key is private. Paste it into Form Plume settings, but never put it in your HTML, JavaScript bundle, or public repository.

ProviderBest forToken fieldPlan
hCaptchaFree, challenge-based CAPTCHA with broad supporth-captcha-responseFree
Cloudflare TurnstilePrivacy-friendly, low-friction checkscf-turnstile-responsePro
Google reCAPTCHA v2Checkbox or invisible challenge flowsg-recaptcha-responsePro
Google reCAPTCHA v3Invisible, score-based risk checksg-recaptcha-responsePro

Each provider has its own setup guide with the full widget snippet, token field, and verification details:

What to actually turn on

Honeypot and the time-trap token together stop the overwhelming majority of automated spam for the cost of two extra fields and zero user-facing friction. Rate limiting and email hygiene run regardless of what you choose.

Reach for CAPTCHA only if you're still seeing spam after that, it's usually a sign of a human spammer, not a script. Blocked keywords are a quick lever too if the spam always mentions the same things.

On this page