Google reCAPTCHA
Require a reCAPTCHA v2 checkbox or a v3 score on your form so automated submissions are rejected before they are stored.
Google reCAPTCHA checks each visitor with Google's risk analysis. Nisuform verifies the v2 "I'm not a robot" checkbox and score-based v3 with your own keys, on every plan. Google's free tier covers 10,000 checks a month across your whole Google Cloud organization, and it asks you to turn on billing above that.
If you don't have reCAPTCHA keys yet, Cloudflare Turnstile is quicker to set up and needs no Google Cloud project.
Pick a key type
| Key type | What visitors see | Works with |
|---|---|---|
| Checkbox (v2) | An "I'm not a robot" checkbox, and sometimes an image puzzle | The styled embed, the generated code and plain HTML |
| Score (v3) | Nothing. Google scores each visit from 0.0 to 1.0 | Your own JavaScript |
Nisuform rejects v3 tokens that score below 0.5, Google's suggested starting threshold.
Set it up
Create a reCAPTCHA key
In the Google Cloud console, open Fraud Defense, then the Keys tab, and create a website key. Choose the checkbox type for the styled embed, or the score type for your own code, and add every domain your form is on. The key's Key ID is your site key.
To get the secret key, open the key's Integration tab and click Use legacy key, or Integrate with a third-party service or plugin. Keys you created in the older reCAPTCHA admin console work the same way.
Add the keys to your form
Open the form's Settings, Spam protection. Turn on Require a CAPTCHA, choose Google reCAPTCHA, paste the Site key and the Secret key, and save.
The secret key is write only. Once saved, it is never shown again. Switching to Turnstile later clears both keys.
Add the checkbox to your form
If you use the styled embed, copy it again from Get code in the builder or from the Setup tab. It includes the checkbox once reCAPTCHA is on.
For your own markup, load the reCAPTCHA script and place the checkbox inside the form:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<form action="https://api.nisuform.com/s/YOUR_FORM_KEY" method="POST">
<input type="email" name="email" required>
<textarea name="message" required></textarea>
<div class="g-recaptcha" data-sitekey="YOUR_RECAPTCHA_SITE_KEY"></div>
<button type="submit">Send</button>
</form>The checkbox adds a hidden g-recaptcha-response field to the form. Nisuform checks it with Google, and never stores it.
Add the checkbox to your site before you turn reCAPTCHA on, or right after. While it's on, every submission without a valid token is rejected.
reCAPTCHA v3
A v3 key has no checkbox. Load the script with your site key, ask Google for a token when the visitor submits, and send it as g-recaptcha-response:
<script src="https://www.google.com/recaptcha/api.js?render=YOUR_RECAPTCHA_SITE_KEY"></script>
<form id="contact" action="https://api.nisuform.com/s/YOUR_FORM_KEY" method="POST">
<input type="email" name="email" required>
<textarea name="message" required></textarea>
<input type="hidden" name="g-recaptcha-response">
<button type="submit">Send</button>
</form>
<script>
const form = document.getElementById('contact')
form.addEventListener('submit', (event) => {
event.preventDefault()
grecaptcha.ready(async () => {
form.elements['g-recaptcha-response'].value = await grecaptcha.execute('YOUR_RECAPTCHA_SITE_KEY', { action: 'submit' })
form.submit()
})
})
</script>Tokens expire after two minutes, so ask for one on submit rather than when the page loads. A visitor who scores below 0.5 gets captcha_failed, and v3 has no puzzle to fall back on. If real visitors are getting blocked, switch to a checkbox key or to Turnstile.
With fetch
When you submit with JavaScript, send the token along with your fields. FormData picks up the checkbox's hidden field:
const response = await fetch(form.action, {
method: 'POST',
headers: { Accept: 'application/json' },
body: new FormData(form),
})
const result = await response.json()
if (result.error === 'captcha_failed') {
grecaptcha.reset()
}A token can only be used once. Reset the checkbox after a failed submit so the visitor can tick it again.
When the check fails
A missing, expired, reused or invalid token, or a v3 score below 0.5, is rejected with 403 and captcha_failed, and the message "Captcha verification failed. Complete the captcha and try again". Nothing is stored, so the visitor can try again.
If every submission fails:
- Check that the site key in your page and the keys in your form settings belong to the same reCAPTCHA key.
- Check that your site's domain is in the key's domain list.
- Check that the checkbox, or the hidden
g-recaptcha-responseinput for v3, is inside the<form>element. - Check that the key type matches your code. A checkbox key needs the checkbox, and a score key needs
grecaptcha.execute. Mixing them shows "Invalid key type" in the widget.