FCaptcha has served the same siteverify API as Turnstile, reCAPTCHA and hCaptcha for a while, so a backend could switch by changing a URL. The browser side was the catch. Every app that supports those providers loads the provider’s script and calls its JavaScript (grecaptcha.render, turnstile.getResponse) and FCaptcha’s widget didn’t answer to any of it.

v1.45.0 closes that gap.

The widget on each provider’s script path

The FCaptcha server now also serves its widget at:

ProviderScript URLSiteverify URLForm field
Turnstile/turnstile/v0/api.js/turnstile/v0/siteverifycf-turnstile-response
hCaptcha/1/api.js/siteverifyh-captcha-response and g-recaptcha-response
reCAPTCHA/recaptcha/api.js/recaptcha/api/siteverifyg-recaptcha-response

Loaded from one of those paths, the widget provides that provider’s JavaScript API (render, getResponse, reset, remove, execute, ready), renders into the provider’s usual container, and fills the provider’s form field. Loaded as /fcaptcha.js it installs nothing, and it never replaces a provider script that’s already on the page.

So an app that lets an admin change both URLs can point them at an FCaptcha server and use it without a code change.

Gitea

We tested this end to end with Gitea. In app.ini:

[service]
ENABLE_CAPTCHA    = true
CAPTCHA_TYPE      = recaptcha
RECAPTCHA_URL     = https://your-fcaptcha-server.com/recaptcha/
RECAPTCHA_SITEKEY = your-site-key
RECAPTCHA_SECRET  = your FCaptcha verify secret

Gitea’s sign-up page renders the FCaptcha checkbox, posts the token as g-recaptcha-response, and its backend verifies it against FCaptcha.

One thing to check: score direction

Every siteverify path returns FCaptcha’s own score, where lower means more human. Apps that only check success, like Gitea, need nothing else. An app that thresholds a reCAPTCHA v3 score, where higher means more human, would reject real visitors.

Also in v1.45: no callback needed

A checkbox widget inside a <form> now adds a hidden fcaptcha_token input and fills it when the visitor passes, so the shortest integration is two lines:

<div data-fcaptcha="your-site-key" data-endpoint="https://your-fcaptcha-server.com"></div>
<script src="https://your-fcaptcha-server.com/fcaptcha.js"></script>

Other integrations

The Statamic Captcha addon has supported FCaptcha since its v1.18.0. The full list lives in the FCaptcha README.

Try the demo, or see how FCaptcha compares with Turnstile, reCAPTCHA and hCaptcha.

Frequently Asked Questions

How do I use FCaptcha with Gitea? +

Set Gitea's CAPTCHA_TYPE to recaptcha and RECAPTCHA_URL to https://your-fcaptcha-server/recaptcha/, with your FCaptcha site key and verify secret. Gitea loads the widget from FCaptcha's /recaptcha/api.js and verifies tokens at /recaptcha/api/siteverify. No Gitea change is needed.

Which apps can use FCaptcha this way? +

Any app that lets you change both the provider's script URL and its siteverify URL. FCaptcha serves its widget at /turnstile/v0/api.js, /1/api.js and /recaptcha/api.js, where it provides that provider's JavaScript API and form field.

Do I still need a callback to get the token into my form? +

No. From v1.45.0 a checkbox widget inside a form adds a hidden fcaptcha_token input and fills it when the visitor passes.

Want to see WebDecoy in action?

Get a personalized demo from our team.

Request Demo