Security

Spam protection

Three layers of spam defense — honeypot, Turnstile CAPTCHA, and rate limiting.

Vlozi Forms protects every form with three layers of spam defense. They run in order, from cheapest to most expensive:

Honeypot check  →  Rate limit  →  Turnstile (if enabled)

Layer 1 — Honeypot field

A hidden field that humans never fill in, but bots always do. It's always active — no configuration needed.

How it works

Every form has a honeypotField (default name: botcheck). The field is included in your HTML but hidden from human visitors:

<input type="checkbox" name="botcheck" style="display:none" tabindex="-1" autocomplete="off" />

If the field is filled in during submission, the service stores the submission as status=spam and returns 200 { success: true } — silently. Bots never learn they were caught.

Changing the honeypot field name

You can customise the honeypot field name per form (dashboard → Settings → Spam protection → Honeypot field name). Use this if your own form already has a botcheck field for legitimate purposes.

WARNING

Do not set the honeypot field name to the same name as one of your real fields. Every submission with a filled-in version of that field would be silently marked as spam.


Layer 2 — IP-based rate limiting

Every form automatically rate-limits submissions: 20 requests per 60 seconds per IP address. This cap applies even if the honeypot or CAPTCHA is not triggered.

If the limit is exceeded, the server returns 429 Too many requests. This is the correct behavior for high-volume bot attacks.

The rate limit is per-form-per-IP, so one user hitting your contact form quickly does not affect another user submitting a different form.


Layer 3 — Cloudflare Turnstile CAPTCHA

Turnstile is an opt-in CAPTCHA that is invisible to most users (Cloudflare classifies traffic automatically) and only shows a challenge to suspicious requests.

Setup

You need two keys from your Cloudflare dashboard:

Key Used by Where to configure
Site key (public) The browser widget Form settings → Turnstile site key
Secret key (private) Server-side verification Vlozi platform settings (shared across all forms)

Once both are set, enable CAPTCHA per form: dashboard → Forms → your form → Settings → enable CAPTCHA.

How it works

  1. When embed.js renders your form, it detects captchaRequired=true and loads the Turnstile widget from Cloudflare
  2. The visitor solves the challenge (usually invisible — Cloudflare handles it)
  3. The widget injects a cf-turnstile-response token into the submission
  4. Vlozi verifies the token with Cloudflare's siteverify API before accepting the submission
  5. Invalid or missing tokens return 400 Captcha verification failed — the submission is rejected and stored as spam

IMPORTANT

CAPTCHA requires both the site key (configured in the form) and the secret key (configured at the platform level). If only one is set, CAPTCHA protection will not work correctly. Check the dashboard Settings if submissions are failing with a 400 error and you have CAPTCHA enabled.

Plain HTML forms and CAPTCHA

If you use a plain HTML form (no embed.js), you must add the Turnstile widget yourself:

<form action="https://api.vlozi.app/forms/f/YOUR_FORM_ID" method="POST">
  <!-- your fields -->
 
  <!-- Load Turnstile -->
  <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
  <div class="cf-turnstile" data-sitekey="YOUR_SITE_KEY"></div>
 
  <button type="submit">Send</button>
</form>

Turnstile injects cf-turnstile-response into the form submission automatically.


Spam submissions in the dashboard

All spam submissions — honeypot trips and CAPTCHA failures — are stored in the database with status=spam and a spamReason (honeypot or captcha). They are never billed (credits are only charged on legitimate submissions).

View them in the dashboard: Forms → your form → Submissions → filter by Spam.


Defense summary

Defense When active Blocks
Honeypot field Always Simple bots that auto-fill all fields
Rate limiting Always High-volume submission floods
Turnstile CAPTCHA When enabled Sophisticated bots that avoid honeypots
allowed_origins CORS When configured Cross-origin requests from unlisted domains
Forms · SecurityEdit on GitHub