How to Solve reCAPTCHA v3 in Python and Set an Action

solve recaptcha v3 in python - How to Solve reCAPTCHA v3 in Python and Set an Action

reCAPTCHA v3 never shows a challenge. It runs in the background and hands the site a token, which the site then verifies server side. From your code that means there is nothing to click and nothing to look at, so the whole job is producing a token the site will accept. In Python that is the same recaptcha method you would use for v2, with a version flag.

The part that trips people up is the action.

Setup

# Python 3.10 or newer.
pip install capskip
from capskip import CapSkip

solver = CapSkip(
    host="127.0.0.1",
    port=8080,
    recaptchaTimeout=300,   # seconds, shared with Turnstile and GeeTest
)

CapSkip runs on your own machine, so the desktop app has to be open before any of this works.

The basic call

result = solver.recaptcha(
    sitekey="6Lc...YOUR_SITEKEY",
    url="https://example.com/checkout",
    version="v3",
    action="submit",
)

print(result["code"])   # the v3 token

Two things differ from v2. version="v3" is required, and action should match whatever the page passes to grecaptcha.execute. If you omit it the default is verify.

Why the action matters

v3 actions are labels the site attaches to each protected interaction, so a login and a checkout can be scored separately. The site’s own backend usually checks that the action on the returned token matches the action it expected for that endpoint.

Send the wrong one and the token is technically valid but arrives labelled for a different interaction, which many backends reject outright. Read the real value out of the page rather than guessing:

import re
import requests

html = requests.get("https://example.com/checkout").text

# Sites usually call execute() with the action as a literal string.
match = re.search(r"execute\([^,]+,\s*\{\s*action:\s*['\"]([^'\"]+)", html)
action = match.group(1) if match else "verify"

result = solver.recaptcha(
    sitekey=sitekey, url=page_url, version="v3", action=action,
)

Common values are login, submit, homepage and checkout, but they are arbitrary strings chosen by whoever built the site.

Enterprise v3

Enterprise is an orthogonal flag rather than a separate product, so it stacks on top:

result = solver.recaptcha(
    sitekey=sitekey,
    url=page_url,
    version="v3",
    enterprise=1,
    action="submit",
)

You can tell Enterprise from standard by the script the page loads. Enterprise pulls enterprise.js, standard pulls api.js. Guessing wrong causes the solve to fail rather than returning a bad token, so it is cheap to check.

Submitting the token

import requests

response = requests.post(
    "https://example.com/checkout",
    data={
        "g-recaptcha-response": result["code"],
        "order_id": "...",
    },
)

Some v3 integrations use a different field name, or send the token as JSON, because there is no standard form widget to constrain them. Check what the page’s own JavaScript does before assuming g-recaptcha-response.

Solving in bulk

Python is the only CapSkip SDK where AsyncCapSkip is a real async client rather than an alias, so it genuinely overlaps work:

import asyncio
from capskip import AsyncCapSkip

async def main():
    solver = AsyncCapSkip()
    tokens = await asyncio.gather(*[
        solver.recaptcha(sitekey=sitekey, url=u, version="v3", action="submit")
        for u in urls
    ])
    return [t["code"] for t in tokens]

asyncio.run(main())

Errors

from capskip import (
    ValidationException, NetworkException, ApiException, TimeoutException,
)

try:
    result = solver.recaptcha(sitekey=sitekey, url=page_url, version="v3")
except ValidationException:
    pass   # missing sitekey or url
except NetworkException:
    pass   # CapSkip is not running
except ApiException:
    pass   # rejected sitekey or pageurl
except TimeoutException:
    pass   # exceeded recaptchaTimeout

Frequently asked questions

What happens if I leave out the action?

It defaults to verify. That works on sites that never check the action, and fails on sites that do. Since reading the real value out of the page is a few lines, it is worth doing rather than relying on the default.

Can I check the score before submitting?

No. The score lives with Google and is only revealed to the site owner when their backend verifies the token. From the client side you get a token and nothing else, so there is no way to inspect or filter on the score before you submit.

How long is a v3 token valid?

About two minutes, and single use, the same as v2. Solve immediately before the request that needs it rather than building up a pool.

Summary

Pass version="v3", set action to whatever the page actually uses, add enterprise=1 when the page loads enterprise.js, and submit the token quickly because it expires in about two minutes.

Other languages are covered on the reCAPTCHA v3 solver page, the Enterprise specifics on the Enterprise solver page, and the wider Python surface on the Python CAPTCHA solver page. You can watch a real v3 token being generated on our v3 demo, and CapSkip itself is an unlimited captcha solver that runs locally.