Guide

September 25, 2026 · 12 min read

What Is a CAPTCHA? How They Work and How to Get Past One

The puzzle is the last step of a check that started before the page loaded. What modern CAPTCHAs look at, what a block looks like from code, why a retry with a fresh identity clears most of them, and when a solving service is the right tool.

Adam Ben-Ayoun

Adam Ben-Ayoun

CTO, OpenWeb Ninja

CAPTCHA · Anti-Bot · Web Scraping

Illustration of a reCAPTCHA image challenge in a browser window, with a bot flagged and a person passing, the signals a site checks, and an HTTP 403 captcha response

What a CAPTCHA is

A CAPTCHA is a test a website uses to decide whether a visitor is a person or a program. The name is an acronym: Completely Automated Public Turing test to tell Computers and Humans Apart. It was coined in 2000 by Luis von Ahn, Manuel Blum, Nicholas Hopper and John Langford at Carnegie Mellon University, and the first versions asked you to read distorted text that software of the time could not.

That premise did not last. A 2023 study from UC Irvine, presented at USENIX Security, measured 1,400 people solving the CAPTCHAs on popular websites and compared them with published bot results. Humans took 9 to 15 seconds on distorted text and got it right 50 to 84% of the time. Bots answered in under a second at 99.8%.

So the modern CAPTCHA is less a puzzle and more a risk check. By the time you see a checkbox or a grid of traffic lights, the site has already scored your connection, your browser and your session. The puzzle is what happens when the score comes back low. Most visitors never see one at all.

In one line: a CAPTCHA is a gate that opens for visitors a site trusts and asks everyone else for proof. Getting past it is mostly about looking trustworthy, and only sometimes about answering the question.

The main types of CAPTCHA

The list below runs roughly from oldest to newest. What they have in common in 2026 is that almost all of them return a token or cookie when you pass, and the website checks that token on its server before it lets the request through.

TypeExamplesWhat the visitor doesWhat passing produces
Text and image recognitionDistorted characters, "type the word"Reads and typesA form field value
CheckboxreCAPTCHA v2 "I’m not a robot"Clicks; a grid follows only if the score is lowg-recaptcha-response token
Image gridreCAPTCHA v2 challenge, hCaptchaSelects the squares with buses, bikes, crosswalksToken
Score-based, invisiblereCAPTCHA v3, reCAPTCHA EnterpriseNothing. The site gets a score from 0.0 (bot) to 1.0 (human) and picks its own threshold; Google suggests starting at 0.5Token plus score
Browser challengeCloudflare Turnstile, Cloudflare challenge pages, AWS WAF ChallengeUsually nothing: the page runs small JavaScript checks (proof of work, browser API probes) and sometimes shows a checkboxToken, or a clearance cookie such as cf_clearance or aws-waf-token
Puzzle and sliderGeeTest, Arkose LabsDrags a piece, rotates an image, picks an iconToken
Proof of workFriendly CaptchaNothing: the device solves a small computationToken
AudioThe accessibility fallback on most of the aboveListens and typesSame token as the visual version
Device attestationPrivate Access Tokens (iOS 16, macOS 13 and later)Nothing: the operating system vouches for the deviceA signed token, no puzzle

The direction is clear: less puzzle, more background check. Cloudflare estimated in 2021 that the average CAPTCHA took a person 32 seconds, which across the web added up to about 500 human years lost every day. The invisible types exist to get that number close to zero for trusted visitors.

What the invisible score looks at

Vendors do not publish their models, but their documentation names the inputs, and they fall into five groups:

  • IP reputation. Datacenter ranges, addresses with recent abuse, and heavily shared exits score lower than a home connection.
  • Request pattern. How many requests, how fast, how evenly spaced, and whether they skip the pages a person would load first.
  • Browser fingerprint. Headers, TLS handshake, JavaScript APIs, canvas rendering, and the telltale properties of automated browsers. Turnstile describes its checks as proof of work, probing for web APIs and detecting browser quirks.
  • Session history. Cookies from earlier visits that passed. A session that has behaved well before is trusted more.
  • Behavior. Mouse movement, scrolling, typing rhythm and time on page, where the page can observe them.

Which of these matters most changes from site to site, and that is the practical point for anyone writing code. On some sites the IP and session decide almost everything, and switching HTTP clients changes nothing. On others the TLS handshake of your client is exactly what the check keys on. You find out which lever a site uses by changing one thing at a time.

What a CAPTCHA looks like from code

In a browser a CAPTCHA is obvious. To a script it is just another response, and often not the one you expect. These are block responses we have logged while collecting public data, as they arrive over plain HTTP:

ProtectionStatus codeWhat the body looks like
Google Search302 to /sorry/, then 429An "unusual traffic from your computer network" page with a reCAPTCHA
Cloudflare managed challenge (a job board)403A 38 KB "Security Check" page, a cf-mitigated: challenge header, and no checkbox to click
AWS WAF (a review site)403A 991-byte "Verifying Connection" page that loads a challenge script
Akamai (a large retailer)200A 2.5 KB page reading "Powered and protected by Akamai", with no product data in it
Cloudflare interstitial (many sites)403A page titled Just a moment.... Two of the pages we read while researching this post, including Cloudflare's own explainer on CAPTCHAs, answered our script this way.

Two lessons come out of that table. First, the status code is not a reliable block signal: the Akamai page is a 200, and code that checks only for 403 will store the challenge page as if it were data. Detect success by the content you expect (a product title, a results container), not by the absence of an error.

Second, the opposite mistake is just as easy. The job board's real results page includes Cloudflare's challenge script on every load, so a check like "page contains challenge-platform" flags good pages as blocked. Match on something that appears only on the block page, such as its title.

Four reasons you get blocked, and what fixes each

Before choosing a fix it helps to know what kind of block you are looking at. They look alike from the outside and respond to completely different treatments.

Kind of blockWhat the site is sayingWhat fixes it
Rate limitThis IP, session or account sent too many requests in a short windowFewer requests per identity: slow down on the same IP, or spread the same volume across more IPs. A limit tied to an account or API key follows you to every IP, so there only waiting helps
ReputationThis IP or session looks automated, whatever its volumeA different identity: new IP, new session. Waiting rarely helps
ChallengeProve you are a browser or a personPassing the challenge: a real browser, or a solving service for the token
AuthenticationThis content needs a signed-in accountA valid session. A solved CAPTCHA will not help

The first two rows are the ones people mix up. A rate limit is a counter: it is kept per IP, session or account, and it resets on its own once that identity sends less. A reputation block is a verdict: even one request from that IP can be refused, and the verdict does not reset in the time a retry waits. Moving to a new IP gets you past both, which is why rotation looks like a universal fix. The difference shows when you cannot rotate, for example behind an account or API key, where only slowing down works.

The last row is easy to miss. On one map service we tested, we minted a valid reCAPTCHA token with the correct site key and sent the same request with and without it. Both got the identical 403: the request was rejected before anything looked at the token. What the endpoint wanted was a signed-in session. Solving the CAPTCHA faster would never have fixed it.

Retries: the first fix, if you retry differently

Most blocks you hit while collecting public data are reputation blocks, and the cheapest way past one is to come back as someone else. That is why a retry works so often, and why a naive retry (same IP, same cookies, a second later) rarely does. A few rules cover most cases:

  • Change the identity, not just the timing. A blocked IP or session tends to stay blocked for a while. A fresh one often passes on the first try.
  • Keep what works. A session that just succeeded is usually the best bet for the next request, so do not rotate it away.
  • Back off only for real rate limits. If errors start above a certain request rate and stop when you slow down, add exponential backoff with jitter. Otherwise waiting mostly costs time.
  • Do not wait out a stuck challenge. A challenge page tends to clear within seconds or not at all. Reload, or start over on a new identity.
  • Cap the attempts. Three or four tries per request keeps a hard block from turning into an endless loop and a large proxy bill.

How much the identity matters: on a job board behind Cloudflare, every exit we tried in one IP range passed, and every exit in another got a challenge page that never resolved, however long we waited. Nothing else about the requests differed.

A retry loop that follows those rules

This is the pattern in about 40 lines of code: detect the block by content, change the exit on every attempt, back off exponentially with jitter, and stop after a fixed number of tries.

# fetch_with_retries.py

import random

import time

 

import requests

 

BLOCK_MARKERS = ("captcha", "unusual traffic", "verify you are human", "just a moment")

 

def looks_blocked(resp):

# A block is not always a 403: challenge pages often come back as 200

if resp.status_code in (403, 429, 503):

return True

head = resp.text[:5000].lower()

return any(marker in head for marker in BLOCK_MARKERS)

 

def fetch(url, proxies, max_attempts=4):

for attempt in range(max_attempts):

proxy = random.choice(proxies) # a new exit per attempt, not the same one again

try:

resp = requests.get(

url,

proxies={"http": proxy, "https": proxy} if proxy else None,

headers={"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "

"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36"},

timeout=15,

)

if not looks_blocked(resp):

return resp

print(f"attempt {attempt + 1}: blocked ({resp.status_code})")

except requests.RequestException as exc:

print(f"attempt {attempt + 1}: {type(exc).__name__}")

time.sleep(2 ** attempt + random.random()) # 1s, 2s, 4s... plus jitter

return None

 

if __name__ == "__main__":

proxies = [None] # replace with your proxy URLs, e.g. "http://user:pass@host:port"

print(fetch("https://httpbin.org/status/429", proxies, max_attempts=3))

ok = fetch("https://httpbin.org/html", proxies)

print(ok.status_code, len(ok.text))

Output, run on September 25, 2026 (the first URL always answers 429, the second is a normal page):

attempt 1: blocked (429)

attempt 2: blocked (429)

attempt 3: blocked (429)

None

200 3739

The marker list is a starting point. For a real target, replace it with a positive check for the element you are after, since a generic keyword list will miss the Akamai-style 200 page above.

When retries are not enough: CAPTCHA solving services

Retries stop working in a few recognizable situations. The challenge appears on every IP you try, including clean residential ones. The page puts a CAPTCHA in front of a specific action, like a search form or a checkout step, no matter who you are. Or your volume is high enough that a pool of fresh identities costs more than proving yourself once. That is where a CAPTCHA solving service fits.

For token-based CAPTCHAs, which is almost all of them now, a solver does not look at your page. It works from two values you give it:

  1. Find the site key and page URL. The site key is public, in the page's HTML as a data-sitekey attribute or in the challenge script's URL.
  2. Submit a task. The service returns a task ID immediately.
  3. Poll for the result. Depending on the type, the answer is ready in a few seconds to about a minute.
  4. Use the token. Put it in the field the site expects (for reCAPTCHA, g-recaptcha-response) and submit the form or request as the page would.

Full-page challenges work differently. For a Cloudflare challenge page, a solver returns a cf_clearance cookie and the User-Agent it was earned with, and both are bound to the IP that solved it. You give the solver your proxy, then send your own requests through that same proxy with that same User-Agent.

How solving services charge

There are two pricing models, and which one is cheaper depends almost entirely on your volume. Most services charge per solve, usually quoted per 1,000, with image CAPTCHAs cheapest and reCAPTCHA or Cloudflare types costing more. You pay for exactly what you use, which suits spiky or low volume.

The other model charges a flat monthly fee for a number of threads, where a thread is one solve in progress at a time, and no per-solve fee. The cost is fixed however many CAPTCHAs you push through, so it gets cheaper per solve the busier you keep it. As a rough guide, at 20 seconds per solve one thread handles about 3 solves a minute, or around 4,300 a day if you keep it busy around the clock.

One option: CaptchaAI

CaptchaAI is a thread-based service that uses automated solving rather than human workers. Every plan includes unlimited solves:

PlanPrice per monthConcurrent threads
Basic$155
Advance$9050
Enterprise$300200

It covers reCAPTCHA v2 and v3 (including Enterprise), Cloudflare Turnstile and challenge pages, GeeTest v3 and image CAPTCHAs, and new accounts can ask support for trial threads.

Special deal for OpenWeb Ninja users: get up to 15% off CaptchaAI. Claim the offer

Use the token quickly. A reCAPTCHA token is valid for about two minutes and only once, so solve right before you submit, not in a batch ahead of time. The same goes for the other types: the AWS WAF token we tested stopped working after about five minutes, and a cf_clearance cookie only works from the IP and User-Agent that earned it.

Choosing an approach

Put together, the order that tends to cost least is: do not trigger the check, then retry with a new identity, then solve. And it is worth asking early whether you need the page at all, or just the data on it.

Your situationA sensible first move
429s that start only above a certain request rateLower the rate per IP: slow down, or spread requests across more IPs, with exponential backoff and jitter on each retry
Blocks that follow an IP or sessionRotate to a new exit and a fresh session on every failure; keep sessions that succeed
A challenge page that clears in a real browserFetch with a real browser, reuse the clearance cookie for as long as it lasts
A CAPTCHA on every identity, or in front of a form you must submitA solving service such as CaptchaAI
A 403 that no token changesCheck whether the content needs a signed-in session; a solver will not help
You need structured data from a site many people already collectA data API that handles the blocks, so there is no CAPTCHA on your side at all

The last row is where we work. Our APIs return structured data from Google, Amazon, Google Maps, job boards and 50+ other sources, and the blocks and retries are handled on our side. For sites we do not cover, the Web Unblocker API fetches any URL through rotating proxies with automatic retries, optional JavaScript rendering, and success and failure selectors so a challenge page is not mistaken for a result. For Google specifically, the Real-Time Web Search API returns results as JSON, and queries run in real time with no caching.

Limitations and responsible use

  • Everything above is about public pages. A CAPTCHA in front of a login, someone else's account or a paywall is a different situation, and getting past it does not change what you are allowed to access.
  • A block is also a signal about load. Keep request rates reasonable, especially on small sites, and back off when a site tells you to.
  • Our numbers come from our own traffic on specific sites and dates. Anti-bot systems change often, and the same site can behave differently a month later. Measure on your own target before building on any figure here, ours included.
  • CAPTCHAs are a known accessibility barrier for people with visual and cognitive impairments, which is part of why the industry is moving to invisible checks. If you run a site, prefer the invisible modes.

FAQ

Can bots solve CAPTCHAs?

+

Yes, and often better than people. A 2023 UC Irvine study published at USENIX Security compared human results with published bot results: distorted-text CAPTCHAs took humans 9 to 15 seconds at 50 to 84% accuracy, while bots solved them in under a second at 99.8%. That is why modern systems score the visitor first and use the puzzle only as a last step.

Why do I get CAPTCHAs when I browse normally?

+

The risk score is mostly about your connection and session, not about you. A VPN or a shared office or mobile IP with a poor reputation, freshly cleared cookies, a privacy extension that blocks the challenge script, or a burst of fast requests can all lower the score enough to trigger a visible challenge.

Should I retry or use a CAPTCHA solver first?

+

Retry first, but retry with a different identity: a new IP, and a new session or cookie jar. In our measurements a blocked session almost never recovered on its own, while a fresh one often passed. Move to a solver when the challenge appears on every identity you try, or when the page requires a token to submit a form.

How long does a solved CAPTCHA token last?

+

Not long. A reCAPTCHA response token is valid for about two minutes and can be verified once. A Cloudflare cf_clearance cookie is bound to the IP and User-Agent that earned it. The AWS WAF token we tested stopped working after about five minutes. Solve close to the moment you submit, and reuse the same proxy and User-Agent.

How much do CAPTCHA solving services cost?

+

There are two pricing models. Most services charge per solve, with different rates per CAPTCHA type. Thread-based services such as CaptchaAI charge a flat monthly fee for a number of simultaneous solves, with no per-solve cost: its Basic plan is $15 a month for 5 threads, and its Enterprise plan $300 a month for 200 threads.

Is it legal to bypass a CAPTCHA?

+

It depends on what you access and where you are. Collecting publicly available data is a long-established practice, but a CAPTCHA does not make data public or private: logins, other people’s accounts and terms you have agreed to still apply. Respect rate limits, do not use solvers to create accounts or abuse forms, and get legal advice for your jurisdiction and use case.

Adam Ben-Ayoun

Written by

Adam Ben-Ayoun

CTO at OpenWeb Ninja

Adam leads engineering at OpenWeb Ninja, building the APIs and infrastructure that make public web data accessible to developers and AI agents.

Connect on LinkedIn

Get the data without the CAPTCHA

50+ real-time data APIs that handle proxies, retries and blocks for you, plus a Web Unblocker for any other URL. Every API has a free plan, no credit card required.

Try the Web Unblocker API