Skip to content
اللغة: العربية

الـ API للمطوّرين

حدود المعدل: كل الحدود والترويسات

آخر تحديث 1 نوفمبر 2026 القراءة: 5 د

كم طلبًا في الدقيقة تسمح به واجهة LinkHarbor API، وما الحجم الأقصى للطلب، وكيف تقرأ الترويسات، وكيف تتعامل مع الخطأ 429 بشكل صحيح.

لكي تبقى الـ API سريعة للجميع، يحدّ LinkHarbor عدد الطلبات في الدقيقة. ولا تعتمد الحدود على خطتك، فلا توجد حصة شهرية من استدعاءات الـ API. تسرد هذه المقالة كل الحدود وتبيّن كيف تتعامل شيفرتك معها بشكل سليم.

كيف تُحسب الطلبات

  • يقع كل طلب في حاوية (bucket) واحدة بالضبط، مثل user للطلبات المصادَق عليها أو token لاستبدال الرمز
  • يجري العدّ لكل دقيقة كاملة (UTC)؛ ويبدأ العدّاد من الصفر مع كل دقيقة جديدة
  • حسب الحاوية، تعدّ الـ API لكل مساحة عمل أو لكل شخص أو لكل اتصال أو لكل عنوان IP
  • الطلبات التي تفشل مبكرًا عند الرمز أو النطاق أو المخطط (401، و403 insufficient_scope، و400، و422 validation_failed من فحص المخطط) لا تُحسب؛ أما الأخطاء اللاحقة مثل 403 feature_not_available فتُحسب

كل الحدود

الحاوية (X-RateLimit-Bucket)الحديُحسب لكليسري على
user600 في الدقيقةمساحة العمل لرموز مفاتيح API (كل المفاتيح وأدوات الذكاء الاصطناعي في مساحة العمل معًا)؛ والشخص لتسجيلات الدخول إلى لوحة التحكمكل الطلبات المصادَق عليها إلى /v1 التي ليس لها حاوية خاصة بها
token30 في الدقيقةعنوان IPPOST /v1/token
public120 في الدقيقةعنوان IPالطلبات إلى الـ API دون مصادقة، مثل GET /v1/plans وGET /v1/pages/available
callback120 في الدقيقةعنوان IPPOST /v1/callbacks/sale
internal120 في الدقيقةعنوان IPرابط الاستقبال لتكامل Custom (API) ‏(POST /v1/ingest/{id})
mcp120 في الدقيقةاتصال الذكاء الاصطناعي (رمز الوصول)خادم MCP على /mcp
oauth300 في الدقيقةعنوان IPتسجيل الدخول عبر OAuth والاكتشاف لمساعدي الذكاء الاصطناعي
auth30 في الدقيقةعنوان IPتسجيل الدخول والتسجيل وإعادة تعيين كلمة المرور (لوحة التحكم والتطبيق)
refresh120 في الدقيقةعنوان IPتمديد جلسة لوحة التحكم
discover60 في الدقيقةالشخص، أو عنوان IP عند عدم تسجيل الدخولقسم «استكشاف» في التطبيق
subs_read120 في الدقيقةالشخص، أو عنوان IP عند عدم تسجيل الدخولقراءة الصفحات التي تتابعها (التطبيق)
subs_write20 في الدقيقةالشخص، أو عنوان IP عند عدم تسجيل الدخولتغيير الصفحات التي تتابعها (التطبيق)

ميزانية واحدة لكل مساحة عمل

كل رموز مفاتيح API في مساحة العمل نفسها تتشارك الـ 600 طلب في الدقيقة، بغض النظر عن عدد المفاتيح التي تنشئها. وتُحسب هنا أيضًا أدوات مساعدي الذكاء الاصطناعي المتصلين، لأنها تستدعي الـ API داخليًا. لذا لا ترفع المفاتيح الإضافية الحد. وإذا توزّع حِمل كبير على عدة برامج، فخطّط على أساس الميزانية المشتركة.

الترويسات

X-RateLimit-Limit
حد الحاوية في الدقيقة، مثل 600.
X-RateLimit-Remaining
عدد الطلبات المتبقية في الدقيقة الحالية.
X-RateLimit-Bucket
الحاوية التي وقع فيها الطلب، مثل user.
Retry-After
مع 429 rate_limited فقط: عدد الثواني حتى بداية الدقيقة التالية. ومع api_key_locked يكون وقت الانتظار في details.retry_after_sec.

عند بلوغ الحد

عند بلوغ الحد، تستجيب الـ API بـ HTTP 429 وبهذا الجسم. ونص message يأتي بلغة الحساب (انظر تنسيق أخطاء الـ API ورموز الأخطاء)، وهو هنا بالإنجليزية، أما الرمز rate_limited فيبقى ثابتًا:

الاستجابة عند 429
HTTP/1.1 429 Too Many Requests
Retry-After: 37
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 0
X-RateLimit-Bucket: user

{ "error": "rate_limited", "message": "Too many requests. Please try again in a moment.", "retry_after_sec": 37 }
  1. اقرأ Retry-After أو retry_after_sec
  2. انتظر هذا العدد من الثواني على الأقل، مع قدر صغير من العشوائية حتى لا تبدأ كل العمليات من جديد في اللحظة نفسها
  3. أعد محاولة الطلب بضع مرات على الأكثر
  4. إذا استمر ظهور 429، فوزّع العمل على وقت أطول
Node.js: تخزين الرمز مؤقتًا والتعامل مع 429
const BASE = 'https://dock.at-harbor.com';
let cached = null; // { token, expiresAt }

async function getToken() {
  if (cached && Date.now() < cached.expiresAt - 60_000) return cached.token;
  const res = await fetch(BASE + '/v1/token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      key_id: process.env.LH_KEY_ID,
      key_secret: process.env.LH_KEY_SECRET,
    }),
  });
  if (!res.ok) throw new Error('Token exchange failed: HTTP ' + res.status);
  const data = await res.json();
  cached = { token: data.token, expiresAt: Date.now() + data.expires_in * 1000 };
  return cached.token;
}

async function lh(method, path, body, attempt = 0) {
  const headers = { Authorization: 'Bearer ' + (await getToken()) };
  if (body !== undefined) headers['Content-Type'] = 'application/json';

  const res = await fetch(BASE + path, {
    method,
    headers,
    body: body === undefined ? undefined : JSON.stringify(body),
  });

  if (res.status === 429 && attempt < 3) {
    const wait = Number(res.headers.get('Retry-After') ?? 5);
    await new Promise((r) => setTimeout(r, (wait + Math.random() * 2) * 1000));
    return lh(method, path, body, attempt + 1);
  }
  if (res.status === 401 && attempt === 0) {
    cached = null; // token expired – try once more with a new token
    return lh(method, path, body, attempt + 1);
  }
  const data = await res.json().catch(() => null);
  if (!res.ok) throw new Error((data && data.error) + ' (HTTP ' + res.status + ')');
  return data;
}

// Example: const { items } = await lh('GET', '/v1/pages');

نصائح للكميات الكبيرة من البيانات

  • خزّن الرمز مؤقتًا، ولا تجدّده إلا قبل انتهاء صلاحيته بعد 15 دقيقة بقليل
  • راقب X-RateLimit-Remaining وأبطئ عندما تنخفض القيمة
  • أرسل الطلبات واحدًا تلو الآخر بدلًا من عشرات الاتصالات المتوازية
  • حمّل القوائم مرة واحدة وصفّها محليًا بدلًا من الاستعلام عن كل صفحة على حدة
  • وزّع عمليات المزامنة الكبيرة على عدة دقائق
  • أعد محاولة أخطاء 5xx بفواصل متزايدة، لكن لا تعد محاولة أخطاء 4xx

حدود أخرى

ماذاالحدالاستجابة
تسجيلات الدخول الفاشلةقفل بعد 5 و10 و20 محاولة فاشلة لكل عنوان بريد إلكتروني وعنوان IP: لمدة 60 ثانية، و5 دقائق، و30 دقيقة429 account_locked
إرسالات النماذج10 في الساعة لكل عنوان IP، عبر كل النماذج429 form_rate_limited

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

حدود المحتوى في خطتك، كالصفحات والروابط والكتل والروابط المختصرة وغيرها، ليست حدود معدل بل سقوفًا ثابتة. وهي مذكورة في مقارنة الخطط.

حجم الطلب

يُقاس كل جسم قبل أن تقرأه الـ API. والحجم المسموح يعتمد على نقطة النهاية:

نقاط النهايةأكبر جسم
تسجيل الدخول والتسجيل والاستدعاءات الأخرى غير المصادَق عليها تحت /v1/auth، وPOST /v1/token، وPOST /v1/oauth/exchange، ونقاط نهاية OAuth لمساعدي الذكاء الاصطناعي تحت /oauth والموافقة الخاصة بها، وPOST /v1/ingest/{id}، والدفع في كتلة «ادعم»، واستدعاءات الاشتراك في التطبيق (المتابعة، والمجموعات، وأجهزة الإشعارات الفورية)، وتبديل مساحات العمل، وPOST /v1/auth/logout-all، وحذف حساب، وإعداد المصادقة الثنائية، وقبول دعوة، وتفعيل برنامج الإحالة، وخطوة العودة عند ربط تكامل64 KB
كل نقاط نهاية JSON الأخرى، بما في ذلك إرسال نموذج على صفحة1 MB
POST /v1/webhooks/{id}/verify-signature وخادم MCP على /mcp2 MB
رفع الملفات (POST /v1/assets وPOST /v1/pages/{id}/uploads، بصيغة multipart/form-data)11 MB للطلب كله، والملف نفسه 10 MB كحد أقصى

إذا كان الجسم أكبر، تستجيب الـ API بالخطأ 413 request_too_large؛ ويذكر details.max_bytes وdetails.max_kb الحد. والملف الأكبر من اللازم في عملية رفع يؤدي إلى 413 payload_too_large. ونقاط النهاية التي ليس لها جسم، مثل استدعاءات DELETE، لا تقبل جسمًا أو تقبل {} فقط.

الاستجابة عند 413
HTTP/1.1 413 Payload Too Large

{ "error": "request_too_large", "message": "…", "details": { "max_bytes": 65536, "max_kb": 64 }, "request_id": "…" }

وداخل الجسم أيضًا حدود: لكل نص طول أقصى، ولكل قائمة عدد أقصى من العناصر، والحقول غير المعروفة تُرفض. والقيم مذكورة لكل نقطة نهاية في مرجع الـ API. والمخالفة تؤدي إلى 422 validation_failed، ويذكر details الحقل والقاعدة والحد. ولا يتجاوز طول المسار وسلسلة الاستعلام (query string) معًا 16 KB.

لم تجد ما تبحث عنه؟

أخبرنا بما تحتاج إليه، وسيساعدك فريق الدعم لدينا شخصيًا.

تواصل مع الدعم