Spam
protection.
Combine a website check, a hidden honeypot, origin restrictions and rate limits. Keep a place to review messages that may have been filtered by mistake.
1. Add a Turnstile widget
- In Cloudflare Turnstile, create a Managed widget for your website. Keep its secret private.
- In your Form Koi form settings, choose Connect Turnstile. Enter the public site key, matching secret and exact website hostnames. Include
www.example.comandexample.comseparately if you use both. - Save the widget with enforcement disabled while you install it. Copy the updated HTML or React example from the connection guide onto your website.
- Confirm the widget renders, enable protection in form settings, then submit from the real website. Enabling immediately requires a valid check on every new public message.
- Return to the form and check its protection status. A stored public submission that passes verification is the installation evidence; saving keys or running the receiver test is not.
Form Koi uses customer-owned widgets. Your site key is public; your secret is encrypted in the backend and is not returned in form reads. You can use Turnstile without moving your website or DNS to Cloudflare. Check Cloudflare’s current widget limits for your account.
2. Verify on the server
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js"
async defer></script>
<!-- Inside your existing form: -->
<div class="cf-turnstile"
data-sitekey="YOUR_PUBLIC_SITE_KEY"
data-action="formkoi_submit"
data-cdata="YOUR_FORM_UUID"
data-size="flexible"></div>The widget adds cf-turnstile-response to the form. Form Koi checks the proof with Cloudflare and requires the exact configured hostname, action formkoi_submit and your form UUID as cData. The UUID is different from the public submission key. An Origin header, when present, must also match the verified hostname.
For JSON, include the widget response as cf-turnstile-response. Tokens are single-use and expire after five minutes. Reset the widget after a request, clear expired verification and keep the visitor’s fields on failure. The generated React example handles these states. Cloudflare documents the token lifecycle.
Missing proof returns 422 verification_required. Rejected or mismatched proof returns 422 verification_failed. Provider or credential problems return 503 verification_unavailable. These failures do not store a new submission or consume its allowance. Sending a token to an unconfigured form does not enable protection.
Public test keys are for local development and do not verify a real installation. Staging and production configuration require real keys. Form Koi’s own sign-in widget is separate from your website widget.
3. Restrict origins and hostnames
Allowed origins are exact HTTPS origins, such as https://www.example.com. Scheme, hostname and port matter; do not include a path. A non-empty allowlist rejects both a missing Origin and a nonmatching one.
Allowed origins and Turnstile hostnames are independent settings. Update both when moving the form to another host, and update the Cloudflare widget’s own hostname list. For preview websites, register the exact hosts you intend to test.
Origin restrictions help control browser submissions. They are not authentication: a non-browser caller can supply an Origin header. Keep the other spam controls enabled and treat all incoming content as visitor input.
4. Review the spam folder
Leave your configured honeypot hidden and empty. A filled honeypot or a message with more than five HTTP(S) links goes to Spam without an owner notification. The visitor receives the same acknowledgement as an ordinary accepted message.
Review Spam and restore false positives deliberately. Restoring a previously uncounted message charges the allowance for its original month and queues its owner notifications. Deleting a message does not refund counters. Spam acceptance has a separate capacity, so storage cannot grow without a limit.
Rate limits also apply to submissions. A transient limiter response includes Retry-After; other quota errors explain the relevant capacity. These layers reduce abuse but cannot promise a spam-free inbox.