Guide

Why reCAPTCHA v3 Stops Your AI Agent

reCAPTCHA v3 never shows your agent a puzzle. It scores the request from 0.0 to 1.0, hands that score to the site's own backend, and the site's threshold decides — so what you actually see is a 403, a form that will not submit, or a redirect into an extra verification step. Fixing it starts with working out whether you are being scored, challenged, or blocked by something else entirely.

reCAPTCHA v3 scores your request; it does not challenge it

There is no puzzle in v3. The page loads https://www.google.com/recaptcha/api.js?render=<sitekey>, calls grecaptcha.execute(sitekey, { action: 'login' }), and gets a token, which rides along with the form post or the XHR. The site's backend posts that token to Google's siteverify endpoint with its secret key and gets back a small JSON object:

  • success — whether the token verified at all
  • score — a float from 0.0 to 1.0
  • action — the action the token was minted under, echoed back
  • hostname — the origin it was minted on
  • challenge_ts — when it was minted

Google's documentation suggests 0.5 as a starting threshold, but every site sets its own, and a site can use a different one per action. That threshold is what rejected you. Not Google, and not a captcha.

Two things follow. First, the score never reaches the client, so your agent has nothing to log. You get whatever the site chose to do with it: a 403, a form that quietly does not submit, a redirect into an extra verification step, a 200 whose body says something went wrong. No error says "score too low".

Second, the token is short-lived (about two minutes) and single-use, and it carries the sitekey, origin and action it was minted under. Caching it past its lifetime or replaying it fails verification outright. A wrong action does not: siteverify still returns success and echoes the action back, and the site's own comparison of that field is what rejects you. Same visible outcome, completely different thing to debug.

Work out what is actually stopping you before you change anything

Ten minutes here decides everything downstream. All of it assumes the site is yours or you have authorization to automate it — if neither is true, skip to the last item in the next section.

  • Look for api.js?render= in the page source or the network tab. A render=<sitekey> parameter means v3: invisible, score-based, no user interaction. api.js without it, plus a g-recaptcha-response field, means v2 — checkbox or invisible.
  • Confirm reCAPTCHA is the thing failing. An Akamai, Cloudflare or DataDome interstitial is a different product, and a reCAPTCHA token does nothing for it. Neither does a 429 from the site's own rate limiter.
  • Run the flow by hand, in a normal browser, from the same egress IP as the agent. If the human session passes and the agent fails, the difference is the session. If both fail, you are looking at IP reputation or a block unrelated to scoring.
  • Try a second test account you own and a second IP. A failure that is byte-identical across both is usually a rule, not a score. Scores vary between attempts; rules do not.

Only after that does "get a token" become a sensible next step.

Why agents score badly

Google does not publish the signal list and it changes, so anyone who tells you exactly what moves the number is guessing. What is public is the shape: the score reflects how a request looks in context, and Google's documentation says the system needs real traffic before it calibrates well on a site.

The practical version is easy to reason about. A returning human arrives with cookies for that origin, history on the domain, and a residential IP that has done ordinary things for years. A fresh automation run has none of it: a profile created seconds ago, a datacenter egress range shared with a great deal of other automation, no prior page view on the site. A WebDriver-controlled browser also says so — navigator.webdriver is a standard flag those browsers set by design.

None of that is a defect in your agent. reCAPTCHA is built to be suspicious of exactly this traffic shape, and it cannot tell your accessibility audit from a credential-stuffing run. It is also why this page does not hand you client-side knobs to turn. Tuning a score from inside the browser is a treadmill, and on plenty of sites it is not even the dominant term.

Fix it in this order: allowlist, exemption, then a token

1. You own the site. Do not solve your own captcha. The case most people skip, and the cheapest by a wide margin. Turn reCAPTCHA off in staging. Or have the staging backend skip verification for requests carrying a signed header that only CI holds, with the CI egress allowlisted. Staging only — that bypass must not exist in the production build, because a verification skip that ships is a worse hole than the one it was meant to route around. Either way it costs nothing per run, adds no third-party dependency to the hot path, and survives a sitekey rotation.

2. You do not own it, but you have a relationship. Vendor, partner, customer, employer — ask. An API key, an IP exemption, or a service account is usually on the table, and most teams would rather hand you a documented endpoint than have a bot driving their UI. Asking also settles the authorization question in writing.

3. Authorized work, no allowlist and no relationship to lean on. Here a solving API is the remaining option. You send the sitekey, the page URL and the action; you get a token back and submit it where the page would have. One POST /solve against api.kagedcap.io, authenticated with an x-api-key header. Only successful solves are billed.

4. You are not authorized. Stop. If you cannot name who approved the automation and point at terms that permit it, a token does not solve your problem, it relocates it. If you asked and the answer was no, the answer is no.

What a token fixes, and what it does not

The v3 request:

{
  "task": "ReCaptchaV3Task",
  "url": "https://example.com/login",
  "sitekey": "6Lc...",
  "action": "login",
  "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36",
  "proxy": "http://user:pass@1.2.3.4:8888"
}

And the response:

{
  "success": true,
  "task": "ReCaptchaV3Task",
  "token": "03AFcWeA...",
  "score": null,
  "verification": null
}

score is a float from 0.0 to 1.0 when the solve reports one, and null when it does not. The example above leaves it null deliberately: any figure printed here would get read as a typical result, and there is no typical result. verification is populated only when you send secretKey — the API then runs siteverify with your own secret and returns what Google said, which is only meaningful if the secret is yours, and if it is, you are back in option 1.

ReCaptchaV3EnterpriseTask covers Enterprise sitekeys with the same fields. ReCaptchaV2Task covers v2 invisible: no action, and score is always null because a v2 token is pass/fail. v2 checkbox is not supported — it can escalate to an image challenge, which is a different problem. The ProxyLess variant of each task must omit proxy; every other reCAPTCHA task requires one. Proxy rules for the non-reCAPTCHA tasks are their own thing — check the docs rather than assuming this rule generalises.

action is optional on every reCAPTCHA task, but send the site's real action when you know it: siteverify reports it back to the verifying backend, which is an ordinary thing to reject on. Send a real desktop userAgent too — the token is minted against the UA you supply, so match the browser you replay with.

What a token does not fix: a WAF block, a rate limit, a suspended account, an expired session, or a threshold high enough that a good score still fails. The token is one field in a request. If that request was going to be refused for another reason, it still is.

Mechanics. Mint close to submission; the token dies in about two minutes. Failures are not billed, and the error codes say what to do:

  • Retry 503 no_capacity, 503 solver_unavailable and 504 solve_timeout with backoff — the solve never really happened.
  • Back off on 429 concurrency_limit_exceeded.
  • Never blindly retry 502 solve_failed. That was a real attempt, and repeating it is the usual route to the next code.
  • 429 key_frozen means the key is temporarily frozen after too many failed solves; the message carries the wait in seconds. Honour it rather than retrying through it.
  • 502 proxy_unreachable is the dead-proxy code: the solve ran and your proxy did not answer. Fix the proxy — the same one will fail again.
  • 400 proxy_required and 400 proxy_not_allowed mean a proxy paired with the wrong task variant.

For bursts, POST /v2/solve returns 202 with a job id — poll GET /v2/solve/{id} about every five seconds and read status, not success — or supply a public HTTPS callback_url and verify the X-Kagedcap-Signature header before trusting the delivered body.

Common questions

Why does my bot get blocked by reCAPTCHA v3 when there is no captcha to solve?

reCAPTCHA v3 does not present a challenge. It scores the request from 0.0 to 1.0 and returns that score to the site's own backend through Google's siteverify endpoint. The site compares it against a threshold it chose (Google suggests 0.5 as a starting point) and rejects the request itself. The score never reaches the browser, so your agent sees only the site's reaction — a 403, a form that silently fails, or a redirect into extra verification — and never an error that says the score was too low.

How long is a reCAPTCHA v3 token valid?

About two minutes, and it is single-use. It also carries the sitekey, the origin and the action it was minted under. Caching it past its lifetime or replaying it fails verification outright. A mismatched action is different: siteverify still succeeds and echoes the action back, and the site's own comparison of that field is what rejects the request. Mint the token as close as possible to the moment you submit it, and never cache or replay one.

Should I use a captcha solving API on a site I own?

No. If you control the site, allowlist your own automation instead — it is cheaper, faster, and has no third-party dependency in the hot path. Turn reCAPTCHA off in staging, or have the staging backend skip verification for requests carrying a signed header that only CI holds, with the CI egress range allowlisted. Keep that bypass out of the production build entirely; a verification skip that ships is a worse hole than the one it was meant to avoid. Solving your own captcha means paying per request to defeat a control you can simply configure.

Why does an automated browser score low on reCAPTCHA v3?

Because it has none of the context a returning human arrives with: no cookies for the origin, no history on the domain, and a datacenter egress IP shared with a lot of other automation. A WebDriver-controlled browser also advertises itself through the standard navigator.webdriver flag. This is not a defect in the agent — reCAPTCHA is designed to distrust exactly that traffic shape, and it cannot distinguish a sanctioned QA or accessibility run from an abusive one.

Should I retry a failed captcha solve?

It depends on the error code. Retry no_capacity, solver_unavailable and solve_timeout with backoff, because those mean the attempt never really ran. Do not blindly retry solve_failed: that was a real attempt, and hammering it is the usual way an API key ends up frozen. KagedCap freezes a key temporarily after too many failed solves and answers with a 429 key_frozen whose message says how many seconds to wait. If the proxy is the problem you get proxy_unreachable instead, and the fix is the proxy, not the retry.

What does a captcha solving API not fix?

A token is one field in one request. It does nothing for a WAF or bot-management interstitial from Cloudflare, Akamai or DataDome, a rate limit, a suspended account, an expired session, or a site whose score threshold is high enough that even a good score fails. It also does not create authorization: if the automation is not sanctioned by whoever runs the site, or the site's terms forbid it, the correct action is to stop rather than to route around the control.

SupportWhy reCAPTCHA v3 Stops Your AI Agent — KagedCap