This guide gets you from zero to a solved CAPTCHA as fast as possible. No theory, no deep dives — just the minimum steps to make your first successful API call and get a solved token back.
Every CAPTCHA type CaptchaAI supports follows the same four-step pattern:
- Submit — send the CAPTCHA details to
in.php - Get the task ID — save the ID from the response
- Poll — check
res.phpevery 5 seconds until the result is ready - Use the token — inject the solved token into the target page or request
Step 0: Get your API key
- Sign up at captchaai.com
- Go to your dashboard
- Copy your 32-character API key
You need active threads on your account to submit tasks. Contact support for a free trial if you are evaluating the service.
Step 1: Submit a CAPTCHA
This example solves a reCAPTCHA v2 — the most common type. You need two inputs from the target page:
- sitekey — the public key tied to the reCAPTCHA widget (find it in
data-sitekeyor the anchor URLkparameter) - pageurl — the full URL where the widget loads
cURL
curl -X POST "https://ocr.captchaai.com/in.php" \
-d "key=YOUR_API_KEY" \
-d "method=userrecaptcha" \
-d "googlekey=6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-" \
-d "pageurl=https://example.com/login" \
-d "json=1"
Python
import requests
response = requests.post("https://ocr.captchaai.com/in.php", data={
"key": "YOUR_API_KEY",
"method": "userrecaptcha",
"googlekey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
"pageurl": "https://example.com/login",
"json": 1,
})
print(response.json())
Node.js
const response = await fetch("https://ocr.captchaai.com/in.php", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
key: "YOUR_API_KEY",
method: "userrecaptcha",
googlekey: "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
pageurl: "https://example.com/login",
json: "1",
}),
});
console.log(await response.json());
PHP
<?php
$response = file_get_contents("https://ocr.captchaai.com/in.php?" . http_build_query([
"key" => "YOUR_API_KEY",
"method" => "userrecaptcha",
"googlekey" => "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
"pageurl" => "https://example.com/login",
"json" => 1,
]));
echo $response;
Step 2: Save the task ID
You will receive:
{
"status": 1,
"request": "71823469"
}
The request field is your task ID. Save it — you need it to get the result.
If status is 0, something went wrong. Check the request field for the error code:
| Error | Meaning | Fix |
|---|---|---|
ERROR_WRONG_USER_KEY |
API key format is wrong | Check your 32-character key |
ERROR_KEY_DOES_NOT_EXIST |
API key not found | Verify the key from your dashboard |
ERROR_ZERO_BALANCE |
No available threads | Top up or wait for threads to free |
ERROR_PAGEURL |
Missing pageurl parameter | Add the full page URL |
ERROR_WRONG_GOOGLEKEY |
Sitekey is blank or malformed | Re-extract the sitekey from the page |
Step 3: Poll for the result
Wait 15 seconds, then check every 5 seconds until the result is ready.
cURL
curl "https://ocr.captchaai.com/res.php?key=YOUR_API_KEY&action=get&id=71823469&json=1"
Python
import time
time.sleep(15)
while True:
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": "YOUR_API_KEY",
"action": "get",
"id": "71823469",
"json": 1,
}).json()
if result["request"] == "CAPCHA_NOT_READY":
time.sleep(5)
continue
if result["status"] == 1:
token = result["request"]
print(f"Solved! Token: {token[:60]}...")
break
print(f"Error: {result}")
break
Node.js
await new Promise((r) => setTimeout(r, 15_000));
while (true) {
const result = await fetch(
`https://ocr.captchaai.com/res.php?${new URLSearchParams({
key: "YOUR_API_KEY",
action: "get",
id: "71823469",
json: "1",
})}`
).then((r) => r.json());
if (result.request === "CAPCHA_NOT_READY") {
await new Promise((r) => setTimeout(r, 5_000));
continue;
}
if (result.status === 1) {
console.log(`Solved! Token: ${result.request.slice(0, 60)}...`);
break;
}
console.error("Error:", result);
break;
}
PHP
<?php
sleep(15);
while (true) {
$result = json_decode(file_get_contents("https://ocr.captchaai.com/res.php?" . http_build_query([
"key" => "YOUR_API_KEY",
"action" => "get",
"id" => "71823469",
"json" => 1,
])), true);
if ($result["request"] === "CAPCHA_NOT_READY") {
sleep(5);
continue;
}
if ($result["status"] === 1) {
echo "Solved! Token: " . substr($result["request"], 0, 60) . "...\n";
break;
}
echo "Error: " . json_encode($result) . "\n";
break;
}
When the solve completes, you get:
{
"status": 1,
"request": "03AHJ_Vuve5Asa4koK3KSMyUkCq0vUFCR5Im4CwB7PzO3dCxIo..."
}
The request field is the solved CAPTCHA token.
Step 4: Use the token
For reCAPTCHA v2, inject the token into the g-recaptcha-response field on the target page:
With Selenium (Python):
driver.execute_script(
'document.getElementById("g-recaptcha-response").innerHTML = arguments[0];',
token
)
driver.find_element("css selector", "form").submit()
With Puppeteer (Node.js):
await page.evaluate((token) => {
document.getElementById("g-recaptcha-response").innerHTML = token;
}, token);
await page.click("#submit-button");
Without a browser (HTTP request):
response = requests.post("https://example.com/login", data={
"username": "user@example.com",
"password": "your_password",
"g-recaptcha-response": token,
})
What's next?
You just solved your first CAPTCHA. The same submit → poll → use pattern works for every type CaptchaAI supports. The only differences are the method name and the parameters you send.
| CAPTCHA Type | Method | Key Parameters | Guide |
|---|---|---|---|
| reCAPTCHA v2 | userrecaptcha |
googlekey, pageurl |
Full guide |
| reCAPTCHA v3 | userrecaptcha |
googlekey, pageurl, version=v3 |
Full guide |
| reCAPTCHA v2 Enterprise | userrecaptcha |
googlekey, pageurl, enterprise=1 |
Full guide |
| Cloudflare Turnstile | turnstile |
sitekey, pageurl |
Full guide |
| Cloudflare Challenge | cloudflare_challenge |
pageurl, proxy, proxytype |
Full guide |
| GeeTest v3 | geetest |
gt, challenge, api_server, pageurl |
Full guide |
| BLS Captcha | bls |
body (9 base64 images), textinstructions |
Full guide |
| Normal/image | post |
file or body (base64) |
Full guide |
FAQ
Do I need to change my code for different CAPTCHA types?
Only the method and parameters change. The submit/poll/result flow is identical for every type. Once you have the quickstart pattern working, adapting it for other types takes minutes.
How long does solving take?
Token-based CAPTCHAs (reCAPTCHA, Turnstile, GeeTest) typically solve in 15–60 seconds. Image CAPTCHAs solve in under 10 seconds. Wait 15 seconds before your first poll, then check every 5 seconds.
What does CAPCHA_NOT_READY mean?
It means the solve is still in progress. Wait 5 seconds and poll again. This is normal — not an error.
What if I get ERROR_ZERO_BALANCE?
Your account has no available threads. Either wait for active tasks to complete or upgrade your plan.
Can I use any programming language?
Yes. The API is plain HTTP — any language that can make GET/POST requests works. This guide shows Python, Node.js, PHP, and cURL, but the same calls work in Go, Java, C#, Ruby, or any other language.
Start solving
- Get your API key — captchaai.com/api.php
- Copy any code block above — replace
YOUR_API_KEYwith your key - Replace the sitekey and pageurl — use the values from your target page
- Run it — you will have a solved token in under 60 seconds
For type-specific details, pick your CAPTCHA type from the what's next table and follow the full guide.
Discussions (0)
Join the conversation
Sign in to share your opinion.
Sign InNo comments yet.