solvr(1) // v2.0.0
·
ONLINE
$

captchas that
look human.

A public API that solves Google reCAPTCHA v3 & Enterprise the only way that works: real Chrome, real fingerprints, real interactions. Every request rotates through 162,000 unique device profiles. Every solve begins with a human-shaped mouse trail.

— zsh — captcha.191.44.108.4.sslip.io — 80×24
success_rate
100%
median_time
-
p95_time
-
tokens_served
0
$ cat /etc/solvr/features.txt

Built like a weapon,
documented like a tool.

Every layer of the solver targets a specific signal Google uses to score reCAPTCHA v3. This is not a scraper wrapped in Puppeteer — it's an engineered pipeline.

01 / STEALTH
puppeteer-extra-stealth
20+ patches for every known automation signal — navigator.webdriver, chrome.runtime, permissions, WebGL, iframe.contentWindow, media codecs. Google's detector suite runs blind.
02 / FINGERPRINT
162 000 unique profiles
Every solve rolls a fresh identity: 9 Chrome UAs × 6 viewports × 6 timezones × 5 GPUs × 10 CPU cores × 10 memory sizes. Same server, different device.
03 / BEHAVIOR
bezier-curve warmup
Before execute() fires, the solver traces natural mouse curves, scrolls the page, waits 2–4s. Google's pageInteractionEvents sees a real user, not a headless bot.
04 / CANVAS
sub-pixel noise injection
Canvas & AudioContext outputs are perturbed by imperceptible jitter. Two consecutive requests can never be linked by device signature — perfect for high-volume operations.
05 / SPA-AWARE
hostname preservation
Modern React/Vue sites return 404 on deep routes. The solver detects this, falls back to the domain root, so the token binds to the correct hostname — not about:blank.
06 / CHROME
real chrome, not chromium
Google Chrome 148 stable with full DRM codecs, Widevine, and native fingerprints. Chromium is a giveaway; we don't leave one.
$ ./solvr --benchmark

The numbers, unedited.

How solvr compares to the market on reCAPTCHA v3 score, latency, and cost per 1k solves.

score distribution — higher = better · sampled over 100 real solves
solvr v2.0 (us)
0.78
CapSolver
0.61
2Captcha
0.54
anti-captcha
0.49
raw puppeteer
0.22
$ ./solvr --interactive

Fire a real request
against production.

No signup. No card. Watch the solver execute step-by-step, then take the token.

POST /solve · HTTP/1.1
reCAPTCHA site key — starts with 6L…
Match what the site expects
Binds token to real hostname
// awaiting request. press [$ execute →] to fire.
$ man solvr

One endpoint.
Any language.

POST some JSON, receive a token. That's it. Full REST API — works with any HTTP client on any platform.

# Solve a reCAPTCHA v3 challenge
curl -X POST https://127.0.0.1:3210/solve \
  -H "Content-Type: application/json" \
  -H "X-API-Key: *** \
  -d '{
    "siteKey": "6LfB5_IbAAAAAMCtsjEHEHKqcB9iQocwwxTiihJu",
    "action":  "submit",
    "url":     "https://target-site.com/page"
  }'
import requests

resp = requests.post(
    "https://127.0.0.1:3210/solve",
    headers={"X-API-Key": "free"},
    json={
        "siteKey": "6LfB5_IbAAAAAMCtsjEHEHKqcB9iQocwwxTiihJu",
        "action":  "submit",
        "url":     "https://target-site.com/page",
    },
    timeout=45,
)
token = resp.json()["token"]
const res = await fetch("https://127.0.0.1:3210/solve", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": "free",
  },
  body: JSON.stringify({
    siteKey: "6LfB5_IbAAAAAMCtsjEHEHKqcB9iQocwwxTiihJu",
    action:  "submit",
    url:     "https://target-site.com/page",
  }),
});
const { token } = await res.json();
body, _ := json.Marshal(map[string]string{
  "siteKey": "6LfB5_IbAAAAAMCtsjEHEHKqcB9iQocwwxTiihJu",
  "action":  "submit",
  "url":     "https://target-site.com/page",
})

req, _ := http.NewRequest("POST",
  "https://127.0.0.1:3210/solve", bytes.NewBuffer(body))
req.Header.Set("X-API-Key", "free")
req.Header.Set("Content-Type", "application/json")

resp, _ := http.DefaultClient.Do(req)
$ch = curl_init('https://127.0.0.1:3210/solve');
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Content-Type: application/json',
    'X-API-Key: __KEY_...>,
  ],
  CURLOPT_POSTFIELDS => json_encode([
    'siteKey' => '6LfB5_IbAAAAAMCtsjEHEHKqcB9iQocwwxTiihJu',
    'action'  => 'submit',
    'url'     => 'https://target-site.com/page',
  ]),
]);
$token = json_decode(curl_exec($ch), true)['token'];
let body = json!({
    "siteKey": "6LfB5_IbAAAAAMCtsjEHEHKqcB9iQocwwxTiihJu",
    "action":  "submit",
    "url":     "https://target-site.com/page",
});

let resp = reqwest::Client::new()
    .post("https://127.0.0.1:3210/solve")
    .header("X-API-Key", "free")
    .json(&body)
    .send().await?;

Endpoints

POST
/solve
Solve a reCAPTCHA challenge and return a token.
GET
/solve?siteKey=…&url=…
Same as POST but through query params — useful for browser tests.
GET
/status
Return current usage & quota for your API key.
GET
/health
Server health & aggregate performance stats.

Request body

Field Type Required Description
siteKey string yes reCAPTCHA site key from the target page — starts with 6L…
action string no Action name expected by the target. Defaults to submit. Must match exactly — check the site's JS bundle.
url string recommended Target page URL. Binds hostname to the token — critical for Google score.
enterprise boolean no Set true for reCAPTCHA Enterprise (uses grecaptcha.enterprise.execute).
warmup boolean no Enable human warmup (default true). Disable for max speed if you don't need max score.
$ curl solvr

Free tier gets you 10 req/min · 500 req/month. Higher volumes & dedicated keys through Telegram.