حدود معدل الطلبات
حدود الطلبات لكل خطة عبر Listings وSocial، وبنية الاستجابة 429، وكيفية زيادة مدة الانتظار وإعادة المحاولة.
تحتسب Listings API الطلبات لكل حساب ضمن حد معدل الطلبات الخاص بخطتك. يضمن الالتزام بالحد استمرار استجابة تكاملك؛ ويؤدي تجاوزه إلى إرجاع 429 Too Many Requests مع كل ما تحتاج إليه لإعادة المحاولة بطريقة صحيحة.
الحدود لكل خطة
هل تجرّب API دون خطة مدفوعة؟ يُرجع تصريح ليوم واحد مجاني لبيئة الاختبار حدود الطلبات الفعلية الخاصة به مع مفتاح API عند بدء التصريح.
تستند الحدود إلى الخطة وتُطبَّق لكل حساب: يستهلك كل مفتاح API في الحساب من الحصة نفسها. تُحتسب الطلبات ضمن 3 فترات زمنية: حد للطلبات المتتابعة خلال دقيقة، وحد لكل ساعة، وسقف يومي. يُحتسب كل طلب بالتكلفة نفسها، بغض النظر عن نقطة النهاية. تعمل التجربة المجانية وفق الخطة التي اخترتها، لذا تسري عليها حدود تلك الخطة من أول طلب.
يستهلك Social من الحصة نفسها
تُحتسب الطلبات إلى نقاط نهاية Social ضمن حصة الطلبات نفسها لكل حساب التي تُحتسب ضمنها جميع الطلبات الأخرى. يُحتسب POST /social/bulk-posts الذي يتضمن 500 صف كطلب واحد، وليس 500 طلب، لذا فإن التحميل على دفعات هو الطريقة الأقل استهلاكًا للحصة لتحميل كمية كبيرة من المحتوى.
إن Listings وSocial اشتراكان منفصلان، لكنهما لا يملكان حصتين منفصلتين. يحصل الحساب الذي يجمع الاشتراكين على الحدود الأعلى من بين حدود مستويَي الاشتراك، وتُطبَّق مرة واحدة عبر جميع نقاط النهاية — فلا تُجمع الحدود، ولا تُخصَّص حصة لكل منتج. تُحتسب جميع طلبات العميل المشترك في Listings Launch وSocial Growth وفق أرقام Growth الواردة أعلاه.
الاستجابة 429
عندما تتجاوز أحد الحدود، تُرجع API حالة HTTP 429 واستجابة الخطأ القياسية. هناك 3 حقول مهمة لإعادة المحاولة:
retry_after_seconds: مدة الانتظار قبل إعادة المحاولة. تحمل ترويسة HTTP المسماةRetry-Afterالقيمة نفسها عند وجودها.correlation_id: معرّف الطلب الذي ينبغي ذكره عند التواصل مع الدعم.doc_url: رابط يعيدك إلى مُدخلrate_limitedفي مرجع رموز الأخطاء.
{ "error": { "code": "RATE_LIMITED", "message": "Too many requests. Slow down.", "retry_after_seconds": 30, "correlation_id": "9f2c1e64-2b1a-4b0e-9f1a-2c7d5e8a1b3c", "doc_url": "https://listingsapi.com/docs/error-codes#rate_limited" }}التعامل مع استجابات 429 بزيادة مدة الانتظار
التزم بقيمة retry_after_seconds عند وجودها، وإلا فزِد مدة الانتظار تصاعديًا على نحو أُسّي: ضاعف مدة الانتظار مع كل استجابة 429 متتالية حتى بلوغ حد أقصى، مع إضافة تفاوت عشوائي بسيط كي لا تعيد مجموعة من العملاء المحاولة في الوقت نفسه.
import randomimport time import requests MAX_RETRIES = 5 def get_with_backoff(url: str, headers: dict, max_retries: int = MAX_RETRIES): for attempt in range(max_retries): resp = requests.get(url, headers=headers) if resp.status_code != 429: resp.raise_for_status() return resp.json() # Prefer the server's hint; fall back to exponential backoff + jitter. body = resp.json().get("error", {}) retry_after = body.get("retry_after_seconds") if retry_after is None: retry_after = min(2 ** attempt, 30) + random.uniform(0, 1) time.sleep(retry_after) raise RuntimeError("Still rate limited after retrying")البقاء ضمن الحد
- اطلب صفحة واحدة في كل مرة: حلقات جلب الصفحات المتوازية التي تعمل بتتابع سريع هي السبب الأكثر شيوعًا لاستجابات
429. اقرأpageInfo.hasNextPageولا تجلب الصفحة التالية إلا بعد اكتمال الاستجابة لطلب الصفحة الحالية. - رشِّح النتائج على جانب الخادم باستخدام مُعامل الاستعلام
filterبدلًا من جلب جميع الصفحات واستبعاد الصفوف على جانب العميل. - خزِّن الاستجابات التي لا تتغير كثيرًا في ذاكرة التخزين المؤقت بدلًا من إعادة جلبها مع كل طلب.