لا تحتاج إلى حفظ كل رمز خطأ يعيده CaptchaAI؛ يكفي أن تعرف الفئة التي ينتمي إليها الخطأ، لأن الفئة — لا الاسم الحرفي — هي التي تحدد إن كنت ستُصلح الطلب أم تعيد المحاولة أم تتوقف. تعيد واجهة CaptchaAI أخطاءها من نقطتَي نهاية فقط: in.php لحظة إرسال المهمة، وres.php لحظة استطلاع النتيجة، ومعرفة أيّهما أصدر الخطأ تختصر نصف طريق التشخيص.
عند تمرير json=1 في الطلب، تصلك الأخطاء بصيغة JSON:
{"status": 0, "request": "ERROR_CODE_HERE"}
أمّا بدون json=1 فيصلك رمز الخطأ نصاً صريحاً مباشرة: ERROR_CODE_HERE.
صنّف الخطأ أولاً: ست فئات تحدد ردّ فعلك
ضع كل خطأ في إحدى الفئات الست التالية؛ الفئة وحدها تكفي لتقرير الإجراء الصحيح:
| فئة الخطأ | أمثلة | ما تفعله |
|---|---|---|
| مصادقة وحساب | ERROR_WRONG_USER_KEY، ERROR_KEY_DOES_NOT_EXIST، IP_BANNED |
أوقف الإرسال، صحّح بيانات الاعتماد، ولا تُعد المحاولة آلياً |
| انشغال الخيوط أو الرصيد | ERROR_ZERO_BALANCE |
انتظر تحرّر خيط تنفيذ أو ارفع خطتك، ثم أعد الإرسال |
| معلمات وتنسيق | ERROR_PAGEURL، ERROR_WRONG_GOOGLEKEY، ERROR_BAD_TOKEN_OR_PAGEURL، ERROR_BAD_PARAMETERS |
أصلح الطلب أولاً؛ إعادة إرسال الطلب نفسه بلا فائدة |
| أخطاء عابرة من الخادم | ERROR_SERVER_ERROR، ERROR_INTERNAL_SERVER_ERROR |
أعد المحاولة بتراجع أسي من 3 إلى 5 مرات |
| خاصة بالمهمة | ERROR_CAPTCHA_UNSOLVABLE، ERROR_PROXY_CONNECTION_FAILED |
أرسل مهمة جديدة بمعلمات محدّثة، لا نفس المعرّف |
| استطلاع النتيجة | CAPCHA_NOT_READY |
ليست خطأً؛ واصل الاستطلاع كل 5 ثوانٍ حتى المهلة |
أخطاء المصادقة والحساب
تظهر قبل أن يبدأ الحل، وتعني رفض الطلب لسبب في المفتاح أو الحساب أو الخيوط المتاحة، والعلاج إصلاح بيانات الاعتماد لا تكرار الطلب.
ERROR_WRONG_USER_KEY
السبب: قيمة المعلمة key بتنسيق غير صحيح. مفاتيح CaptchaAI API تتكوّن من 32 حرفاً بالضبط.
الإصلاح:
- تحقّق أن طول المفتاح 32 حرفاً تماماً.
- تأكّد من خلوّه من أي مسافات زائدة أو فواصل أسطر.
- انسخ المفتاح مباشرةً من لوحة مفاتيح الـ API دون أي تعديل يدوي.
مثال على مفتاح خاطئ يحمل مسافة زائدة في نهايته:
{
"key": "abc123... "
}
والصيغة الصحيحة لمفتاح مكتمل بلا مسافات:
{
"key": "abc12345678901234567890123456789a"
}
ERROR_KEY_DOES_NOT_EXIST
السبب: مفتاح الـ API لا يطابق أي حساب مسجّل في النظام.
الإصلاح:
- سجّل الدخول إلى captchaai.com وانسخ المفتاح من لوحة التحكم مجدداً.
- تأكّد من أنك تستخدم مفتاح الحساب الصحيح، لا مفتاح حساب اختباري قديم.
- إن كنت قد أنشأت الحساب للتو، فامنح المفتاح بضع دقائق حتى يُفعَّل قبل أول طلب.
ERROR_ZERO_BALANCE
السبب: لا يتوفّر في حسابك خيط تنفيذ (thread) حرّ لاستقبال المهمة. لاحظ أن هذا لا يعني بالضرورة نفاد الرصيد.
الإصلاح:
- انتظر حتى تنتهي المهام قيد التشغيل، فيتحرّر خيط جديد.
- ارفع خطتك للحصول على عدد أكبر من الخيوط المتزامنة.
- تحقّق من حالة حسابك عبر صفحة الـ API.
ليس هذا دائماً خطأ "نفاد رصيد". قد يعني ببساطة أن كل خيوطك مشغولة الآن؛ فإن كنت على خطة بخيط واحد ومهمة قيد التنفيذ، ستُعيد كل عمليات الإرسال الجديدة هذا الرمز حتى تكتمل المهمة الأولى.
IP_BANNED
السبب: حُظر عنوان IP الخاص بك مؤقتاً بعد محاولات مصادقة فاشلة متكرّرة.
الإصلاح: انتظر نحو 5 دقائق ثم أعد المحاولة ببيانات الاعتماد الصحيحة. لا تستمر في إرسال الطلبات بمفاتيح API خاطئة، فذلك يطيل الحظر.
أخطاء المعلمات ومفتاح الموقع
الطلب وصل بالفعل، لكنه يحمل معلمات ناقصة أو غير متطابقة مع الصفحة المستهدفة؛ والحل تصحيحه لا تكراره كما هو.
ERROR_PAGEURL
السبب: المعلمة pageurl مفقودة أو فارغة. هذه المعلمة إلزامية لكل اختبارات CAPTCHA المبنية على الرمز مثل reCAPTCHA وCloudflare Turnstile وGeeTest.
الإصلاح: مرّر العنوان الكامل للصفحة التي يُحمَّل عليها اختبار CAPTCHA، متضمناً البروتوكول. قيمة خاطئة (فارغة):
{
"pageurl": ""
}
قيمة صحيحة تحمل البروتوكول والمسار كاملاً:
{
"pageurl": "https://example.com/login"
}
ERROR_WRONG_GOOGLEKEY / ERROR_GOOGLEKEY
السبب: قيمة googlekey (مفتاح الموقع) فارغة أو مشوّهة أو مفقودة.
الإصلاح:
- أعد استخراج مفتاح الموقع من السمة
data-sitekeyفي الصفحة المستهدفة، أو من المعلمةkفي رابط reCAPTCHA. - تأكّد من أن القيمة غير فارغة وغير مقطوعة قبل الإرسال.
مفتاح موقع فارغ يسبّب الخطأ:
{
"googlekey": ""
}
ومفتاح موقع صحيح بالطول المتوقّع:
{
"googlekey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
}
ERROR_BAD_TOKEN_OR_PAGEURL
السبب: تركيبة googlekey (مفتاح الموقع) مع pageurl غير صالحة؛ أي أن مفتاح الموقع غير مسجّل لعنوان الصفحة الذي أرسلته.
الأسباب الشائعة:
- عنصر reCAPTCHA مُحمَّل داخل إطار iframe على نطاق فرعي مختلف، وأنت تمرّر عنوان الصفحة الأم بدل عنوان الـ iframe.
- مفتاح الموقع يخصّ صفحة أو نطاقاً آخر.
- استُخرج مفتاح الموقع من بيئة تطوير أو staging لا من صفحة الإنتاج.
الإصلاح:
- إن كان reCAPTCHA داخل iframe، فاستخدم عنوان
srcالخاص بالـ iframe قيمةً لـpageurl. - تحقّق من مفتاح الموقع من صفحة الإنتاج المباشرة نفسها.
- اختبر القيمتين معاً بتحميل رابط reCAPTCHA يدوياً:
https://www.google.com/recaptcha/api2/anchor?k=YOUR_SITEKEY
ERROR_BAD_PARAMETERS
السبب: معلمات إلزامية مفقودة أو بأنواع بيانات خاطئة.
الإصلاح: راجع وثائق الـ API الخاصة بنوع الاختبار الذي تحلّه، وتأكّد من وجود كل المعلمات المطلوبة له:
| نوع التحقق | المعلمات المطلوبة |
|---|---|
| reCAPTCHA v2/v3 | key، method=userrecaptcha، googlekey، pageurl |
| Cloudflare Turnstile | key، method=turnstile، sitekey، pageurl |
| Cloudflare Challenge | key، method=cloudflare_challenge، pageurl، proxy، proxytype |
| GeeTest v3 | key، method=geetest، gt، challenge، pageurl |
| BLS | key، method=bls، body، textinstructions |
| عادي/صورة | key، method=post، file أو body |
أخطاء الخادم العابرة
الفئة الوحيدة التي تستحق إعادة المحاولة الآلية، لأن سببها مؤقت من جانب الخادم لا من طلبك.
ERROR_SERVER_ERROR / ERROR_INTERNAL_SERVER_ERROR
السبب: خطأ عابر من جانب الخادم.
الإصلاح: انتظر 10 ثوانٍ ثم أعد المحاولة، مع تراجع أسي في حال تكرّر الفشل:
import time
retry_delay = 10
for attempt in range(5):
response = submit_captcha()
if response.get("status") == 1:
break
time.sleep(retry_delay)
retry_delay *= 2 # 10s, 20s, 40s, 80s, 160s
أخطاء الصور والملفات المرفوعة
تخصّ اختبارات الصور ورفع الملفات؛ سببها غالباً حجم أو تنسيق أو ترميز غير سليم، وتُصلَح بتعديل الملف قبل إعادة الإرسال.
ERROR_TOO_BIG_CAPTCHA_FILESIZE
السبب: حجم الصورة المرسلة أكبر من الحد الأقصى المسموح به.
الإصلاح: اضغط الصورة أو صغّر أبعادها قبل الإرسال. استخدم JPEG للصور الفوتوغرافية وPNG للقطات الشاشة.
ERROR_ZERO_CAPTCHA_FILESIZE
السبب: ملف الصورة أصغر من اللازم (أقل من 100 بايت)، ما يشير إلى تحميل فارغ أو تالف.
الإصلاح: تأكّد من أنك ترسل بيانات صورة فعلية، لا ملفاً فارغاً ولا سلسلة Base64 مقطوعة.
ERROR_WRONG_FILE_EXTENSION
السبب: امتداد الملف المرسل غير مدعوم. الامتدادات المدعومة: jpg وjpeg وpng وgif.
الإصلاح: حوّل الصورة إلى أحد التنسيقات المدعومة قبل التحميل.
ERROR_IMAGE_TYPE_NOT_SUPPORTED
السبب: تعذّر على الخادم تحديد نوع الصورة من محتوى الملف نفسه.
الإصلاح: حوّل الصورة إلى تنسيق قياسي (PNG أو JPEG) وتأكّد من سلامتها.
ERROR_UPLOAD
السبب: لم يتمكّن الخادم من قراءة الملف المرفوع أو حمولة Base64.
الإصلاح:
- عند رفع ملف: راجع ترميز بيانات النموذج متعدد الأجزاء (multipart).
- عند إرسال base64: تأكّد من اكتمال السلسلة وصحّة ترميزها.
- جرّب صورة معروفة السلامة لاستبعاد تلف الملف.
أخطاء الوسيط (Proxy)
ترتبط بالخادم الوسيط الذي تمرّره، وتظهر عند الإرسال أو أثناء محاولة الوصول إلى الموقع المستهدف عبره.
ERROR_BAD_PROXY
السبب: الخادم الوسيط الذي مرّرته غير قابل للوصول، أو صنّفه النظام على أنه رديء.
الإصلاح:
- اختبر الوسيط بمعزل عن CaptchaAI — هل يصل فعلاً إلى الموقع المستهدف؟
- جرّب وسيطاً مختلفاً.
- تحقّق من التنسيق:
login:password@IP:PORTأوIP:PORTللوسطاء المصادَق عليهم بعنوان IP.
استخدام الوسيط يجب أن يكون مفعّلاً على حسابك أولاً؛ تواصل مع دعم CaptchaAI إن لم تفعّله بعد.
ERROR_PROXY_CONNECTION_FAILED
السبب: تعذّر على الخدمة الوصول إلى الموقع المستهدف عبر الوسيط الخاص بك.
الإصلاح:
- قد يكون الوسيط معطّلاً مؤقتاً — جرّب خادماً آخر.
- قد يكون الموقع المستهدف يحظر عنوان IP للوسيط.
- تأكّد من أن الوسيط قادر فعلاً على الوصول إلى الموقع المستهدف.
أخطاء استطلاع النتيجة على res.php
تظهر عند الاستفسار عن حالة مهمة أرسلتها، ومعظمها لا يستدعي القلق ما دمت تستطلع بالمعرّف الصحيح.
CAPCHA_NOT_READY
هذا ليس خطأً. إنه يعني أن الحل ما زال قيد التنفيذ.
الإجراء: انتظر 5 ثوانٍ ثم استطلع النتيجة مجدداً.
if result.get("request") == "CAPCHA_NOT_READY":
time.sleep(5)
continue # poll again
دليل التوقيت المقترح لأول استطلاع:
| نوع التحقق | أول استطلاع بعد | فاصل الاستطلاع |
|---|---|---|
| reCAPTCHA v2/v3/Enterprise | 15 ثانية | 5 ثوانٍ |
| Cloudflare Turnstile | 15 ثانية | 5 ثوانٍ |
| Cloudflare Challenge | 20 ثانية | 5 ثوانٍ |
| GeeTest v3 | 15 ثانية | 5 ثوانٍ |
| عادي/صورة | 5 ثوانٍ | 5 ثوانٍ |
ERROR_EMPTY_ACTION
السبب: المعلمة action مفقودة أو فارغة في طلب الاستطلاع.
الإصلاح: أضف action=get إلى طلب res.php:
params = {
"key": api_key,
"action": "get", # Required
"id": captcha_id,
"json": 1,
}
ERROR_CAPTCHA_UNSOLVABLE
السبب: لم يتمكّن CaptchaAI من حل الاختبار بعد عدة محاولات.
الأسباب الشائعة:
- نوع CAPTCHA غير مدعوم أو المعلمات خاطئة.
- التحدي تالف أو منتهي الصلاحية.
- في الحلول المعتمدة على وسيط: الوسيط بطيء جداً أو متعذّر الوصول.
- غيّر الموقع طريقة تطبيقه لاختبار CAPTCHA.
الإصلاح:
- تحقّق من صحة معلماتك (مفتاح الموقع، عنوان الصفحة، الطريقة).
- أعد الإرسال بطلب جديد.
- إن كنت تستخدم وسيطاً، فجرّب وسيطاً مختلفاً.
- إن استمر الخطأ، فقد يكون الموقع قد تغيّر — أعد استخراج مفتاح الموقع وعنوان الصفحة.
لا تعِد المحاولة بنفس معرّف المهمة. أرسل مهمة جديدة بمعلمات محدّثة.
ERROR_WRONG_ID_FORMAT
السبب: معرّف الاختبار يجب أن يكون رقمياً فقط.
الإصلاح: تأكّد من أنك ترسل المعرّف الدقيق الذي أعاده in.php (أرقام فقط، دون أي أحرف إضافية).
ERROR_WRONG_CAPTCHA_ID
السبب: معرّف المهمة غير موجود أو انتهت صلاحيته.
الإصلاح:
- تأكّد من أنك تستطلع بالمعرّف الذي أعاده إرسالك، لا بمعرّف آخر.
- قد تنتهي صلاحية المعرّفات بعد فترات طويلة — أعد الإرسال إن كانت المهمة قديمة جداً.
ملاحظة: قد يظهر ERROR_WRONG_USER_KEY وERROR_KEY_DOES_NOT_EXIST على res.php بنفس سبب وإصلاح فئة المصادقة أعلاه.
سيناريو واقعي: ERROR_ZERO_BALANCE أثناء ذروة الجمعة البيضاء
تخيّل فريق بيانات في القاهرة يراقب أسعار المنافسين قبيل الجمعة البيضاء. مع ارتفاع وتيرة جمع البيانات، بدأت طلبات الإرسال تُعيد ERROR_ZERO_BALANCE رغم أن الرصيد الشهري لم ينفد. السبب أن الفريق على خطة BASIC ($15 شهرياً، 5 خيوط)، وكانت الخيوط الخمسة جميعها مشغولة، فلم يبقَ خيط حرّ للمهمة الجديدة.
الحل ليس شراء رصيد، لأن CaptchaAI يحاسب على أساس الخيوط المتزامنة لا على كل عملية حل، مع حلول غير محدودة لكل خيط. أمام الفريق خياران: قائمة انتظار مع تراجع أسي حتى يتحرّر خيط، أو الترقية إلى خطة أعلى مثل ADVANCE ($90 شهرياً، 50 خيطاً) قبل الذروة. القاعدة: عامِل ERROR_ZERO_BALANCE إشارةَ تزامن قبل أن تعامله إشارةَ رصيد.
قالب جاهز لمعالجة أخطاء CaptchaAI
انسخ النمط التالي لتغليف الإرسال والاستطلاع بمعالجة أخطاء متينة؛ فهو يفصل الأخطاء التي تُصلَح مرة واحدة عن القابلة لإعادة المحاولة، ويطبّق التراجع الأسي تلقائياً.
بايثون
import time
import requests
API_KEY = "YOUR_API_KEY"
SUBMIT_URL = "https://ocr.captchaai.com/in.php"
RESULT_URL = "https://ocr.captchaai.com/res.php"
# Errors that should not be retried (fix the request first)
NO_RETRY_ERRORS = {
"ERROR_WRONG_USER_KEY",
"ERROR_KEY_DOES_NOT_EXIST",
"ERROR_PAGEURL",
"ERROR_WRONG_GOOGLEKEY",
"ERROR_GOOGLEKEY",
"ERROR_BAD_TOKEN_OR_PAGEURL",
"ERROR_BAD_PARAMETERS",
"ERROR_WRONG_FILE_EXTENSION",
"ERROR_IMAGE_TYPE_NOT_SUPPORTED",
"IP_BANNED",
}
# Errors that can be retried
RETRY_ERRORS = {
"ERROR_ZERO_BALANCE",
"ERROR_SERVER_ERROR",
"ERROR_INTERNAL_SERVER_ERROR",
"ERROR_UPLOAD",
}
def solve_captcha(submit_data, max_retries=3, max_polls=60):
"""Submit and solve a CAPTCHA with full error handling."""
# Submit with retry logic
for attempt in range(max_retries):
resp = requests.post(SUBMIT_URL, data={**submit_data, "json": 1}, timeout=30)
resp.raise_for_status()
data = resp.json()
if data.get("status") == 1:
captcha_id = data["request"]
break
error = data.get("request", "UNKNOWN")
if error in NO_RETRY_ERRORS:
raise ValueError(f"Fatal error (fix request): {error}")
if error in RETRY_ERRORS and attempt < max_retries - 1:
time.sleep(10 * (2 ** attempt))
continue
raise RuntimeError(f"Submit failed: {error}")
else:
raise RuntimeError("Submit failed after max retries")
# Poll for result
time.sleep(15)
for _ in range(max_polls):
resp = requests.get(
RESULT_URL,
params={"key": API_KEY, "action": "get", "id": captcha_id, "json": 1},
timeout=30,
)
data = resp.json()
if data.get("request") == "CAPCHA_NOT_READY":
time.sleep(5)
continue
if data.get("status") == 1:
return data["request"]
error = data.get("request", "UNKNOWN")
if error == "ERROR_CAPTCHA_UNSOLVABLE":
raise RuntimeError("CAPTCHA unsolvable — resubmit with fresh parameters")
raise RuntimeError(f"Poll error: {error}")
raise TimeoutError("Solve timed out")
Node.js
const NO_RETRY_ERRORS = new Set([
"ERROR_WRONG_USER_KEY",
"ERROR_KEY_DOES_NOT_EXIST",
"ERROR_PAGEURL",
"ERROR_WRONG_GOOGLEKEY",
"ERROR_BAD_TOKEN_OR_PAGEURL",
"ERROR_BAD_PARAMETERS",
"IP_BANNED",
]);
async function solveCaptcha(submitData, maxRetries = 3, maxPolls = 60) {
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
// Submit with retry
let captchaId;
for (let attempt = 0; attempt < maxRetries; attempt++) {
const resp = await fetch("https://ocr.captchaai.com/in.php", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({ ...submitData, json: "1" }),
});
const data = await resp.json();
if (data.status === 1) {
captchaId = data.request;
break;
}
if (NO_RETRY_ERRORS.has(data.request)) {
throw new Error(`Fatal error: ${data.request}`);
}
if (attempt < maxRetries - 1) {
await sleep(10_000 * 2 ** attempt);
continue;
}
throw new Error(`Submit failed: ${data.request}`);
}
// Poll for result
await sleep(15_000);
for (let i = 0; i < maxPolls; i++) {
const resp = await fetch(
`https://ocr.captchaai.com/res.php?${new URLSearchParams({
key: submitData.key,
action: "get",
id: captchaId,
json: "1",
})}`
);
const data = await resp.json();
if (data.request === "CAPCHA_NOT_READY") {
await sleep(5_000);
continue;
}
if (data.status === 1) return data.request;
throw new Error(`Poll error: ${data.request}`);
}
throw new Error("Solve timed out");
}
أسئلة شائعة حول رموز أخطاء CaptchaAI
ما الفرق بين ERROR_ZERO_BALANCE ونفاد الرصيد فعلياً؟
ERROR_ZERO_BALANCE يعني غياب خيط تنفيذ حرّ في اللحظة الحالية، وقد يحدث مع رصيد كامل إذا كانت كل خيوطك مشغولة. إن كانت كلها قيد الاستخدام فالمشكلة تزامن لا رصيد، والحل الانتظار حتى يتحرّر خيط أو الترقية لخطة بخيوط أكثر.
لماذا يظهر ERROR_BAD_TOKEN_OR_PAGEURL رغم أن مفتاح الموقع صحيح؟
غالباً لأن reCAPTCHA مُحمَّل داخل iframe على نطاق فرعي مختلف، فتمرّر عنوان الصفحة الأم بدل عنوان الـ iframe. استخدم عنوان src الخاص بالـ iframe قيمةً لـ pageurl، وتأكّد أن المفتاح من صفحة الإنتاج.
متى أتوقف عن استطلاع res.php وأعتبر المهمة فاشلة؟
ابدأ أول استطلاع بعد الفاصل المذكور في جدول التوقيت، ثم كل 5 ثوانٍ. اضبط حداً أقصى للمحاولات (مثلاً 60) واعتبر المهمة منتهية المهلة بعده، بدل استطلاع لانهائي يستهلك الخيوط.
هل أعيد استخدام نفس معرّف المهمة بعد ERROR_CAPTCHA_UNSOLVABLE؟
لا. أرسل مهمة جديدة بمعلمات محدّثة، فالمعرّف السابق مرتبط بمحاولة فاشلة نهائياً. إن تكرّر، فراجع مفتاح الموقع وعنوان الصفحة وتأكّد أن نوع الاختبار مدعوم.
كيف أتحقق من رصيدي وعدد الخيوط المتاحة؟
سجّل الدخول إلى لوحة التحكم ثم افتح صفحة الـ API، حيث يظهر رصيدك وحالة خيوطك. راجعها قبل موجات الإرسال الكبيرة لتتجنّب مفاجأة ERROR_ZERO_BALANCE وقت الذروة.