Back to Overview

reCAPTCHA Bot Protection

Protect your signup and booking forms from bots with Google reCAPTCHA v3 — invisible verification with no user friction.

Luka Breitig — Technical Product Builder & AI Developer
Luka Breitig

Technical Product Builder & AI Developer

Before You Begin

You will need:

  • A Google account with access to google.com/recaptcha/admin
  • A publicly accessible production domain for your Tymeslot instance (e.g., tymeslot.yourdomain.com) — reCAPTCHA tokens are domain-bound and do not work on localhost
  • Access to your Tymeslot instance's environment variables

By the end of this guide, your signup and booking forms will be protected against bot submissions with invisible reCAPTCHA v3.

How reCAPTCHA v3 Works

reCAPTCHA v3 (also called "invisible CAPTCHA" or "score-based CAPTCHA") runs entirely in the background. It assigns a score from 0.0 (very likely a bot) to 1.0 (very likely human) based on user behaviour signals, and Tymeslot rejects submissions below your configured threshold. Legitimate users see no challenge, no checkbox, and no puzzle.

Do not confuse it with reCAPTCHA v2 (the "I'm not a robot" checkbox — that is a different product) or hCaptcha (a different provider entirely). Tymeslot integrates with v3 only.

reCAPTCHA is optional and disabled by default. The next section helps you decide whether to enable it.

Should You Enable reCAPTCHA?

Enable reCAPTCHA if you are experiencing any of the following:

  • Bot registrations — a surge of accounts with random email patterns (e.g., xk3m9@mailinator.com)
  • Spam bookings — meetings booked with fake names or throwaway email addresses
  • Credential stuffing — repeated failed login attempts against your users' accounts

You can safely skip reCAPTCHA for small or private deployments where your scheduling link is shared only with known contacts. There is no security benefit in adding friction to a closed deployment.

1 Create a reCAPTCHA Site

  1. Go to google.com/recaptcha/admin and click the [+] button in the top-right corner to create a new site.
  2. Set Label to something identifiable, such as Tymeslot Production.
  3. Under reCAPTCHA type, select [Score based (v3)]. Do not select v2 — it presents a checkbox challenge to users and is not what Tymeslot integrates with.
  4. Under Domains, add your production domain exactly as it appears in the browser address bar — for example, tymeslot.yourdomain.com. Do not include https:// or a trailing slash.
  5. Accept the terms of service and click [Submit].
  6. You are shown a [Site Key] and a [Secret Key]. Copy both — you will need them in the next step. The site key is embedded in your pages (public); the secret key stays server-side (private).

2 Configure Environment Variables

Add the following environment variables to your Tymeslot instance. Restart the application after making changes.

# reCAPTCHA v3 keys from google.com/recaptcha/admin
RECAPTCHA_SITE_KEY=6Le...your-site-key
RECAPTCHA_SECRET_KEY=6Le...your-secret-key

# Accepted hostname — only tokens generated on this domain are accepted.
# Prevents token replay attacks (see explanation below).
RECAPTCHA_EXPECTED_HOSTNAMES=tymeslot.yourdomain.com

# Protect the signup form
RECAPTCHA_SIGNUP_ENABLED=true
RECAPTCHA_SIGNUP_MIN_SCORE=0.5
RECAPTCHA_SIGNUP_ACTION=signup_form

# Protect the booking form
RECAPTCHA_BOOKING_ENABLED=true
RECAPTCHA_BOOKING_MIN_SCORE=0.3
RECAPTCHA_BOOKING_ACTION=booking_form

Why does RECAPTCHA_EXPECTED_HOSTNAMES matter?

A reCAPTCHA token is tied to the domain that generated it, but without hostname verification an attacker could generate a valid token on their own site and replay it against your Tymeslot instance. Setting this variable to your exact domain causes Tymeslot to reject any token that was not generated on your site.

Score Thresholds

Google scores each interaction from 0.0 to 1.0. Tymeslot blocks submissions whose score falls below your configured minimum. Use this table as a reference:

0.0 Very likely a bot — automated traffic with no human signals
0.3 Suspicious — recommended minimum for booking forms
0.5 Neutral — recommended minimum for signup forms
0.7 Likely human — confident interaction pattern
1.0 Very likely human — strong human interaction signals

Why different thresholds for signup and booking? Booking forms are often the first touch point for people who just received a scheduling link from a colleague — they are real humans, but Google may score them lower because they have no prior interaction history with your site. A more permissive threshold (0.3) prevents blocking these legitimate users. Signup forms attract more determined bots and can safely use a higher threshold (0.5) — a false positive just means the user tries again.

Do Not Set Thresholds Above 0.7

Thresholds above 0.7 will block legitimate users — particularly those on older devices, mobile connections, or with browser extensions that interfere with reCAPTCHA's behaviour signals. Start conservative and raise the threshold only if bot traffic persists.

Development Environment

reCAPTCHA is automatically disabled in the development environment regardless of how your environment variables are set. You do not need to add any variables to your local .env file, and no code changes are required for local testing. All forms accept submissions normally in dev.

Enable reCAPTCHA in Staging First

Before rolling out to production, deploy to a staging environment with reCAPTCHA enabled. Submit a real booking from a browser, then open google.com/recaptcha/admin, select your site, and view the [Analytics] tab to confirm that the score appeared. This verifies end-to-end integration before real users are affected.

Monitoring Score Distributions

Once reCAPTCHA is live, use the admin console to understand how your real users are scoring and decide whether your thresholds need adjusting:

  1. Go to google.com/recaptcha/admin and select your site.
  2. Click the [Analytics] tab.
  3. Review the score distribution histogram. If the bulk of your traffic is scoring above 0.7, your thresholds are well-calibrated. If you see a large cluster near your threshold boundary, consider whether those users are being incorrectly blocked.

Troubleshooting

Legitimate users are blocked from completing a booking

Lower RECAPTCHA_BOOKING_MIN_SCORE to 0.2 or 0.1 and monitor the reCAPTCHA admin console to see if score distributions shift. Users on mobile or with certain browser extensions can score lower than expected.

reCAPTCHA tokens are always rejected

Check that RECAPTCHA_EXPECTED_HOSTNAMES exactly matches your production domain — no trailing slash, no https:// prefix. The value must be the bare hostname as it appears in the browser address bar.

reCAPTCHA appears to be doing nothing

Verify that the Site Key used in environment variables matches the key shown in the reCAPTCHA admin console for your site. Also confirm that RECAPTCHA_SIGNUP_ENABLED or RECAPTCHA_BOOKING_ENABLED is set to true (not 1 or yes).

Frequently Asked Questions

reCAPTCHA is configured but the booking form still submits without any visible check — why?

That is expected behaviour. reCAPTCHA v3 is invisible — it runs silently in the background and never presents a challenge to the user. If you suspect it is not running at all, open the reCAPTCHA admin console at google.com/recaptcha/admin, select your site, and check the Analytics tab. If no scores appear after submitting the form, verify that RECAPTCHA_SITE_KEY is correct and that your domain is registered under the site key settings.

What reCAPTCHA version does Tymeslot use?

Tymeslot uses reCAPTCHA v3 exclusively. It is invisible to users — no checkbox, no image puzzle, and no interruption to the form flow. Google's systems observe user behaviour signals in the background and return a score between 0.0 (likely a bot) and 1.0 (likely human). Tymeslot rejects submissions whose score falls below your configured threshold.

Can I use reCAPTCHA v2 (the 'I'm not a robot' checkbox) instead?

No. Tymeslot integrates with the reCAPTCHA v3 Score API only. A v2 site key will not work — the two versions use different APIs and different token formats. When creating your site in the reCAPTCHA admin console, you must select Score based (v3).

How do I register my domain with reCAPTCHA?

In the Google reCAPTCHA admin console at google.com/recaptcha/admin, open your site's settings and locate the Domains section. Add your domain exactly as it appears in the browser address bar — for example tymeslot.yourdomain.com — without the https:// prefix or a trailing slash. Subdomains are covered automatically once the root domain is listed.

Users on localhost cannot complete the booking form after enabling reCAPTCHA — why?

reCAPTCHA v3 validates tokens against a registered domain list. localhost is not trusted by default. You can add it explicitly in the reCAPTCHA admin console under your site key's Domains settings. Alternatively, leave localhost unregistered — Tymeslot automatically disables reCAPTCHA in the development environment, so local testing is unaffected by production reCAPTCHA configuration.

Verification Checklist

Confirm each item before considering reCAPTCHA live:
  • reCAPTCHA site created in Google admin console with type Score based (v3)
  • Your production domain is listed under Domains in the Google console (no https:// prefix)
  • Both RECAPTCHA_SITE_KEY and RECAPTCHA_SECRET_KEY are set in environment variables
  • RECAPTCHA_EXPECTED_HOSTNAMES is set to your exact production domain
  • Tymeslot restarted after environment variable changes
  • A real booking was submitted from a browser in staging and the score appeared in the reCAPTCHA [Analytics] tab
  • The booking went through successfully (confirming the threshold is not too aggressive)

🔗 Related Articles

Read Docker Self-Hosting

Docker Self-Hosting

Deploy Tymeslot using Docker and Docker Compose. Perfect for VPS hosting, home servers, or any environment with Docker support.

Read Cloudron Deployment

Cloudron Deployment

One-click installation on Cloudron. Automated backups, SSL certificates, and updates handled automatically.

Read Reverse Proxy Setup

Reverse Proxy Setup

Run Tymeslot behind Nginx or Caddy with automatic HTTPS. Required for production deployments and OAuth integrations.