EndCaptcha uses a SOAP/XML-based API with unique method names. CaptchaAI uses a simpler REST API with in.php/res.php endpoints. This guide maps every EndCaptcha call to its CaptchaAI equivalent.
API Architecture Difference
| Aspect | EndCaptcha | CaptchaAI |
|---|---|---|
| Protocol | SOAP/XML or HTTP POST | HTTP POST/GET (REST) |
| Submit | /Captcha/Upload or WSDL |
https://ocr.captchaai.com/in.php |
| Result | /Captcha/GetText or WSDL |
https://ocr.captchaai.com/res.php |
| Auth | Username + Password | API key |
| Response | XML/custom | JSON (json=1) or plain text |
Parameter Mapping
| EndCaptcha Parameter | CaptchaAI Parameter | Notes |
|---|---|---|
username |
key |
CaptchaAI uses single API key |
password |
— | Not needed; API key covers auth |
captchaData (base64) |
body (base64) |
Same base64 image data |
captchaType |
method |
Different type identifiers |
siteKey |
googlekey |
For reCAPTCHA types |
pageUrl |
pageurl |
Same concept, different casing |
captchaId |
id |
Task ID for polling |
CAPTCHA Type Mapping
| EndCaptcha Type | CaptchaAI Method | CaptchaAI Parameters |
|---|---|---|
| Image CAPTCHA | method=base64 |
body={base64_image} |
| reCAPTCHA v2 | method=userrecaptcha |
googlekey, pageurl |
| reCAPTCHA v3 | method=userrecaptcha |
googlekey, pageurl, version=v3, action, min_score |
| hCaptcha | method=hcaptcha |
sitekey, pageurl |
Code Migration
Python — Before (EndCaptcha)
import requests
USERNAME = "your_endcaptcha_user"
PASSWORD = "your_endcaptcha_pass"
def solve_image_endcaptcha(image_base64):
# EndCaptcha image solve
resp = requests.post("https://api.endcaptcha.com/Captcha/Upload", data={
"username": USERNAME,
"password": PASSWORD,
"captchaData": image_base64,
"captchaType": "1"
})
result = resp.json()
captcha_id = result.get("captchaId")
import time
for _ in range(30):
time.sleep(5)
poll = requests.post("https://api.endcaptcha.com/Captcha/GetText", data={
"username": USERNAME,
"password": PASSWORD,
"captchaId": captcha_id
})
poll_result = poll.json()
if poll_result.get("text"):
return {"solution": poll_result["text"]}
if poll_result.get("error"):
return {"error": poll_result["error"]}
return {"error": "TIMEOUT"}
Python — After (CaptchaAI)
import os
import time
import requests
API_KEY = os.environ["CAPTCHAAI_API_KEY"]
def solve_image_captchaai(image_base64):
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "base64",
"body": image_base64,
"json": 1
})
data = resp.json()
if data.get("status") != 1:
return {"error": data.get("request")}
captcha_id = data["request"]
for _ in range(30):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": captcha_id,
"json": 1
}).json()
if result.get("status") == 1:
return {"solution": result["request"]}
if result.get("request") != "CAPCHA_NOT_READY":
return {"error": result.get("request")}
return {"error": "TIMEOUT"}
Python — reCAPTCHA v2 (CaptchaAI)
def solve_recaptcha_v2(sitekey, pageurl):
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"json": 1
})
data = resp.json()
if data.get("status") != 1:
return {"error": data.get("request")}
captcha_id = data["request"]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get",
"id": captcha_id, "json": 1
}).json()
if result.get("status") == 1:
return {"solution": result["request"]}
if result.get("request") != "CAPCHA_NOT_READY":
return {"error": result.get("request")}
return {"error": "TIMEOUT"}
JavaScript — Before (EndCaptcha)
const axios = require("axios");
const USERNAME = "your_endcaptcha_user";
const PASSWORD = "your_endcaptcha_pass";
async function solveImageEndCaptcha(imageBase64) {
const submit = await axios.post("https://api.endcaptcha.com/Captcha/Upload", {
username: USERNAME,
password: PASSWORD,
captchaData: imageBase64,
captchaType: "1",
});
const captchaId = submit.data.captchaId;
for (let i = 0; i < 30; i++) {
await new Promise((r) => setTimeout(r, 5000));
const poll = await axios.post("https://api.endcaptcha.com/Captcha/GetText", {
username: USERNAME,
password: PASSWORD,
captchaId,
});
if (poll.data.text) return { solution: poll.data.text };
if (poll.data.error) return { error: poll.data.error };
}
return { error: "TIMEOUT" };
}
JavaScript — After (CaptchaAI)
const axios = require("axios");
const API_KEY = process.env.CAPTCHAAI_API_KEY;
async function solveImageCaptchaAI(imageBase64) {
const submit = await axios.post("https://ocr.captchaai.com/in.php", null, {
params: { key: API_KEY, method: "base64", body: imageBase64, json: 1 },
});
if (submit.data.status !== 1) return { error: submit.data.request };
const captchaId = submit.data.request;
for (let i = 0; i < 30; i++) {
await new Promise((r) => setTimeout(r, 5000));
const poll = await axios.get("https://ocr.captchaai.com/res.php", {
params: { key: API_KEY, action: "get", id: captchaId, json: 1 },
});
if (poll.data.status === 1) return { solution: poll.data.request };
if (poll.data.request !== "CAPCHA_NOT_READY") return { error: poll.data.request };
}
return { error: "TIMEOUT" };
}
Key Differences to Watch
| Area | EndCaptcha | CaptchaAI |
|---|---|---|
| Authentication | Username + password pair | Single API key |
| Error format | Custom JSON with error field |
Standard request field with error codes |
| Polling | POST to separate endpoint | GET to res.php with query params |
| Balance check | Separate SOAP method | res.php?action=getbalance&key=KEY |
| Report bad | Separate method | res.php?action=reportbad&id=ID&key=KEY |
Migration Checklist
| Step | Status |
|---|---|
| Create CaptchaAI account | ☐ |
| Map all EndCaptcha calls to CaptchaAI equivalents | ☐ |
| Replace auth (username/password → API key) | ☐ |
Update submit endpoint (/Captcha/Upload → /in.php) |
☐ |
Update poll endpoint (/Captcha/GetText → /res.php) |
☐ |
| Update response parsing | ☐ |
| Run parallel test with both providers | ☐ |
| Switch production traffic | ☐ |
| Remove EndCaptcha credentials | ☐ |
Troubleshooting
| Issue | Cause | Fix |
|---|---|---|
ERROR_KEY_DOES_NOT_EXIST |
Using EndCaptcha username instead of API key | Use CaptchaAI API key from dashboard |
| Response parsing fails | Different JSON structure | Update to check status and request fields |
Missing method parameter |
EndCaptcha uses captchaType numbering |
Map to CaptchaAI method names (base64, userrecaptcha, etc.) |
| Timeout on reCAPTCHA | Different default timeouts | Set polling to 60 iterations × 5 seconds for token CAPTCHAs |
FAQ
Is the response format the same between EndCaptcha and CaptchaAI?
No. EndCaptcha returns custom JSON with fields like captchaId and text. CaptchaAI returns {"status": 1, "request": "..."}. You'll need to update your response parsing.
Can I use the same proxy configuration?
Yes. CaptchaAI accepts proxy=user:pass@host:port and proxytype=HTTP|SOCKS5 parameters, similar to most CAPTCHA services.
What about EndCaptcha's SOAP/WSDL endpoint?
CaptchaAI doesn't have a SOAP API. The REST API (in.php/res.php) is simpler and widely supported. Most SOAP calls map to a single HTTP POST or GET.
Related Articles
Next Steps
Simplify your CAPTCHA solving with CaptchaAI's REST API — get your API key and migrate today.
Related guides:
Discussions (0)
Join the conversation
Sign in to share your opinion.
Sign InNo comments yet.