الترقيم والتصفية والأخطاء وحدود المعدل
كيف تُرقَّم القوائم، وكيف تُرفض الطلبات، وما معنى كل رمز حالة، وماذا تفعل عند تقييد المعدل.
آخر مراجعة: 2026-08-23
الترقيم
كل نقطة طرفية للقوائم تقبل page وpage_size وتعيد المغلّف نفسه. total هو عدد كل ما يطابق عوامل التصفية لا حجم هذه الصفحة - فعدد الصفحات هو Math.ceil(total / page_size).
| المعامل | الافتراضي | المدى |
|---|---|---|
page | 1 | من 1 فما فوق |
page_size | 25 | من 1 إلى 200 (تُقصّ القيم الأكبر ولا تُرفض) |
curl -sS "https://your-host/api/v1/crm/contacts?page=2&page_size=100" \
-H "Authorization: Bearer $CLIENTO_TOKEN"{
"items": [ { "id": 4182, "display_name": "Sara Ahmadi", "…": "…" } ],
"page": 2,
"page_size": 100,
"total": 3417
}التصفية والبحث
q بحث نصّي حر في الحقول التي يبحث فيها الإنسان - الأسماء والبريد والشركة. وما عداه معاملات استعلام صريحة، وكل مجموعة توثّق معاملاتها في مستند OpenAPI.
# Free-text
curl -sS "https://your-host/api/v1/crm/contacts?q=ahmadi" \
-H "Authorization: Bearer $CLIENTO_TOKEN"
# Typed filters (tasks)
curl -sS "https://your-host/api/v1/crm/tasks?status=open&priority=high&overdue=true" \
-H "Authorization: Bearer $CLIENTO_TOKEN"المعامل غير المعروف يُتجاهل ولا يُرفض - فالخطأ المطبعي يعيد نتائج غير مُصفّاة بدل خطأ. راجع أسماء المعاملات في مستند OpenAPI حين يبدو أن مرشِّحًا لا يفعل شيئًا.
مغلّف الخطأ
كل رفض، من جسم مشوَّه إلى عطل داخلي، يعيد الحقول الثلاثة نفسها. ولا شيء يعيد صفحة خطأ HTML، فلا يضطر العميل أبدًا إلى تخمين ما إذا كان الجسم قابلًا للتحليل.
{
"error": "validation_error",
"message": "Invalid payload",
"details": { "email": ["Not a valid email address."] }
}- `error` - رمز آلي مستقر. تفرّع عليه وعرِّب عليه.
- `message` - نص تشخيصي بالإنجليزية للمطوِّر. لا تعرضه للمستخدم النهائي ولا تطابق عليه؛ فقد تتغيّر صياغته.
- `details` - بنية تختلف بحسب الخطأ: أخطاء الحقول للتحقق، و
requiredلرفض الصلاحية، وreasonلقاعدة عمل، وretry_afterللتقييد. وقد تكون null.
رموز الحالة
| الرمز | error | المعنى وما ينبغي فعله |
|---|---|---|
| 200 | - | نجحت القراءة أو التحديث. |
| 201 | - | أُنشئ. الجسم هو السجل الجديد. |
| 204 | - | حُذف. بلا جسم. |
| 400 | validation_error أو رمز قاعدة | الحمولة خاطئة. details تسمّي الحقول؛ ولمخالفة قاعدة عمل (مثل payment_amount_not_positive) رمزها الخاص. لا تُعِد الإرسال دون تغيير. |
| 401 | unauthorized | اعتماد مفقود أو منتهٍ أو مُبطَل. جدِّد مرة واحدة ثم توقّف. |
| 403 | forbidden | مُصادَق عليه لكن غير مسموح. details.required تسمّي الرموز. |
| 404 | not_found | لا يوجد سجل كهذا - أو سجل لا يحقّ لك رؤيته. الجوابان متطابقان عمدًا. |
| 409 | conflict أو رمز قاعدة | قاعدة تفرّد أو حالة. لقواعد المالية والمبيعات وإدارة العملاء والتذاكر رموزها الخاصة (مثل invoice_has_payments وpayment_exceeds_due) مع الأرقام في details؛ وفي غيرها يبيّن details.reason أيّها. إن لم تعرف الرمز فاعتمد على حالة HTTP. |
| 429 | rate_limited | مُقيَّد. انتظر Retry-After ثم أعد المحاولة. |
| 5xx | internal_error | عطل عندنا. أعد المحاولة بتراجع تدريجي؛ وقد يكون الطلب طُبِّق أو لا. |
حدود المعدل
النقاط الحسّاسة - تسجيل الدخول، ورموز بوابة العملاء لمرة واحدة، وإرسال النماذج العامة، وصفحات الفواتير العامة، وردود الدفع - مُقيَّدة لكل مُنادٍ. أما عمليات CRUD المُصادَق عليها فغير مُقيَّدة افتراضيًا، لكن مشغّل مساحة العمل قد يضبط حدودًا، فالعميل الحسن التصرّف يعالج 429 على أي حال.
HTTP/1.1 429 Too Many Requests
Retry-After: 42
Content-Type: application/json
{
"error": "rate_limited",
"message": "Too many requests",
"details": { "retry_after": 42 }
}- التزم بـ
Retry-After(بالثواني). هو جواب الخادم نفسه - والانتظار الأقصر يُرفض مجددًا. - تراجَع أُسّيًّا مع عشوائية عند 5xx. فالفاصل الثابت يحوّل انقطاعًا قصيرًا إلى تدافع لحظة التعافي.
- أعِد
GETوDELETEبحرية - فهما مُتماثلا الأثر. أماPOSTفانظر القسم التالي.
تماثل الأثر (Idempotency)
لا توجد ترويسة Idempotency-Key عامة. حيث يكون التكرار ضارًّا، تحمل النقطة الطرفية هويّة تماثلها في الجسم وتجعلها مطلوبة لا اختيارية - فالهوية بيد العميل، لأن العميل وحده يعرف أن هذه إعادة محاولة.
| النقطة الطرفية | الهوية | السلوك عند التكرار |
|---|---|---|
POST /chat/conversations/{id}/messages | client_message_id | يعيد الرسالة الموجودة بـ200 بدل 201 |
POST /chat/conversations/support | المُنادي نفسه | يصل إلى المحادثة نفسها |
| تسليم Webhook (وارد إليك) | delivery_id | راجع دليل الـ Webhooks - التسليم «مرة واحدة على الأقل» |
في النقاط التي لا تملك حقل تماثل، فإن POST الذي تنتهي مهلته مجهول النتيجة. لا تُعِد الإرسال عشوائيًا: اقرأ الحالة بـGET مُصفّى على شيء تتحكم فيه أنت - مرجع خارجي خزّنته على السجل - وأنشئ فقط إن كان غائبًا فعلًا.