Scraping Central is reader-supported. When you buy through links on our site, we may earn an affiliate commission.

4.39intermediate5 min read

Third-Party Solvers: 2Captcha, CapSolver, Anti-Captcha

The main CAPTCHA-solving services in 2026. Pricing, API patterns, reliability differences.

What you’ll learn

  • Compare 2Captcha, CapSolver, Anti-Captcha at a feature level.
  • Understand the polling and callback API patterns.
  • Pick a provider based on captcha type and volume.

When CAPTCHAs are unavoidable, you outsource the solve. Three services dominate. They differ in price, reliability per CAPTCHA type, and API ergonomics.

The major services

Service Founded Notes
2Captcha (also branded 2captcha.com) 2014 Largest; supports nearly every CAPTCHA type
CapSolver 2021 Newer; ML-driven; aggressive pricing
Anti-Captcha 2007 Oldest; reliable; sometimes higher prices
DeathByCaptcha 2009 Cheapest historically; smaller variety
CapMonster (cloud variant) Self-hosted ML solver + cloud option

How solving works

All major services use a similar pattern:

  1. You submit the CAPTCHA (image, site key + URL, audio file).
  2. You receive a task ID.
  3. You poll the task ID until status = solved.
  4. You receive the solution (token or text).
import requests, time

API_KEY = "your-key"

def solve_recaptcha_v2(site_key, page_url):
  # Submit
  r = requests.post("https://2captcha.com/in.php", data={
  "key": API_KEY,
  "method": "userrecaptcha",
  "googlekey": site_key,
  "pageurl": page_url,
  "json": 1,
  }).json()
  if r["status"] != 1: raise RuntimeError(r["request"])
  task_id = r["request"]

  # Poll
  for _ in range(60):
  time.sleep(5)
  r = requests.get("https://2captcha.com/res.php", params={
  "key": API_KEY, "action": "get", "id": task_id, "json": 1
  }).json()
  if r["status"] == 1:
  return r["request"]  # the token to submit to the target
  if r["request"] != "CAPCHA_NOT_READY":
  raise RuntimeError(r["request"])
  raise TimeoutError()

That's the pattern. The token returned is then submitted along with the form data on the target site.

Pricing (approximate, 2026)

CAPTCHA 2Captcha CapSolver Anti-Captcha
reCAPTCHA v2 $1.00/1000 $0.80/1000 $1.50/1000
reCAPTCHA v3 $1.50/1000 $1.20/1000 $2.00/1000
hCaptcha $1.50/1000 $1.00/1000 $2.50/1000
Image CAPTCHA $0.80/1000 $0.70/1000 $1.00/1000
FunCaptcha $4.00/1000 $3.50/1000 $5.00/1000
Turnstile $1.50/1000 $1.20/1000 $2.00/1000

These are list prices. Volume discounts apply at $100+/mo commitments. Always verify current rates.

Reliability differences

For most CAPTCHA types, all three services hover at 90–95% solve success. Differences:

  • 2Captcha has the broadest type support; if you need an obscure regional CAPTCHA, they're most likely to have it.
  • CapSolver is ML-leaning; faster for image puzzles; less reliable for behavior-scored types.
  • Anti-Captcha uses more human solvers; reliable but slower (often 30-60s per solve).

Speed matters: if your scraper times out waiting 60s for a solve, you've lost the session. Choose providers with average solve times under 20s for time-sensitive flows.

Integration patterns

Standalone Python

class CaptchaSolver:
  def __init__(self, api_key, base="https://2captcha.com"):
  self.key = api_key
  self.base = base

  def solve_recaptcha_v2(self, site_key, page_url, timeout=120):
  # see code above

  def solve_image(self, image_b64):
  r = requests.post(f"{self.base}/in.php", data={
  "key": self.key, "method": "base64", "body": image_b64, "json": 1
  }).json()
  # poll, return text

Wrap each service in a class. Switch providers via dependency injection.

Inside Playwright

async def with_captcha_handling(page):
  if await page.locator("iframe[src*='recaptcha']").count() > 0:
  # extract site key from page
  site_key = await page.evaluate("() => document.querySelector('.g-recaptcha').dataset.sitekey")
  token = solver.solve_recaptcha_v2(site_key, page.url)
  # inject the token
  await page.evaluate(f'document.getElementById("g-recaptcha-response").value="{token}"')
  await page.evaluate("___grecaptcha_cfg.clients[0].O.O.callback('{token}')")

After solving, inject the token into the page's reCAPTCHA response field and call the callback. The page now considers itself "verified."

In Scrapy

A custom middleware that intercepts responses showing CAPTCHA, solves, retries:

class CaptchaMiddleware:
  def process_response(self, request, response, spider):
  if "data-sitekey" in response.text:
  site_key = re.search(r'data-sitekey="([^"]+)"', response.text).group(1)
  token = self.solver.solve_recaptcha_v2(site_key, response.url)
  new_request = request.copy()
  new_request.cookies["g-recaptcha-response"] = token
  new_request.dont_filter = True
  return new_request
  return response

Per request, expensive, only enable when you know the route includes CAPTCHAs.

PHP integration

class CaptchaSolver
{
  public function __construct(
  private HttpClientInterface $http,
  private string $apiKey,
  ) {}

  public function solveRecaptchaV2(string $siteKey, string $pageUrl): string
  {
  $r = $this->http->request('POST', 'https://2captcha.com/in.php', [
  'body' => [
  'key' => $this->apiKey,
  'method' => 'userrecaptcha',
  'googlekey' => $siteKey,
  'pageurl' => $pageUrl,
  'json' => 1,
  ],
  ])->toArray();
  if ($r['status'] !== 1) throw new \RuntimeException($r['request']);
  $taskId = $r['request'];

  for ($i = 0; $i < 24; $i++) {
  sleep(5);
  $r = $this->http->request('GET', 'https://2captcha.com/res.php', [
  'query' => ['key' => $this->apiKey, 'action' => 'get', 'id' => $taskId, 'json' => 1],
  ])->toArray();
  if ($r['status'] === 1) return $r['request'];
  if ($r['request'] !== 'CAPCHA_NOT_READY') throw new \RuntimeException($r['request']);
  }
  throw new \RuntimeException('timeout');
  }
}

Same pattern as Python. Register as a Symfony service, inject anywhere needed.

Optimization tips

  1. Submit captcha solves asynchronously. Don't block the scraper waiting; queue the captcha task, work on something else, poll periodically.

  2. Cache solves by site key + IP. If your IP holds a session, sometimes the same captcha token works for multiple requests. Verify per-site.

  3. Use the cheapest service that meets your accuracy requirement. Higher accuracy isn't always needed. Test 2-3 services with your target's CAPTCHAs.

  4. Pre-warm sessions. A logged-in user with a long session may not need to solve CAPTCHA again. Maintain long sessions where possible.

When solvers fail

  • The site uses Enterprise tier (reCAPTCHA Enterprise, hCaptcha Enterprise). Solvers' success rate drops dramatically.
  • The CAPTCHA is invisible and scoring you. No solve helps, you're scored, not gated.
  • The site rotates challenges faster than the solver adapts (rare but happens with bespoke CAPTCHAs).
  • Your IP is denylisted so any solve from your IP fails. Rotate proxies.

For these cases, commercial unblockers (§4.37) are usually a better fit.

Hands-on lab

Pick a site with reCAPTCHA v2 (many exist on signup pages):

  1. Sign up for a 2Captcha free trial (most services offer one).
  2. Write a Python script that solves the captcha and submits the form.
  3. Time the solve. Track success/failure rate over 10 attempts.

You'll feel both the cost and the latency. The exercise informs when solving is the right call vs avoidance.

Quiz, check your understanding

Pass mark is 70%. Pick the best answer; you’ll see the explanation right after.

Third-Party Solvers: 2Captcha, CapSolver, Anti-Captcha1 / 8

Which API pattern do major CAPTCHA solvers (2Captcha, CapSolver, Anti-Captcha) use?

Score so far: 0 / 0