تصل الأخطاء دائما بصيغة RFC 9457 application/problem+json:
HTTP/1.1 422 Unprocessable Content
Content-Type: application/problem+json
{
"type": "https://docs.grem.capital/api/errors/business_rule",
"title": "business_rule",
"status": 422,
"detail": "Describe the property: pick a listing or fill in at least a description, city or area",
"code": "not_enough_input",
"requestId": "req_..."
}
| الحقل | المحتوى |
|---|---|
status | حالة HTTP |
title | رمز خطأ ثابت (القائمة أدناه): ابنِ التفرع عليه |
detail | شرح مقروء للإنسان؛ لا تحلله، فقد تتغير الصياغة |
code | الرمز الآلي للسبب المحدد إن كان معروفا (not_enough_input، INSUFFICIENT_FUNDS، ...) |
errors | مشكلات على مستوى الحقول: { "field", "message" }، وcode إن كان معروفا |
requestId | معرّف الطلب: اذكره عند التواصل مع الدعم |
خطأ تحقق مع حقول:
{
"title": "validation",
"status": 400,
"detail": "\"avatarId\" is required",
"errors": [{ "field": "avatarId", "message": "\"avatarId\" is required" }],
"requestId": "req_..."
}
رموز الأخطاء
يقود عنوان type إلى البند المطابق في هذه القائمة.
invalid_key
401. المفتاح مفقود أو خاطئ أو ملغى أو منتهي الصلاحية. تحقق من الترويسة Authorization ومن حالة المفتاح في لوحة التحكم.
forbidden_scope
403. المفتاح صالح لكن ينقصه النطاق المطلوب. أضف النطاق أو أنشئ مفتاحا جديدا (المصادقة).
forbidden
403. الإجراء غير مسموح لهذا الحساب أو المورد: مثلا العقار يخص حسابا آخر أو الدور في الوكالة غير كاف. السبب في detail.
insufficient_funds
402. الرصيد في المحفظة غير كاف، أو نفدت حصة الخطة، أو يوجد دين غير مسدد، أو بلغت حد الاستخدام العادل. يوضح code السبب: INSUFFICIENT_FUNDS، QUOTA_EXCEEDED، DEBT_OUTSTANDING، FAIR_USE_LIMIT_REACHED وغيرها. اشحن الرصيد أو سدد الدين أو غيّر الخطة.
validation
400. لم يجتز الطلب التحقق. ما الخطأ بالضبط موجود في detail وerrors. صحح الطلب؛ فتكراره دون تغيير لا فائدة منه.
business_rule
422. الطلب سليم الصياغة لكن لا يمكن تنفيذه: بيانات ناقصة، أو العقار في حالة غير مناسبة، أو نوع العقار غير مدعوم، وما إلى ذلك. السبب في detail والرمز الآلي في code.
payload_too_large
413. الجسم أو أحد الملفات يتجاوز الحد. حدود الحجم مذكورة لكل أداة. الجسم الذي ليس JSON صالحا يعيد 400 validation.
range_not_satisfiable
416. نطاق Range في تنزيل الملف يقع خارج الملف. ويذكر Content-Range: bytes */size حجم الملف.
rate_limited
429. تجاوزت حد معدل الطلبات. انتظر عدد الثواني الذي تذكره Retry-After ثم أعد المحاولة (الحدود والفوترة). ويبيّن code أي حد: minute_limit (ثوانٍ) أو daily_limit (يُعاد ضبطه عند 00:00 UTC).
not_found
404. مسار غير معروف، أو مورد غير موجود أو لا يخصك. المورد الذي يخص غيرك يتلقى عمدا الرد نفسه الذي يتلقاه المورد غير الموجود.
idempotency_conflict
409. طلب بهذا Idempotency-Key ما زال قيد التنفيذ. انتظر انتهاءه وأعد المحاولة بالمفتاح نفسه (عدم التكرار). بعد انتهاء المهلة (502 provider_error) يبقى المفتاح محجوزا 15 دقيقة: تحقق من النتيجة قبل الإعادة، فالإعادة بعد انتهاء الحجز تشغّل العمل المدفوع مرة أخرى. أما التقييم السريع فيحرر المفتاح بعد انتهاء المهلة، فأعده بالمفتاح نفسه. ويصل 409 نفسه حين يكون دفع استدعاء بهذا المفتاح ما زال قيد الحجز (code بقيمة RESERVE_IN_PROGRESS أو RESERVE_BUSY) فأعد المحاولة لاحقا؛ وRESERVE_REF_TAKEN يعني أن المفتاح استُنفد، فأرسل مفتاحا جديدا.
conflict
409. المورد في حالة لا تسمح بهذا الإجراء (مثلا نقل عقار من وكالة إلى أخرى، أو حذف عقار عليه عقد عمولة سار). السبب في detail. لا تكرر الطلب دون تغيير.
service_unavailable
503. الأداة غير متاحة مؤقتا. لم يُخصم شيء. أعد المحاولة بعد مهلة Retry-After؛ ويبين GET /tools/status الحالة الحالية للأدوات.
provider_error
502. فشلت الخدمة التي تنفذ العمل. مؤقت: أعد المحاولة مع مهلة متزايدة. إذا ذكر detail أن الأداة لم تُجب في الوقت المحدد، فقد يكتمل العمل ويُخصم مقابله: تحقق من GET /works قبل تشغيله مجددا؛ وأعد التقييم السريع بالمفتاح Idempotency-Key نفسه. نتائج تحسين الصور والموقع والمسودة لا تُحفظ في GET /works: لهذه انتظر انتهاء الحجز البالغ 15 دقيقة وتحقق من النتيجة في لوحة التحكم أو بين عقاراتك.
internal_error
500. خطأ داخلي. أعد المحاولة بعد مهلة؛ وإذا استمر فتواصل مع الدعم مع ذكر requestId.
قد تتوسع القائمة. تعامل مع الرمز غير المعروف كخطأ عام من فئته في HTTP (4xx مشكلة في الطلب، 5xx عطل في الخدمة).
ما الذي يُعاد
| الحالة | هل تعيد المحاولة؟ |
|---|---|
400، 401، 403، 404، 413، 416، 422 | لا: صحح الطلب أو المفتاح أو البيانات أولا |
402 | بعد شحن الرصيد |
409 idempotency_conflict | نعم، بالمفتاح Idempotency-Key نفسه، بعد انتهاء الطلب الأول. بعد انتهاء المهلة (provider_error) يبقى المفتاح محجوزا 15 دقيقة: تحقق من النتيجة أولا، فالإعادة بعد انتهاء الحجز تشغّل العمل المدفوع مرة أخرى؛ أما التقييم السريع فيحرر المفتاح، فأعده بالمفتاح نفسه |
409 conflict | لا: غيّر حالة المورد أولا |
429، 503 | نعم، بعد Retry-After ثانية |
500، 502 | نعم، مع مهلة متزايدة (1، 2، 4، 8 ... ثوان) |
عند إعادة الطلبات التي تنشئ شيئا أرسل دائما Idempotency-Key نفسه: هكذا لن تنفذ الإعادة العمل ولن تخصم مقابله مرتين.
الاستثناءات
- أحداث Swipe Match (
POST /match/leads/{id}/events) التي لا تسمح بها الحالة الحالية للعميل المحتمل تعيد409معtitle: business_ruleوالسبب فيcode(client_event_rejected،invalid_transition،not_available). - إجراءات مجمع عملاء الوكالة (
POST /leads/{id}/claim،POST /leads/{id}/return-to-pool) بمفتاح شخصي أو بدور غير كاف تعيد403معtitle: forbidden.
ما الذي لا يُخصم
الطلب المرفوض (أي رد 4xx أو 5xx) لا يستهلك استدعاء API. سعر الأداة يُخصم فقط مقابل العمل المقبول. الاستثناء هو provider_error بعد انتهاء المهلة: قد ينتهي العمل ويُخصم ثمنه، فتحقق من GET /works قبل تشغيله من جديد (تحسين الصور والموقع والمسودة: في لوحة التحكم أو بين عقاراتك).