# reCAPTCHA integration

> Add Google reCAPTCHA v2 (checkbox) or v3 (invisible) to your form. Formclick verifies every token on the server.

Source: https://docs.formclick.io/html-forms/recaptcha

> **Starter, Pro and Business plans:** reCAPTCHA is a paid feature. You also need your own reCAPTCHA keys from Google; they’re free.

reCAPTCHA stops automated submissions. Your visitor’s browser gets a token from Google, the token is sent with the form, and Formclick checks it with Google before saving the submission. Submissions without a valid token are rejected.

## 1. Create your keys

1. Open the [reCAPTCHA admin console](https://www.google.com/recaptcha/admin/create).
2. Choose **reCAPTCHA v2 → “I’m not a robot” Checkbox**, or **reCAPTCHA v3** for an invisible check.
3. Add your website’s domain (and `localhost` if you test locally).
4. Copy the **site key** and the **secret key**.

## 2. Turn it on in Formclick

Open your form → **Settings → Security**, choose **Google reCAPTCHA v2** or **v3**, paste both keys and save. The secret key is stored encrypted and never shown again.

> **Warning:** From the moment you save, submissions without a valid captcha are rejected. Add the widget to your form first, then save the setting.

## 3. Add it to your form

**reCAPTCHA v2 (checkbox)**

```html title="contact.html"
<form action="https://api.formclick.io/submit" method="POST">
  <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY">
  <input type="email" name="email" required>
  <textarea name="message" required></textarea>

  <!-- The checkbox. Google adds the token to the form for you. -->
  <div class="g-recaptcha" data-sitekey="YOUR_SITE_KEY"></div>

  <button type="submit">Send</button>
</form>

<script src="https://www.google.com/recaptcha/api.js" async defer></script>

<!-- Handles submit, file upload, loading state and success/error messages. -->
<script src="https://cdn.formclick.io/formclick.min.js"></script>
```

**reCAPTCHA v3 (invisible)**

```html title="contact.html"
<!-- Put your site key on the form tag -->
<form action="https://api.formclick.io/submit" method="POST" data-recaptcha-v3="YOUR_SITE_KEY">
  <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY">
  <input type="email" name="email" required>
  <textarea name="message" required></textarea>
  <button type="submit">Send</button>
</form>

<script src="https://www.google.com/recaptcha/api.js?render=YOUR_SITE_KEY"></script>
<!-- Handles submit, file upload, loading state and success/error messages. -->
<!-- Also fetches a fresh reCAPTCHA v3 token right before each submit. -->
<script src="https://cdn.formclick.io/formclick.min.js"></script>
```

## reCAPTCHA v3 score

reCAPTCHA v3 doesn’t show a challenge. Google scores each visitor from 0.0 (likely a bot) to 1.0 (likely a person), and Formclick rejects submissions below your **minimum score** (default 0.5, set in **Settings → Security**). Lower it if real visitors are being blocked; raise it if spam gets through.

> **Note:** reCAPTCHA v3 needs `formclick.min.js`, which asks Google for a token when the visitor presses Submit. reCAPTCHA v2 also works on plain HTML forms without the script.

## What visitors see when it fails

| Situation | Message |
| --- | --- |
| Checkbox not ticked (v2) | “Please complete the captcha.” (shown before sending, with `formclick.min.js`) |
| Token missing on the server | `400` “Please complete the captcha.” |
| Token invalid, expired, reused or v3 score too low | `400` “Captcha verification failed. Please try again.” |
| Google couldn’t be reached | `503` “We couldn’t verify the captcha. Please try again.” |

Tokens work once and expire after about two minutes. `formclick.min.js` resets the widget after every attempt, so visitors can try again straight away.

## If your plan changes

Captcha is checked only while your plan includes it. If your account moves to the Free plan, Formclick stops checking tokens so your form keeps working; upgrade again and the saved settings apply straight away.

## Using fetch or your own JavaScript

Send the token in a field named `g-recaptcha-response`. It is used for verification and never stored with the submission.

```js
const token = grecaptcha.getResponse(); // v2
// const token = await grecaptcha.execute('YOUR_SITE_KEY', { action: 'submit' }); // v3

await fetch('https://api.formclick.io/submit', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
  body: JSON.stringify({ access_key: 'YOUR_ACCESS_KEY', email, message, 'g-recaptcha-response': token }),
});
```
