reCAPTCHA v3
Solve reCAPTCHA v3 (and v3 Enterprise) challenges. Returns a token you verify server-side via siteverify with your secret.
reCAPTCHA v3
reCAPTCHA v3 runs invisibly — there is no checkbox or puzzle. The page calls grecaptcha.execute(site_key, { action }), Google scores the session, and hands back a token. The solver drives that flow in a real browser behind your proxy and returns the resulting token. You then verify it server-side with your secret key; the score and action checks are yours to make.
Request
| Field | Type | Required | Notes |
|---|---|---|---|
type | string | Yes | recaptchav3 (or alias recaptcha-v3). |
site_key | string | Yes | The reCAPTCHA site key (the render/data-sitekey value, usually starts 6L). |
url | string | Yes | The page where reCAPTCHA v3 runs. The token is bound to this URL's domain. |
action | string | No | The action name to execute. Defaults to verify if omitted — match what your backend asserts. |
enterprise | bool | No | true for reCAPTCHA Enterprise (loads enterprise.js). Defaults to false (standard v3). |
proxy | string | Yes | A proxy is required. http://, https://, socks4://, socks5:// schemes only. |
user_agent | string | No | Optional User-Agent override for the solving browser. |
Unlike Turnstile, proxy is required. reCAPTCHA scores the session partly on the egress IP, so the solver routes the whole flow through your proxy. Use a clean IP — a poor reputation egress yields a low score on siteverify.
Response
{
"success": true,
"type": "recaptchav3",
"token": "03AFcWeA...",
"cost": 0.0015
}| Field | Type | Notes |
|---|---|---|
success | bool | Always true on 200. |
type | string | Echoes the request type (recaptchav3). |
token | string | The reCAPTCHA response token. Submit it where your app expects g-recaptcha-response. |
cost | number | USD deducted from your balance for this call. |
Forward the token to your backend and verify it against Google's siteverify endpoint with your secret key. The token is bound to the domain of the url you submitted — the hostname field in the siteverify response will match it. The returned score and action are for you to evaluate against your own thresholds; the API does not gate on them.
Verify server-side
A token on its own proves nothing. Always call siteverify from your server with your secret, then check success, hostname, action, and score before trusting the request.
How it works (under the hood)
- The solver opens the target
urlin a real browser context, routed through your proxy. - It loads reCAPTCHA's
api.js(orenterprise.jswhenenterpriseistrue) for yoursite_key. - It calls
grecaptcha.execute(site_key, { action })— usingactionif you sent one, otherwise the defaultverify. - Google issues a scored token, which the solver returns.
You don't drive any of this — you just need site_key, url, and proxy.
Performance
| Metric | Typical value |
|---|---|
| Solve time | 3-6 seconds |
| Success rate | 90%+ |
score returned | 0.7-0.9 with a clean proxy |
Solve time is dominated by browser startup and the proxy latency on each leg. The
score you get back from siteverify depends mostly on the egress IP reputation
of your proxy — residential/mobile IPs score highest, datacenter IPs lowest.
Examples
import requests
proxy = "http://user:[email protected]:8000"
r = requests.post(
"https://api.nslsolver.com/solve",
headers={"X-API-Key": "YOUR_KEY"},
json={
"type": "recaptchav3",
"site_key": "6LcAAAAA...",
"url": "https://www.target.com/login",
"action": "login",
"proxy": proxy,
},
timeout=120,
)
solved = r.json()
token = solved["token"]
# Verify server-side with YOUR secret before trusting it
verify = requests.post(
"https://www.google.com/recaptcha/api/siteverify",
data={"secret": "YOUR_SECRET", "response": token},
).json()
# verify["success"], verify["hostname"], verify["action"], verify["score"]const proxy = "http://user:[email protected]:8000";
const r = await fetch("https://api.nslsolver.com/solve", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": process.env.NSL_API_KEY,
},
body: JSON.stringify({
type: "recaptchav3",
site_key: "6LcAAAAA...",
url: "https://www.target.com/login",
action: "login",
proxy: proxy,
}),
signal: AbortSignal.timeout(120_000),
});
const { token } = await r.json();
// Submit `token` as g-recaptcha-response, then siteverify on your backend.type RecaptchaReq struct {
Type string `json:"type"`
SiteKey string `json:"site_key"`
URL string `json:"url"`
Action string `json:"action,omitempty"`
Proxy string `json:"proxy"`
}
payload, _ := json.Marshal(RecaptchaReq{
Type: "recaptchav3",
SiteKey: "6LcAAAAA...",
URL: "https://www.target.com/login",
Action: "login",
Proxy: "http://user:[email protected]:8000",
})
req, _ := http.NewRequest("POST", "https://api.nslsolver.com/solve", bytes.NewReader(payload))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-API-Key", os.Getenv("NSL_API_KEY"))
client := &http.Client{Timeout: 120 * time.Second}curl -X POST https://api.nslsolver.com/solve \
-H "Content-Type: application/json" \
-H "X-API-Key: $NSL_API_KEY" \
-d '{
"type": "recaptchav3",
"site_key": "6LcAAAAA...",
"url": "https://www.target.com/login",
"action": "login",
"proxy": "http://user:[email protected]:8000"
}'For reCAPTCHA Enterprise, add "enterprise": true to any of the requests above.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
site_key is required | Missing site key | Send the render/data-sitekey value (usually starts 6L). |
url is required | Missing URL | Send the page URL where reCAPTCHA v3 runs. |
proxy is required | Missing proxy | reCAPTCHA v3 scores partly on the egress IP — a proxy is required. |
proxy format must be protocol://[user:pass@]host:port | Bad proxy URL | Use http://, https://, socks4://, or socks5://. |
Low score on siteverify | Poor proxy IP reputation, or action mismatch | Use cleaner (residential) proxies; ensure action matches your check. |
action mismatch on siteverify | Sent action ≠ the one your backend asserts | Send the same action your server expects (default is verify). |
hostname mismatch on siteverify | Solved a different domain than you verify | Use a url on the same domain you submit the token against. |
| Enterprise token rejected | Site uses enterprise.js but solved standard | Set "enterprise": true. |