Fillo combines renderer signals and server limits to reject simple automated submissions without putting a visible challenge on every form.
What Fillo applies
The default React and DOM renderers include an off-screen honeypot and report elapsed fill time. The public response endpoint treats a filled honeypot or a submission under 400 milliseconds as automated and returns a plausible success without storing the response.
Public write routes also apply per-IP, per-form, and per-workspace rate limits. Schema validation, file binding, response limits, and submission trust add separate boundaries around what a request can store or deliver.
These layers come from the renderer and the server. There's no per-form dashboard toggle for them.
In a headless form
FilloProvider and the framework-neutral controller use the same engine, but a fully custom surface has to go through the controller's submission path instead of posting arbitrary JSON directly. Raw API clients don't produce the built-in renderer's honeypot and timing signals, though the endpoint still validates and rate-limits them.
<FilloProvider form={form} client={client}>
<YourAccessibleLayout />
</FilloProvider>Require a human check
For forms that need more than heuristics, turn on Require a human check (Turnstile) in the form's Respondents settings — or set settings.trust.challenge: "turnstile" in a code-defined schema. The SDK renders a Cloudflare Turnstile check before the form can submit, and Fillo verifies the token on the server: a submission without a valid token is rejected, no matter what the client rendered. Fillo hosts the keys, so there's nothing to configure, and a form with the check off loads no third-party script.
The human check is independent of submission trust — a form can require both.
What's not included
Fillo doesn't expose reCAPTCHA, proof-of-work, or an allowlist. And the passive heuristics above aren't proof that a respondent is human — only the Turnstile check makes that claim.
For a signed-in product flow, pass a server-verified respondent and enable submission trust when unverified traffic should wait for review. For a public high-risk flow, put abuse controls in the host application or a server-side layer in front of the form as well.
Responding to abuse
- Check whether the traffic uses the hosted form, default SDK, headless SDK, or raw endpoint.
- Review source, timing, repeated values, and respondent context in accepted responses.
- Add a response limit only when its identity model fits the form.
- Require host-app sign-in for an access-controlled workflow.
- Delete unwanted accepted responses and rotate any exposed management credential.
Related
- Submission trust: Hold unverified submissions away from every consumer.
- Limit responses: Reduce repeats by browser, contact field, or account.
- Security and boundaries: Separate public collection from management authority.