مرجع API Endpoints

مرجع لجميع endpoints الخاصة بـ FourA API مع معلمات request وتنسيقات response.

Base URL

https://eu.api.foura.ai/api

المصادقة

يتطلب كل request مفتاح API الخاص بك في header X-API-Key:

curl -X POST https://eu.api.foura.ai/api/single/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"method": "GET", "url": "https://example.com"}'

أنشئ مفاتيح API وأدرها في لوحة التحكم. تستخدم المفاتيح البادئة pk_live_.

ترويسات الاستجابة (Response Headers)

تحمل الاستجابات من /api/* ترويستي ارتباط:

الترويسة القيمة الوصف
X-FourA-Request-Id UUID معرف فريد مخصص للطلب. يُرجع مع كل استجابة، بما في ذلك أخطاء 4xx و 5xx، باستثناء جسم الطلب الذي يتعذر على FourA قراءته تماما: يتم رفض 400 Invalid JSON in request body و 413 قبل تعيين معرف. قم بتسجيله في سجلاتك.
X-FourA-Credits عدد صحيح الرصيد المستهلك في هذا الطلب. يُرجع مع كل استجابة وصلت إلى المحرك، سواء نجحت أو فشلت (تمت معالجة العمل في كلتا الحالتين). المكالمة التي رفضتها FourA قبل تشغيل أي محرك لها (مفتاح مفقود أو غير صالح، حد الخطة أو المنصة، هدف مرفوض أو معرف proxy مرفوض) لا تحمل هذه الترويسة. راجع نتائج الطلبات لمعرفة النتائج الخاضعة للاحتساب.

يُستخدم نفس معرف الطلب للربط بمعاينة حمولة الطلب والاستجابة في سجل النشاط في لوحة التحكم (يُحتفظ بها لمدة 24 ساعة، لآخر 200 طلب لكل مفتاح)، حتى تتمكن من البحث عن الطلب بدقة لاحقا وإعادة تشغيله من سجل النشاط مباشرة في Playground. أرفقه عند التواصل مع الدعم لتحديد موقع الطلب في ثوان.

$ curl -i -X POST https://eu.api.foura.ai/api/single/ \
    -H "X-API-Key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"method": "GET", "url": "https://example.com"}'

HTTP/2 200
content-type: application/json
x-foura-request-id: 8f3e2a14-7b6c-4d1a-9e2f-5a3b8c1d4e7f
x-foura-credits: 2
...

راجع Response Headers للاطلاع على القائمة الكاملة وتلميحات الاستخدام.

Endpoints

هل تستخدم هذه الـ endpoints عبر MCP؟ يوفّر خادم @fouradata/mcp تغليفًا لجميع الـ endpoints الأربعة كأدوات MCP أصلية (foura_auto، foura_single، foura_proxy، foura_browser) بنفس هياكل الإدخال بالإضافة إلى خيار offload_large للتعامل مع الردود الكبيرة بكفاءة من حيث استهلاك الـ tokens.

يوفّر FourA أربعة request endpoints، كل منها مخصّص لسيناريو مختلف:

Endpoint الأنسب لـ
POST /auto/ الجلب الذكي. تقوم بتمرير URL، ويختار FourA المسار الأقل تكلفة الذي ينجح (مباشر، proxy بتدوير تلقائي، أو متصفح) ويتذكر المسار الناجح لكل host.
POST /single/ طلبات HTTP السريعة، الصفحات الثابتة، وواجهات برمجة التطبيقات (APIs)
POST /proxy/ المواقع المحمية مع تدوير تلقائي للـ proxy، وتحديد نطاق الدولة المستهدفة اختياريًا
POST /browser/ الصفحات المعالجة عبر JavaScript، وتطبيقات الصفحة الواحدة (SPAs)
GET /profiles كتالوج ملفات تعريف المتصفح الخاصة بـ single وproxy. عام، ولا يتطلب API key.

للحصول على شرح تفصيلي حول كيفية اختيار كل منها، راجع Choosing the Right Endpoint ودليل Smart Fetch guide.

Target URL Restrictions

تُرفض الأهداف التي تشير إلى نطاقات IP خاصة أو محلية (loopback) أو محجوزة (RFC 5735، RFC 6598، وكتل IPv6 المحجوزة) برمز 400 قبل خروج الـ request من FourA. يتم فقط توجيه أسماء المضيفين وعناوين IP العامة.

{ "error": "Refusing to fetch <target>: target resolves to a private or reserved IP range. The FourA scraping API only forwards requests to public internet hosts." }

Smart Fetch (Auto)

POST /api/auto/

تقوم بتمرير URL بالإضافة إلى قواعد validate اختيارية. يتنقل FourA عبر تدرج يراعي التكلفة (فحص مباشر منخفض التكلفة، ثم proxy مُدار بالتناوب، ثم متصفح كامل) ويتوقف عند أول مستوى يُرجع response تقبلها قواعدك. عند تكرار الطلبات إلى نفس المضيف (host)، تتم إعادة استخدام جلسة نشطة (warm session) بدلا من ذلك، مما يجعل الطلب الثاني منخفض التكلفة.

لا تحتاج إلى ضبط محاولات إعادة الطلب، أو أحجام التجمعات (pools)، أو أعداد الـ proxy. يتعلم FourA هذه الإعدادات لكل host.

Request Body

المعامل النوع مطلوب القيمة الافتراضية الوصف
url string نعم - الـ URL المستهدف
method string لا "GET" طريقة HTTP method
headers [string, string][] لا - ترويسات (headers) مخصصة كأزواج [name, value]
data any لا - جسم الطلب (request body) لطلبات غير GET
validate object لا - معايير النجاح، بنفس هيكل validate الخاص بـ Single Request (انظر أدناه). حدد للوضع التلقائي شكل الصفحة الحقيقية حتى يتمكن من التمييز بين المحتوى وصفحة التحدي (challenge page).
returnSession boolean لا true تضمين الجلسة الناجحة (proxy، cookies، userAgent) في الـ response لتتمكن من إعادة استخدامها عبر /api/single/ أو /api/browser/.
forceProxy boolean لا true التوجيه دائما عبر rotating proxy. اضبط القيمة على false للسماح بالمسار المباشر الأقل تكلفة عندما يسمح الهدف بذلك (بعض آليات الحماية تكون أكثر صرامة مع حركة مرور الـ proxy).
timeout_ms integer لا 120000 الحد الزمني الإجمالي للطلب بالكامل، بالمللي ثانية. تعمل جميع المحاولات الفرعية ضمن هذا الحد. الحد الأدنى 5000، والحد الأقصى 180000.
ignoreProxies string[] لا - معرفات الـ proxy المطلوب تجنبها في كل محاولة فرعية. استخدم المعرفات المُرجعة من استجابات /api/auto/ أو /api/proxy/ السابقة.
followRedirects integer لا 5 الحد الأقصى لعمليات إعادة التوجيه التي يتم تتبعها في مستويات التدرج منخفضة التكلفة. 0 للتعطيل. الحد الأقصى 20.

Response

{
  "status": 200,
  "data": "<!doctype html>...",
  "headers": [{"content-type": "text/html"}],
  "meta": {
    "rung": "cache",
    "solved": false,
    "attempts": 1,
    "credits": 2
  },
  "session": {
    "proxy": "A1B2C3",
    "cookies": [{"name": "session", "value": "abc", "domain": "example.com"}],
    "userAgent": "Mozilla/5.0..."
  }
}
الحقل النوع الوصف
status number حالة HTTP من الهدف.
data string نص الـ response body، بغض النظر عن الـ rung التي قامت بالخدمة. تُعاد صفحة JSON كنص JSON، لذا يجب تحليله بنفسك.
headers array أو object ترويسات response الهدف. تُعيد رتب Single و proxy مصفوفة من كائنات header لكل قفزة؛ بينما تُعيد رتب المتصفح كائنًا مسطحًا.
meta.rung string أي درجة في السلم قامت بتسليم الـ response. واحدة من: probe (طلب مباشر منخفض التكلفة)، أو proxy (proxy دوار)، أو browser (تصيير كامل بالمتصفح)، أو cache (إعادة تشغيل جلسة دافئة)، أو warmup (تم جلب صفحة الدخول للموقع أولاً واستُخدمت ملفات تعريف الارتباط الخاصة بها لفتح الرابط العميق)، أو fail (لم تُنتج أي درجة استجابة مقبولة).
meta.solved boolean ما إذا كانت الصفحة تتطلب خطوة إضافية (صفحة تحدي) وتم إكمالها أثناء هذا الاستدعاء.
meta.attempts number المحاولات الفرعية التي تم إجراؤها قبل النجاح.
meta.credits number إجمالي الرصيد المستهلك في هذا الاستدعاء. يطابق X-FourA-Credits.
session.proxy string المعرف المشفر للـ proxy الذي قام بتسليم الـ response. أعد استخدامه في طلب Single أو Browser. يتوفر عندما يكون returnSession هو true.
session.cookies array ملفات تعريف الارتباط (cookies) من المحاولة الناجحة. يتوفر عندما يكون returnSession هو true.
session.userAgent string الـ User-Agent المستخدم في المحاولة الناجحة. يتوفر عندما يكون returnSession هو true.
error string رسالة الخطأ في حال فشل الاستدعاء.

مثال

curl -X POST https://eu.api.foura.ai/api/auto/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/product/42",
    "validate": {"data": {"accept": ["Add to cart"]}}
  }'

ملاحظات

  • Auto هو منسق. يستدعي Single أو Proxy أو Browser داخليًا ويمرر مفتاح API الخاص بك إلى كل استدعاء فرعي. يُحسب استدعاء Auto كطلب واحد في Activity Log وفي صفحة Overview، مع مجموع أرصدة استدعاءاته الفرعية؛ وتُدرج الاستدعاءات الفرعية تحته كمحاولات تابعة له، ولا تُحسب أبدًا كطلبات منفصلة.
  • مرر validate.data.accept مع سلسلة فرعية لا تحتويها إلا الصفحة الحقيقية. من دونها، لا يستطيع auto التمييز بين رمز 200 الحقيقي وصفحة التحدي البينية التي تُرجع بالحالة 200.
  • يحدد timeout_ms الحد الأقصى للاستدعاء بأكمله. قد يستغرق الطلب الأول لموقع محمي عشرات الثواني؛ بينما تنتهي الجلسات الجاهزة المعاد استخدامها عادة في أقل من ثانية.

Single Request

POST /api/single/

يرسل HTTP request بخصائص اتصال واقعية تحاكي المتصفح، دون تشغيل متصفح حقيقي. هذا هو أسرع endpoint.

Request Body

المعلمة النوع مطلوب القيمة الافتراضية الوصف
method string نعم - طريقة HTTP: ‏GET أو POST أو PUT أو PATCH أو DELETE أو HEAD أو OPTIONS
url string نعم - عنوان URL المستهدف. استخدم {ts} في أي مكان داخل URL لإدراج الطابع الزمني الحالي لتجاوز التخزين المؤقت (cache-busting).
headers [string, string][] لا - ترويسات مخصصة كأزواج [name, value]
unblocker boolean لا true إرسال ترويسات متصفح واقعية (User-Agent و Sec-Ch-Ua و *Sec-Fetch- و Accept-Encoding). مفعّل افتراضياً. اضبطه على false لإرسال بصمة عميل بسيطة.
timeout_ms number لا 15000 المهلة الإجمالية بالمللي ثانية (الحد الأقصى: 120000)
connect_timeout_ms number لا 5000 مهلة الاتصال بالمللي ثانية
accept_timeout_ms number لا 5000 مهلة قبول الاتصال بالمللي ثانية (وقت انتظار قبول الاتصال)
server_response_timeout_ms number لا 15000 مهلة استجابة الخادم بالمللي ثانية (وقت انتظار أول بايت)
dns_cache_timeout_sec number لا 120 مدة بقاء ذاكرة التخزين المؤقت لـ DNS (TTL) بالثواني (الحد الأقصى: 240)
followRedirects number لا disabled أقصى عدد لعمليات إعادة التوجيه التي سيتم تتبعها (0-20). اتركه فارغاً للتعطيل.
tryJsonData boolean لا false تحليل جسم الاستجابة بتنسيق JSON إذا أمكن
returnBuffer boolean لا false إرجاع مخزن مؤقت خام (raw buffer) بدلاً من سلسلة نصية مفكوكة الترميز
data any لا - جسم الطلب (سلسلة نصية أو كائن، يُحوّل تلقائياً إلى تسلسل JSON)
proxy string لا - معرف Proxy ID من استجابة سابقة، لتثبيت نفس نقطة الخروج. مرر السلسلة المبهمة كما هي حرفياً. يتم رفض عنوان البروكسي الخام مع 400 Invalid proxy format. لا يمكن تثبيت بعض المعرفات: راجع Pinning an exit.
browser string لا Chrome المتصفح المراد تمثيله: Chrome أو Edge أو Safari أو Firefox أو Tor. راجع Browser profiles.
os string لا - نظام التشغيل المراد تمثيله: Windows أو macOS أو Android أو iOS. يقبل اسم العائلة أياً من إصداراتها.
version string لا newest إصدار المتصفح المراد تمثيله، كما هو موضح في الكتالوج. يُعتمد أحدث تطابق عند توفر عدة خيارات متوافقة.
profile string لا - المعرف الدقيق للملف الشخصي من GET /api/profiles، بدلاً من الحقول الثلاثة أعلاه.
validate object لا - قواعد التحقق من صحة الاستجابة (راجع أدناه)

Browser profiles

يقدم الطلب افتراضياً أحدث إصدار من Google Chrome. تقبل بعض الأهداف متصفحاً وترفض آخر، لذا يقوم browser و os و version بتضييق نطاق كتالوج الملفات الشخصية المقاسة، ويحدد profile ملفاً عبر id.

{
  "method": "GET",
  "url": "https://example.com",
  "browser": "Firefox",
  "os": "Windows"
}

القواعد:

  • يتطلب التحديد تفعيل unblocker (مفعل افتراضيا). عند إيقاف unblocker لا يتم إرسال أي browser headers، وبالتالي يُرفض الـ request بدلا من تطبيقه جزئيا.
  • عند تطابق عدة profiles، يتم اعتماد الإصدار الأحدث.
  • إذا تعذر على الكتالوج تقديم تركيبة معينة، فإنه يُرجع خطأ يحدد الخيارات المتاحة. لا يتم إرسال الـ request كمتصفح مختلف أبدا.
  • تتوفر الحقول الأربعة نفسها داخل كائن request الخاص بـ POST /proxy/.

يُرجع GET /api/profiles الكتالوج الكامل ولا يتطلب API key:

{
  "profiles": [
    { "id": "...", "browser": "Chrome", "version": "...", "os": "...", "osFamily": "macOS" }
  ],
  "default": "..."
}

osFamily هي القيمة المستخدمة للتصفية عند إنشاء أداة اختيار؛ وتحتفظ os باسم الإصدار للعرض.

قواعد التحقق

يتيح لك كائن validate تحديد شروط النجاح والفشل. إذا تطابق شرط fail، يتم التعامل مع الـ request على أنه فاشل. إذا تم تعيين شروط accept، يتم التعامل مع الـ responses المطابقة فقط على أنها ناجحة.

{
  "validate": {
    "status": { "accept": [200, 201], "fail": [403, 503] },
    "headers": { "accept": {"content-type": "application/json"} },
    "data": { "accept": ["product"], "fail": ["captcha", "blocked"] }
  }
}
الحقل النوع الوصف
validate.status.accept number[] رموز حالة HTTP المقبولة
validate.status.fail number[] رموز حالة HTTP المرفوضة
validate.headers.accept object أزواج المفتاح والقيمة في header التي يجب توفرها
validate.headers.fail object أزواج المفتاح والقيمة في header التي تتسبب في الفشل
validate.data.accept string[] النصوص التي يجب أن تظهر في response body
validate.data.fail string[] النصوص في response body التي تتسبب في الفشل

مثال

curl -X POST https://eu.api.foura.ai/api/single/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "method": "GET",
    "url": "https://example.com/products",
    "timeout_ms": 10000
  }'

الاستجابة:

{
  "status": 200,
  "headers": [{"result": {"version": "HTTP/2", "code": 200, "reason": ""}, "content-type": "text/html", "server": "...", "set-cookie": ["session=abc", "tracker=xyz"]}],
  "data": "<!doctype html>...",
  "total_time": 0.342,
  "proxy": "A1B2C3"
}

عندما يُجري الهدف فحص روبوتات (bot check) في طريقه إلى جسم الاستجابة، تتضمن الاستجابة أيضًا كائن defense يحدد اسم المزود وما إذا كان الفحص قد تم تجاوزه بنجاح:

{
  "status": 200,
  "data": "<!doctype html>...",
  "total_time": 3.61,
  "defense": {
    "vendor": "sgcaptcha",
    "solved": true,
    "present": ["sgcaptcha"],
    "ms": 3412,
    "cookie": "_I_=<clearance>"
  }
}
الحقل النوع الوصف
status number رمز حالة HTTP من الهدف
headers array كائن واحد لكل قفزة إعادة توجيه (redirect hop). يحتوي كل منها على حقل result يتضمن سطر الحالة بالإضافة إلى كل response header. الترويسات متعددة القيم (Set-Cookie، Link، WWW-Authenticate) تُرجع كمصفوفات من السلاسل النصية.
data string/object جسم الاستجابة (Response body) (JSON إذا كانت قيمة tryJsonData هي true)
total_time number إجمالي وقت الطلب بالثواني
proxy string المعرّف المشفر للـ proxy الذي مر الطلب من خلاله (فقط عند توفير proxy في الطلب). أعد استخدامه في استدعاء لاحق لتثبيت نفس نقطة الخروج.
defense object موجود عندما يقوم الهدف بإجراء فحص bot على هذا الطلب، أو عندما تؤدي إعادة المحاولة باستخدام ملفات cookie الخاصة بالموقع نفسه إلى جلب المحتوى. يوضح defense.solved ما إذا تم اجتياز الفحص، ويوضح defense.retry ما إذا كانت إعادة المحاولة قد جلبت لك المحتوى. راجع Site checks للاطلاع على كل الحقول والقائمة الكاملة للأنظمة.
error string رسالة الخطأ في حال فشل الطلب

طلب Proxy

POST /api/proxy/

يوجّه طلبك عبر عناوين proxy متناوبة مع إعادة المحاولة تلقائيا عند الفشل. يمكنك اختياريا حصر التحديد ضمن مجموعة من دول الخروج المرئية للهدف.

جسم الطلب (Request Body)

المعلمة النوع مطلوب القيمة الافتراضية الوصف
request object نعم - جسم طلب مفرد (نفس حقول Single Request الموضحة أعلاه)
timeout_ms number لا 45000 المهلة الإجمالية لجميع المحاولات بالمللي ثانية (الحد الأقصى: 120000)
maxTries number لا 5 الحد الأقصى لمحاولات تدوير الـ proxy (الحد الأقصى: 90)
ignoreProxies string[] لا - معرّفات الـ proxy المستبعدة من التدوير (استخدم المعرّفات التي أرجعتها استجابات سابقة)
exitCountries string[] لا - قائمة سماح صارمة لرموز الدول المكونة من حرفين والمرئية للهدف (مثل ["CZ", "GB"]). يتم اقتطاع المسافات الزائدة من القيم وتحويلها إلى أحرف كبيرة وإزالة التكرارات. يتم استبعاد عناوين proxy ذات نقاط الخروج غير المعروفة ولا يتراجع الطلب أبدا إلى دولة غير مطلوبة.
exitClass string لا - standard أو premium. يتيح premium للطلب الترقية إلى نقطة خروج premium عندما يواجه التجمع القياسي صعوبة مع هدف محمي. يتطلب خطة تتضمن نقاط خروج premium.

نطاق exitCountries

يستخدم التحديد أحدث بيانات وصفية متاحة للدول المرئية للهدف، والتي يتم تحديثها عادة خلال نحو عشر دقائق. هذا ليس بحثا مباشرا عن الموقع الجغرافي أثناء الطلب. لا تستنتج الدولة المقدمة للخدمة من عنوان مضيف الـ proxy.

إذا لم يكن التجمع الحالي يحتوي على أي تطابق مع الدول المطلوبة، تُرجع الاستجابة رمز HTTP 200 مع غلاف خطأ (error envelope):

{
  "error": "No eligible proxy found for exit countries: CZ, GB",
  "code": "no_eligible_proxy",
  "details": { "exitCountries": ["CZ", "GB"] },
  "total": 0.084
}

احتفظ بالنطاق المطلوب وأعد المحاولة لاحقاً. لا تقم بتغييره أو توسيعه إلا إذا تغيرت متطلبات البلد لسير عملك بشكل صريح.

مثال

curl -X POST https://eu.api.foura.ai/api/proxy/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "maxTries": 3,
    "exitCountries": ["CZ", "GB"],
    "request": {
      "method": "GET",
      "url": "https://example.com/prices"
    }
  }'

Response:

{
  "status": 200,
  "headers": [{"result": {"code": 200}, "content-type": "text/html", "set-cookie": ["a=1", "b=2"]}],
  "data": "<!doctype html>...",
  "total_time": 1.204,
  "proxy": "A1B2C3",
  "exitCountry": "CZ",
  "total": 2.341
}
الحقل النوع الوصف
proxy string المعرف المشفر لـ proxy المستخدم. أعد استخدامه في طلب Single أو Browser عن طريق تمريره كحقل proxy، أو تخطاه في طلب Proxy التالي عبر ignoreProxies.
exitCountry string رمز الدولة المكون من حرفين والمرئي للهدف لـ proxy الذي خدم الطلب. يكون موجودا فقط عند تعيين exitCountries في الطلب. تحقق دائما من أنه أحد الرموز التي طلبتها قبل الوثوق في الاستجابة.
exitClass string فئة نقطة الخروج التي خدمت هذا الطلب، وتكون موجودة في الاستجابة الناجحة عندما يحدد الطلب واحدة. تعني premium أن نقطة خروج premium أعادت نص الاستجابة؛ بينما تعني standard أن التجمع القياسي هو من قام بذلك. الطلب الفاشل لم يخدم أي شيء، لذا فهو لا يحمل exitClass؛ اقرأ attemptReport الخاص به لمعرفة ما واجهته المحاولات.
total number المدة الزمنية الإجمالية بالثواني (float). تتضمن اختيار proxy وإعادة المحاولات والمحاولة الناجحة. يمثل total_time الطلب الداخلي فقط؛ وقيمة total تكون دائما >= total_time.
profile string ملف تعريف المتصفح الذي اختاره التدوير، ويكون موجودا فقط عندما لا يكون هو الملف الذي طلبته. غيابه يعني أن الطلب تم إرساله تماما كما كُتب. أعد تمرير id كـ profile في الاستدعاءات اللاحقة للاحتفاظ بالمتصفح الذي نجح.
error string رسالة الخطأ في حال فشل الطلب. عند عدم تطابق النطاق، تكون قيمة code هي no_eligible_proxy ويعيد details.exitCountries إظهار النطاق القياسي.
attemptReport object موجود في كل استدعاء Proxy فاشل. يحصي ما واجهته المحاولات، بحيث لا تظهر التجمعات المحظورة والتجمعات المعطلة وقاعدة validate التي لم تتطابق أبدا بنفس رسالة الخطأ. انظر أدناه.

يتم تضمين جميع حقول استجابة Single Request أيضا، ومن بينها defense: محاولة proxy التي واجهت فحص bot تبلغ عنها بنفس طريقة Single.

سبب فشل استدعاء Proxy

تظهر قيمة Download maxTry limit reached بنفس الشكل أيا كان مسار المحاولات، لذلك تحمل كل استجابة Proxy فاشلة attemptReport بجانب الخطأ:

{
  "error": "Download maxTry limit reached",
  "attemptReport": {
    "total": 25,
    "noResponse": 0,
    "defense": 0,
    "contentRejected": 25,
    "statusRejected": 0,
    "other": 0,
    "vendors": [],
    "profilesTried": ["default"],
    "summary": "25 attempt(s): 25 returned HTTP 200 with no defense present and were rejected only by your validate.data - the page was fetched, your content rule did not match it"
  },
  "total": 34.812
}
الحقل النوع الوصف
total integer المحاولات التي تم إجراؤها
noResponse integer لم تستجب عقدة الخروج مطلقًا، لذلك لم يتم الوصول إلى الموقع
defense integer استجاب الموقع وتم التعرف على فحص bot في تلك الاستجابة
contentRejected integer استجابة HTTP 200، بدون فحص bot، ولكن تم الرفض فقط بواسطة validate.data الخاص بك
statusRejected integer استجاب الموقع، بدون فحص bot، ولكن تم الرفض بواسطة validate.status الخاص بك
other integer تمت الاستجابة، وليست أيًا مما سبق
vendors string[] موفرو فحص bot الذين تم التعرف عليهم في أي مكان في المهمة
profilesTried string[] ملفات تعريف المتصفح التي أرسلتها المهمة، مرتبة حسب أول استخدام. default تعني أن طلبك تم إرساله دون تعديل.
summary string جملة واحدة تم إنشاؤها من التعدادات، وهي آمنة للتسجيل في السجلات

سلسلة error لم تتغير، لذا فإن العميل الذي يطابقها يظل يعمل. ما يجب فعله بشأن كل تعداد: سبب نفاد محاولات طلب Proxy.

exitClass

ترفض بعض الأهداف عقد الخروج في المجموعة القياسية بغض النظر عن عدد المحاولات. تُعلم exitClass: premium خدمة Proxy بأنه يجوز لها تصعيد مثل هذا الطلب إلى عقدة خروج premium بالإضافة إلى المجموعة القياسية، بدلاً من مجرد التبديل داخلها فقط.

{
  "exitClass": "premium",
  "request": { "method": "GET", "url": "https://example.com/report" }
}

ثمة ثلاثة أمور يجدر معرفتها قبل إرساله.

إنه إذن وليس تعليمات إلزامية. لا يزال المجمع القياسي (standard pool) يتنافس للحصول على الإجابة، وغالبا ما ينجح أولا. لا ينضم مخرج premium إلا عندما يستنفد المجمع ميزانية قصيرة على الطلب أو عندما يرفضه الهدف بوضوح. الطلب الذي يجيب عليه المجمع القياسي قبل تجربة أي مخرج premium يعد نجاحا عاديا ولا يكلفك أي استهلاك premium. بمجرد تجربة مخرج premium، يُحسب استهلاكه كما هو موضح أدناه.

توضح لك الاستجابة الجهة التي تولت خدمتك فعليا. عند تحديد فئة، تتضمن الاستجابة exitClass:

{
  "status": 200,
  "exitClass": "premium",
  "proxy": "Y2QXVK",
  "data": "..."
}

premium تعني أن نقطة خروج premium هي التي أعادت الـ body. standard تعني أن الـ pool القياسي هو من قام بذلك، وهي نفس الإجابة التي تتلقاها أيضا عند تعذر الحصول على مخرج premium، أو عند استنفاد حركة مرور premium المضمنة في خطتك (بالإضافة إلى أي رصيد إضافي قمت بشرائه) لفترة الفاتورة الحالية. لا يعتبر أي منهما خطأ، ويمكنك مطابقة حركة مرور premium الخاصة بك بناء على هذه القيم لكل request بدلا من الاعتماد على رقم شهري إجمالي. تنتقل نفس القيمة في response header المسماة X-FourA-Exit-Class (راجع Response Headers).

يتم قياس حركة مرور premium عبر الشبكة. تحسب محاولة premium ما تم إرساله واستلامه أثناء عبوره للشبكة، مضغوطا ومشفرًا أثناء نقله، سواء نجح في إعادة صفحتك أم لا. المحاولة التي كانت لا تزال قيد التشغيل عند استجابة مخرج آخر يتم إيقافها فورا ولا يتم احتسابها. تحتسب حركة مرور premium ضمن حصة premium المخصصة لك وأيضا ضمن إجمالي bandwidth الخاص بك: نفس البايتات، يتم الإبلاغ عنها مرتين، ولا يتم جمعها معا أبدا. عندما ينجح مخرج premium في تسليم الصفحة، فإن حركة المرور الخاصة به تمثل كامل حركة مرور الـ request، وبالتالي لا يتم احتساب الصفحة مرة أخرى كحركة مرور قياسية. تعرض صفحة Usage & Limits إجمالي حركة المرور، ونسبة premium منها، وحصة premium المخصصة التي يتم تقييم استهلاكك بناء عليها.

حذف الحقل لا يعادل إرسال standard. ترك الحقل محذوفا يبقي القرار غير محدد؛ بينما إرسال standard يحدد صراحة أن هذا الـ request يجب ألا يتم تصعيده أبدا، وهي الطريقة لمنع مهمة معينة من استخدام حركة مرور premium تماما.

نفاد الرصيد ليس خطأ. يستمر الـ request الذي يحدد premium في العمل بعد نفاد الحصة: حيث يتولى الـ pool القياسي خدمته ويوضح الـ response القيمة standard. لا توجد مهمة تتوقف بسبب نفاد الحصة المخصصة.

تتطلب exitClass: premium خطة تتضمن مخارج premium. في الخطط التي لا تشملها، لا يستهلك الـ request أي مخرج premium على الإطلاق: فإما أن يتم رفضه برمز 403 مصحوبا بـ X-FourA-Limit: plan_limit_premium (راجع Rate Limits)، أو تتم خدمته من الـ pool القياسي مع إرجاع exitClass: standard في الـ response. يجب التعامل مع كلتا الحالتين.

Browser Profile Rotation

يقوم الـ Proxy بتدوير المخارج. عندما يرفض أحد المواقع المتصفح الذي قدمته FourA بدلا من رفض نقطة الخروج القادم منها، ينتقل الـ Proxy أيضا إلى عائلة متصفحات أخرى من الدليل. هذا لا يضيف أي محاولة جديدة: فالتدوير يغير ما يرسله الـ retry، ولا يؤثر مطلقا على حدوث المحاولة من عدمها.

يتذكر الـ Proxy أيضا لفترة معينة عائلة المتصفحات التي قبلها الموقع آخر مرة، بحيث يمكن لأي استدعاء لاحق لنفس الموقع البدء بتلك العائلة بدلا من الإعداد الافتراضي. يحدد الـ response اسم تلك العائلة في profile، تماما كما يفعل مع أي عائلة تم اختيارها عبر التدوير.

لا يتم أبدا تجاوز أي تحديد صريح للقيم profile أو browser أو os أو version في الـ request الداخلي، وينطبق الأمر ذاته على الـ request الذي يحمل الـ header الخاص به مثل User-Agent أو Cookie، وذلك لأن التصريح مرتبط بالبصمة التي حصلت عليه.


Browser Request

POST /api/browser/

يفتح عنوان URL الخاص بك في مثيل متصفح Chrome. يتم تحميل الصفحة، وتنفيذ JavaScript، وستحصل على HTML المعروض بالكامل بالإضافة إلى cookie jar.

Request Body

المعامل النوع مطلوب القيمة الافتراضية الوصف
url string نعم - عنوان URL الهدف
headers object لا - ترويسات مخصصة كأزواج مفتاح-قيمة
cookies array لا - ملفات cookie لتعيينها: [{name, value, domain?}]
userAgent string لا - سلسلة User-Agent مخصصة
unblocker boolean لا true يكمل التحقق الذي تطلبه الصفحة قبل تحميلها (صفحة تحدي أو بوابة مشابهة). مفعّل افتراضيا. اضبط false لعرض كل ما ترجعه الصفحة، بما في ذلك صفحة التحدي، كما هي.
proxy string لا - معرف Proxy من استجابة سابقة لتثبيت نفس المخرج. أعد إرسال السلسلة غير الشفافة حرفيا. يتم رفض عنوان proxy الخام برمز 400 Invalid proxy format.
exitCountry string لا - رمز الدولة المكون من حرفين (ISO 3166-1 alpha-2) للبلد الذي يخرج منه الطلب. يضبط ساعة المتصفح على المنطقة الزمنية المطابقة. راجع مطابقة ساعة المتصفح مع المخرج.
timeout_ms number لا 30000 مهلة تحميل الصفحة بالمللي ثانية (الحد الأقصى: 120000)
checkStatus number لا - حالة HTTP المتوقعة (يفشل الطلب إذا كانت مختلفة)
checkText string لا - نص يجب أن يظهر في الصفحة المعروضة

مطابقة ساعة المتصفح مع المخرج

يمكن للصفحة قراءة المنطقة الزمنية للمتصفح ومقارنتها ببلد IP الذي تراه. يعد عدم التطابق أحد أبسط الإشارات التي يعتمد عليها نظام اكتشاف الروبوتات، ولا يكلفك تجنبه أي شيء.

اضبط exitCountry على البلد الذي تخرج منه حركة المرور الخاصة بك، وسيقوم المتصفح بالإبلاغ عن المنطقة الزمنية التابعة له:

{
  "url": "https://example.com",
  "proxy": "A1B2C3",
  "exitCountry": "BR"
}

القواعد:

  • القيمة هي دولة الخروج، أي الدولة التي يراها الهدف، وليس مكان استضافة الـ proxy. يختلف الاثنان بما يكفي ليكون الأمر مهما.
  • إذا تم حذفه، يستخدم FourA دولة الخروج عندما يعرفها، وإلا فإنه يترك ساعة المتصفح كما هي بدلا من التخمين.
  • رمز الدولة الذي لا يتعرف عليه FourA يعامل بنفس طريقة حذف الحقل. هذا ليس خطأ.
  • الساعة فقط هي التي تتبع الدولة. يظل Accept-Language والمحتوى الذي يقدمه الموقع دون تغيير، لذا لن تقوم الصفحة بتبديل اللغات فجأة.

معامل userAgent

أرسل userAgent وستكون هذه السلسلة النصية الدقيقة هي ما تراه الصفحة وعمالها والهدف. يشتق FourA أيضا تلميحات العميل المتطابقة منها (sec-ch-ua و sec-ch-ua-platform و navigator.platform والقيم عالية الإنتروبيا التي يطلبها الكاشف بالاسم)، وبالتالي لا يدعي الـ request متصفحا في الـ header ومتصفحا آخر في JavaScript.

الـ userAgent في الـ response هو ما تم تقديمه. هذا مهم عند إعادة تشغيل clearance: يتم ربط ملف تعريف الارتباط cf_clearance بمخرج الـ proxy والـ User-Agent الذي حصل عليه، لذا أعد إرسال السلسلة النصية التي أبلغ عنها الـ response، وليس تلك التي تعتقد أنها استخدمت. راجع Site checks.

أرسل سلسلة نصية ليست تابعة لـ Chromium (مثل User-Agent لـ Firefox) وسيتم تقديمها كما هي، دون إرفاق قائمة علامات Chromium التجارية.

مثال

curl -X POST https://eu.api.foura.ai/api/browser/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/spa-app",
    "timeout_ms": 15000,
    "checkText": "product-list"
  }'

الـ response:

{
  "status": 200,
  "headers": {"content-type": "text/html"},
  "body": "<!doctype html>...",
  "cookies": [{"name": "session", "value": "abc123", "domain": "example.com", "path": "/", "expires": 1735689600, "httpOnly": true, "secure": true, "sameSite": "Lax"}],
  "userAgent": "Mozilla/5.0...",
  "defenseSolved": true,
  "defenses": {"present": ["cloudflare"], "cleared": ["cloudflare"]},
  "proxy": "A1B2C3"
}
الحقل النوع الوصف
status number رمز حالة HTTP من الهدف
headers object ترويسات الاستجابة
body string or object محتوى الصفحة المُصيّر بالكامل. يكون نص HTML عندما يكون content-type هو HTML؛ وكائن عندما تُرجع الصفحة JSON ويتم تحليله تلقائياً.
cookies array كائنات ملفات تعريف الارتباط (cookie) الكاملة من الصفحة. يتضمن كل ملف تعريف ارتباط name وvalue وdomain وpath وexpires وhttpOnly وsecure وsameSite وخصائص ملفات تعريف الارتباط الأخرى.
userAgent string قيمة Browser User-Agent المُستخدمة
defenseSolved boolean تكون true إذا تمت مواجهة نظام حماية من البوت وتجاوزه بنجاح في هذا الاستدعاء. وتكون غائبة في الحالات الأخرى. تحدد ما إذا كان الاستدعاء يستهلك 5 أو 10 أرصدة.
defenses object تسرد present كل مزود تم التعرف عليه أثناء تحميل الصفحة، وتسرد cleared المزودين الذين تتضمن الصفحة النهائية تجاوزاً لحمايتهم. يمكن أن يظهر المزود في present ولا يظهر أبداً في cleared. انظر Site checks.
proxy string المعرّف المُشفّر للبروكسي الذي مر عبره الطلب (فقط عند توفير proxy في الطلب). أعد استخدامه في الاستدعاءات اللاحقة للحفاظ على نفس نقطة الخروج.
error string رسالة الخطأ في حال فشل الطلب

تثبيت نقطة الخروج (Exit Pinning)

تُثبّت قيمة proxy في طلب Single أو Browser نقطة الخروج التي استخدمها استدعاء سابق. مرّر المعرّف المرمز (opaque ID) كما ورد تماماً، ولا تمرر أبداً عنوان بروكسي.

يتم رفض ثلاث قيم، وجميعها برمز الحالة 400:

الخطأ المعنى
Invalid proxy format القيمة ليست معرّفاً صادراً عن FourA. عناوين البروكسي المباشرة تقع هنا.
Proxy not found تم فك تشفير المعرّف، لكنه لم يعد يشير إلى نقطة خروج نشطة. احصل على معرّف جديد من استدعاء جديد.
Managed exit: this proxy id cannot be pinned to a request نقطة الخروج موجودة، لكنها ليست نقطة خروج تُبقيها FourA مفتوحة لطلب محدد. يقع معرّف نقطة الخروج المتميزة (premium exit) هنا عندما لا يتبقى في خطتك أي رصيد لحركة مرور متميزة لاستهلاكه. أعد استخدام الجلسة التي ورد منها، أو نفّذ الاستدعاء عبر POST /api/proxy/ واقبل أي نقطة خروج يختارها.

تُحتسب نقطة الخروج المتميزة المُثبّتة كحركة مرور متميزة (premium traffic). تحمل الاستجابة X-FourA-Exit-Class: premium حتى تتمكن من رؤيتها لكل طلب، وتُحسب حركة المرور التي نقلتها نقطة الخروج ضمن حركة المرور المتميزة في صفحة Usage & Limits الخاصة بك بالإضافة إلى إجمالي عرض النطاق الترددي (bandwidth)، سواء أرجَع الموقع الصفحة المطلوبة أم لا. يتطلب التثبيت توفر نقاط خروج متميزة في خطتك مع بقاء رصيد متاح؛ وإلا سيتم رفض المعرّف برمز الخطأ 400 الخاص بنقاط الخروج المُدارة المذكور أعلاه.

رموز حالة HTTP

الرمز المعنى
200 اكتمل الـ request (تحقق من status الداخلي لمعرفة استجابة الهدف)
400 نص request غير صالح، أو معلمات غير صحيحة، أو IP الهدف يقع ضمن نطاق خاص/محجوز، أو معرف proxy لا يمكن تثبيته
401 مفتاح API مفقود أو غير صالح
403 الـ endpoint أو المعلمة ليست ضمن خطتك. يحدد X-FourA-Limit ذلك: plan_limit_feature أو plan_limit_premium.
404 Not Found: لا يوجد endpoint في هذا المسار.
413 حجم نص الـ JSON في الـ request يتجاوز 100 كيلوبايت. الاستجابة ليست JSON ولا تحتوي على X-FourA-Request-Id.
429 حد الخطة (تم تعيين X-FourA-Limit) أو الحصة المشتركة للمنصة في الدقيقة (بدون header)
500 خطأ داخلي في الخادم
502 Upstream unavailable. تمكن FourA من الوصول إلى محركه ولكن الاستجابة كانت غير قابلة للاستخدام. أعد المحاولة.
503 الخدمة معطلة مؤقتا أو بلغت سعتها القصوى، أو Backend service unavailable أثناء إعادة تشغيل المحرك
504 Upstream timeout. لم ينتهِ المحرك ضمن المهلة الزمنية المحددة لهذا الـ request. ارفع timeout_ms أو أعد المحاولة.

الخطوات التالية

آخر تحديث: 30 سبتمبر 2026