Solve reCAPTCHA Enterprise with Python
Use the official Python SDK to request a reCAPTCHA v3 Enterprise token, then submit solution.token with the returned browser identity and the same proxy. You'll need Python 3.10 or later, a workspace API key, and an active profile for the target site.
On this page
Install the SDK and configure your site
Install the official Python SDK:
python -m pip install https://solvethree.com/downloads/solvethree_sdk-0.1.0-py3-none-any.whl- 1.
Create the site profile
Set up the target hostname in the solvethree console and make sure its profile is active and available to your workspace. Sending a hostname in a solve request doesn't create a profile. See site profile setup if you haven't configured one.
- 2.
Set SOLVETHREE_API_KEY
In the shell or deployment environment that will run the script, set
SOLVETHREE_API_KEYto your workspace API key. Keep it on the server, not in browser code or a committed source file. - 3.
Set SOLVETHREE_PROXY
Set
SOLVETHREE_PROXYto the proxy URL the solve and subsequent application request will use. The example uses one proxy, so don't also addproxyCandidates.
Request the Enterprise token
Save this example as solve.py. Replace accounts.example.com with your configured hostname—without a scheme or path—and replace login with the action used by the target page.
import os
from uuid import uuid4
from solvethree import Solvethree, SolvethreeError, TaskFailedError
client = Solvethree(os.environ["SOLVETHREE_API_KEY"])
request = {
"site": "accounts.example.com", # Use your configured hostname.
"action": "login", # Use the page's actual action.
"proxy": os.environ["SOLVETHREE_PROXY"],
"requestId": str(uuid4()),
}
try:
result = client.solve(request, timeout=180)
except TaskFailedError as error:
raise SystemExit(f"Task failed: {error.error_code}") from None
except SolvethreeError as error:
# Keep these IDs so an interrupted request can be recovered.
raise SystemExit(f"Recover request {error.request_id}, task {error.task_id}") from None
solution = result["solution"]
token = solution["token"]
user_agent = solution["userAgent"]
client_hints = solution["secChUa"]
print("Ready task:", result["id"]) # Do not print the token or proxy password.The request defaults to enterprise-v3, so it doesn't need a recaptchaType field. Don't add type or url; those aren't reCAPTCHA request fields.
Solvethree is synchronous. client.solve creates the task once, then polls until it returns a ready result or raises an exception. Here, timeout=180 sets a 180-second limit on how long the client waits. On success, the script extracts the token, user agent and client hints without printing sensitive values.
Submit the token to your application
Continue in the same script after the solve. Install requests separately as noted in the example. Replace the login URL and form data with your application's actual request, including any required credentials, CSRF token and session cookies.
# Continue after client.solve(). Install requests separately: pip install requests.
import requests
# This example endpoint accepts the standard reCAPTCHA form field.
# Use your application's real URL, form fields, CSRF token and session.
response = requests.post(
"https://accounts.example.com/login",
data={"g-recaptcha-response": solution["token"]},
headers={
"User-Agent": solution["userAgent"],
"sec-ch-ua": solution["secChUa"],
},
proxies={"http": request["proxy"], "https": request["proxy"]},
timeout=30,
allow_redirects=False,
)
# Inspect the application's response to determine whether it accepted the request.
print("Application HTTP status:", response.status_code)This example assumes the application accepts the token in g-recaptcha-response. Check the real request rather than assuming that field name. If the form depends on an existing session, submit through that session instead of making a fresh, cookieless request.
Keep the returned userAgent and secChUa, and use the same proxy supplied to the solve. Switching IPs or substituting an unrelated browser identity can break the request.
A ready task means a solution was generated, not that the application accepted it. Inspect the application's response and resulting session; an HTTP status alone doesn't establish a successful login. If it rejects the token, check the outgoing request before paying for another solve: it must contain solution.token, not the task ID or an old token. See diagnosing a rejected token.
Recover an interrupted solve without creating another task
The example generates a new requestId each time the script starts. Save that ID and the original request before calling solve if you need recovery across process restarts. Simply rerunning the script creates a new logical request.
- If an exception includes
task_id, useget_taskto resume polling that task. Don't create a replacement just because the connection timed out. - If creation was interrupted and you only have
request_id, replay the identical task request with that samerequestId. It returns the existing task; changing the task inputs while reusing the ID conflicts. - For
TaskFailedError, stop polling that task. Inspect itserrorCodeanderrorbefore retrying; unchanged invalid inputs won't be fixed by another solve. Failed solves are refunded.
The SDK doesn't automatically retry task creation. It does honor Retry-After for temporary polling failures within the solve deadline. For more control over waiting and recovery, see task polling and timeouts.
Sources and API reference
Run your first task.
Start with $5 in workspace credit.