Captcha bypass tutorials

Was this helpful?

How to fix the most common captcha API integration errors

Gregory Fisher
Gregory Fisher

Technical engineer

Almost every integration hits the same handful of walls, usually in the first week. You copy the example code, swap in your API key, run it — and get an error that doesn't match anything in the quick-start guide. Most of the time it's not a bug in the SDK, it's one of a small set of recurring mistakes that are easy to fix once you know what's actually going wrong.

Here are the ten we see most often, roughly in the order people run into them.

1. Wrong or missing API key

You'll see this as ERROR_WRONG_USER_KEY or ERROR_KEY_DOES_NOT_EXIST. Nine times out of ten it's a copy-paste issue — an extra space at the end of the key, quotes accidentally included, or a key from the wrong account (test vs. production, or a teammate's key that got shared in Slack and pasted with a trailing newline). Print the key right before you send the request and compare its length to what's shown in your account dashboard. If it still doesn't match, just generate a new one and swap it in.

2. Zero balance

ERROR_ZERO_BALANCE means exactly what it says — there's no money left on the account to pay for solves. This one's simple to fix, but it trips people up in production because a script that was working fine suddenly starts failing with no code changes at all. Worth setting up a balance alert or checking it periodically if you're running anything unattended, so this doesn't surprise you at 3am.

3. ERROR_CAPTCHA_UNSOLVABLE

This means the captcha genuinely couldn't be solved — not a bug on your end, but usually a data quality problem. For image-based captchas, this often comes from a cropped or corrupted screenshot, a captcha image that expired before it got sent, or a base64 encoding step that mangled the image. For token-based captchas like reCAPTCHA or Turnstile, it can mean the sitekey or page URL you sent don't actually match a live, working captcha widget. Double-check what you're sending matches exactly what's rendered on the page.

4. Wrong sitekey

Related to the above but common enough to call out separately. People often grab the wrong sitekey when a page has more than one captcha widget, or they pull a sitekey from a cached version of the page that's since changed. Always extract the sitekey fresh, right before you use it, straight from the live page's data-sitekey attribute or the network request that loads the widget — never hardcode one from an earlier session.

5. Polling too fast or timing out

If you're polling for a result yourself instead of using an SDK method that handles it, hammering the result endpoint every second or two usually just wastes requests — captchas typically take 10 to 20 seconds to solve, sometimes longer for harder types. Poll every 5 seconds or so, and give it a reasonable timeout (a minute or two, not five seconds) before you decide something's actually broken. Most SDKs handle this polling loop for you, so if you're writing it by hand, ask whether you actually need to.

6. Token received, but the form still rejects it

This is almost always one of two things: the token got set on the wrong input field, or the site expects its JavaScript callback function to fire and you only set the input value without calling it. Check the widget's data-callback attribute (or its render() call in the page's source) to find the right function name, and call it directly with the token instead of — or in addition to — setting the hidden input.

7. Works fine locally, fails on the server

Same code, same key, different result — this one's rarely about the API itself. It's almost always the server's IP. Datacenter IPs get flagged by a lot of anti-bot systems long before a captcha even loads, which either triggers a harder challenge or blocks the request outright. If your local machine passes and your server doesn't, try routing the server through a residential or mobile proxy and see if that changes anything.

8. Token expired before you used it

Solved tokens don't last forever — reCAPTCHA tokens are good for about two minutes, and other types have their own limits. If there's a long gap between getting the token and submitting the form (waiting on other steps, retry logic, slow page loads), the token can go stale before it's ever used. Keep the time between "get token" and "submit form" as short as you can, and if a submission fails, get a fresh token rather than reusing the old one.

9. Pingback or webhook not firing

If you've set up pingback so the API notifies your server when a captcha is solved instead of you polling for it, and nothing's arriving, check the callback URL is actually reachable from the public internet — not localhost, not an internal-only address. Firewalls and NAT are the usual suspects here. A quick way to confirm: hit the URL yourself from an external tool and make sure it responds the way you expect.

10. Rate limited under load

Send too many requests at once and you'll run into ERROR_NO_SLOT_AVAILABLE or similar throttling. This shows up mostly when scaling up a script that worked fine at low volume. The fix is usually to add a queue or a concurrency limit on your end rather than firing everything at once — spread requests out instead of blasting them in parallel, and back off and retry if you do get throttled.

When none of this matches your error

Error codes cover a lot more ground than what's listed here — the full table with every code and a one-line explanation lives in the API documentation. It's worth bookmarking, since new integrations tend to surface at least one error that isn't covered above.