Backend SDK-style examples
These examples all do the same thing: your backend receives a token, calls the siteverify REST endpoint with your secret, then inspects the JSON response. For reCAPTCHA v3 specifically, Google documents that you should validate the action and use the score to decide what to do next for the request.
Node.js (server-side verify)
// Node.js 18+
import express from "express";
const app = express();
app.use(express.json()); // Parses application/json requests
app.post("/api/login", async (req, res) => {
const token = req.body.recaptchaToken;
// Prepare parameters for Google (x-www-form-urlencoded)
const params = new URLSearchParams();
params.set("secret", process.env.RECAPTCHA_SECRET);
params.set("response", token);
const verifyResp = await fetch("https://www.google.com/recaptcha/api/siteverify", {
method: "POST",
headers: { "content-type": "application/x-www-form-urlencoded" },
body: params
});
const data = await verifyResp.json();
if (!data.success) {
return res.status(403).json({
error: "recaptcha_failed",
details: data["error-codes"]
});
}
if (data.action !== "login") {
return res.status(403).json({ error: "recaptcha_action_mismatch" });
}
// Choose your own thresholds based on traffic patterns
if (data.score < 0.5) {
return res.status(403).json({
error: "recaptcha_low_score",
score: data.score
});
}
return res.json({ ok: true });
});
app.listen(3000);
The siteverify URL, method, and parameters are defined in Google's verification documentation. The score and action fields come from Google's reCAPTCHA v3 documentation.
Python (server-side verify)
import os
import requests
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.post("/api/signup")
def signup():
token = request.json.get("recaptchaToken")
r = requests.post(
"https://www.google.com/recaptcha/api/siteverify",
data={
"secret": os.environ["RECAPTCHA_SECRET"],
"response": token,
# "remoteip": request.remote_addr, # optional
},
timeout=5,
)
data = r.json()
if not data.get("success", False):
return jsonify({"error": "recaptcha_failed"}), 403
if data.get("action") != "signup":
return jsonify({"error": "recaptcha_action_mismatch"}), 403
if data.get("score", 0) < 0.5:
return jsonify({"error": "recaptcha_low_score"}), 403
return jsonify({"ok": True})
The siteverify endpoint, required parameters, and the error-codes array are specified in Google's verification documentation.
Browser JavaScript (token creation recap)
This is the browser-side portion of the captcha google api flow: execute reCAPTCHA with an action and forward the token to your backend for verification.
grecaptcha.ready(() => {
grecaptcha.execute("YOUR_SITE_KEY", { action: "submit" }).then(async (token) => {
await fetch("/api/contact", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ recaptchaToken: token })
});
});
});
Authentication model (what proves you're allowed to verify)
The secret POST parameter is the shared key between your site and reCAPTCHA, and it authenticates your server-to-server verification call to siteverify. Because the token expires quickly and is single-use, you should verify it promptly and avoid retrying verification with the same token. If you need a new token, Google's guidance is to re-run the client-side reCAPTCHA flow.
Error handling and error codes
At the API level, the verification response includes success and may include error-codes that describe what went wrong. Google's documented error code reference for siteverify is below:
missing-input-secret: The secret parameter is missing
invalid-input-secret: The secret parameter is invalid or malformed
missing-input-response: The response parameter (token) is missing
invalid-input-response: The token is invalid or malformed
bad-request: The request is invalid or malformed
timeout-or-duplicate: The token is no longer valid (too old) or has already been used
Treat missing/invalid-* errors as configuration or request bugs, and treat timeout-or-duplicate as an expected runtime condition when tokens expire or are replayed.
Interpreting the Score (0.0 to 1.0)
Unlike reCAPTCHA v2, v3 does not show a challenge (like "click the buses"). Instead, it returns a score.
Google does not block requests automatically; it is up to your backend logic to interpret the score. A common starting threshold is 0.5.
Recommended Actions based on Score
High Score (> 0.5): Grant access immediately.
Low Score (< 0.5): Do not just block. instead, introduce friction:
Require Two-Factor Authentication (2FA).
Send a verification email.
Serve a visible challenge (like reCAPTCHA v2) as a fallback.
Send the transaction to manual review.
Implementation checklist
Register reCAPTCHA v3 keys and embed the site key in your frontend integration
Generate tokens for explicit action names and send the token to your backend immediately
Verify the token with POST https://www.google.com/recaptcha/api/siteverify using your secret key
Enforce token restrictions: verify within two minutes and only once per token
For v3, check action and use score to choose your response behavior
Handle error-codes using Google's documented meanings (especially timeout-or-duplicate)
Captcha Solver APIs (Automation & Testing)
Note: This section addresses the "solver API" distinction mentioned in the introduction.
While the "Captcha API" protects your site, Captcha Solver APIs (like CapMonster Cloud) are services used by developers to automate testing or by software that needs to bypass CAPTCHAs. These services use AI or human workers to generate valid tokens that mimic real users.
If you are building an automated test suite or a scraper and need to bypass reCAPTCHA v3, you would use a solver API to obtain a token and then submit it to the target website just like a browser would.
For more details and CapMonster Cloud integration examples, please refer to its official API documentation.
Useful Links