الخدمة 4

اقتراح القرار على ملف شكوى

POST/insaf/complaint-recommendation

ترسل ملف شكوى ضد محامٍ في طلب واحد، فيُقترح القرار مع تقييم على rubric من 19 قاعدة موزّعة على 5 قرارات: حفظ الشكوى، طلب استكمال نواقص من المشتكي، طلب الإفادة، الإحالة إلى الإدارة العامة للمحاماة، توصية مركّبة.

المرحلة الإجرائية تُستنتج من الملف: وجود respondentStatement = الإفادة وصلت. وجود statementRequestedAt دونها = الإفادة طُلبت ولم يُرد عليها. المرحلة تحدّد القواعد المسموحة وليست حقلاً يُرسل.

  • •استخدم الـ webhook دائماً. الطلب يستغرق عشرات الثواني وقد يصل لدقائق، وأي timeout في الطريق يُضيّع الطلب لأنه لا يُستكمل من حيث توقف.
  • •attachments: كل ملف يُرسل إلى صفحة دون template_id (free-form — القسم 7)، ويُحفظ الـ JSON الراجع كما هو. الـ template يُرجع حقوله فقط ويضيع الباقي الذي قد يكون هو الدليل.
  • •لا افتراض على أسماء الـ keys؛ الكائنات المتداخلة تُفرد، وكل مستند يُقص عند 4,000 حرف، وقد يقل الحد إلى 800 ليبقى الملف كله في حدود 30,000 حرف.
  • •attachments الفارغة مؤشر بحد ذاته لقرارين: "حفظ الشكوى — عدم كفاية المستندات" و"طلب استكمال نواقص من المشتكي".

جرّب الطلب

المفتاح يُحفظ في متصفحك فقط ويُرسل مع الطلب عند التجربة.

POSThttps://inbound-api-gateway.velents.ai

Request

الحقلالنوعمطلوبالشرح
factsstringإجباريالوقائع، من 20 إلى 50,000 حرف. الحقل الإجباري الوحيد.
request_typestringاختيارينفس قيم الخدمة 2. الافتراضي complaint. يحدد قائمة المخالفات والقرارات المسموحة.
complainantobjectاختياريبيانات المشتكي: name, capacity, identityType, nationality (كلها اختيارية). capacity فقط يدخل في التحليل حالياً.
respondentobjectاختياريبيانات المشتكى عليه، بنفس الشكل.
requestsstringاختياريالطلبات، حتى 20,000 حرف.
classificationsstring[]اختيارينصوص المخالفات المرفقة بالشكوى.
hasContractualRelationshipbooleanاختياريهل توجد علاقة تعاقدية؟ عدم الإرسال = "غير محدد" وليس false.
underConsiderationElsewherebooleanاختياريهل الموضوع منظور أمام جهة أخرى؟ نفس المعاملة.
systematicAnalysisstringاختياريالتحليل النظامي، حتى 50,000 حرف.
attachmentsobject[]اختياريناتج صفحة، object لكل ملف.
statementRequestedAtstringاختياريتاريخ طلب الإفادة، حتى 100 حرف.
respondentStatementstringاختياريإفادة المشتكى عليه إن وصلت، حتى 50,000 حرف.
webhook, webhook_headers, webhook_body—مهم جداًاختياري لتشغيل الطلب بشكل غير متزامن (انظر الأساسيات المشتركة).
request
{
  "complainant": { "capacity": "أصالة عن نفسه", "identityType": "هوية وطنية", "nationality": "سعودي" },
  "respondent": { "capacity": "فرد" },
  "facts": "تعاقدت مع المحامي على الترافع عني في قضية تجارية بأتعاب قدرها 30000 ريال، وسددت كامل المبلغ عند التعاقد ...",
  "requests": "التحقق مما وقع من المحامي من إخلال بالتزاماته المهنية، وإلزامه برد الأتعاب",
  "classifications": ["عدم التزام المحامي بالمواعيد المحددة نظاماً"],
  "hasContractualRelationship": true,
  "underConsiderationElsewhere": false,
  "systematicAnalysis": "بمراجعة محاضر الجلسات يتبين عدم حضور وكيل المدعي في الجلسات الثلاث دون عذر مدون.",
  "attachments": [
    { "نوع_المستند": "عقد أتعاب", "الأتعاب": 30000, "التاريخ": "05-01-2026" },
    { "doc_type": "hearing_minutes", "التاريخ": "14-02-2026", "حضور_وكيل_المدعي": "لم يحضر" }
  ],
  "statementRequestedAt": "2026-04-01",
  "respondentStatement": "أفيد بأنني تابعت القضية وحضرت ما يلزم من الجلسات وكنت على تواصل مستمر مع الموكل.",
  "webhook": "https://insaf.example/velents/webhook"
}

Response — 200

الحقلالنوعالشرح
requestTypeIdnumber1 أو 2 أو 3.
recommendations[]object[]عنصر لكل قرار مقترح (score ≥ 0.5)، الأعلى أولاً، بحد أقصى 5. إن وُجد أكثر من سبب لنفس القرار يبقى الأعلى عنصراً والباقي في otherReasons[] ({ reason, score, rationale }) مع description من الـ rubric.
recommendationCountnumberعدد recommendations.
isCompositebooleantrue إذا وُجد أكثر من قرار مختلف.
scorecard[]object[]القواعد الـ 19 كلها، الأعلى أولاً، وذات score = null في الآخر.
violations[]object[]المخالفات المقيّمة في الملف، الأعلى أولاً: violationId, violationName, categoryId, categoryName, score (0–1), rationale, evidence[] (حرفي).
classifications[]object[]كل نص في classifications بالطلب ومقابله في القائمة: name, violationId, categoryId, categoryName (null إن لم يوجد مقابل).
statementStatusstringمحسوبة من الملف: not_requested أو requested_no_reply أو received.
summarystringجملة أو جملتان بالعربية تلخّص القرار.

عنصر recommendations[] و scorecard[]

Fieldالشرح
recommendationIdid القرار في lookup التوصيات عند إنصاف، أو null.
recommendation, reason, labelالقرار (بالاسم في lookup إنصاف إن وجد) وسببه، و label هو الاثنان معاً.
stageمرحلة القاعدة (مثلاً "الفحص أو الدراسة"، "بعد الإفادة").
eligiblefalse إذا كانت المرحلة تستبعد القاعدة، أو القرار غير منشور عند إنصاف لنوع الطلب.
scoreمن 0 إلى 1، أو null إذا كانت غير eligible أو لم تُقيّم (وليس صفراً).
recommendedالـ score وصل إلى الـ threshold.
rationaleالتسبيب.
evidence[]مقتطفات حرفية من ملف الشكوى فقط.
violationIds[]المخالفات من violations التي بُنيت عليها القاعدة.
scopeيظهر فقط إن كانت له قيمة.
response
{
  "requestTypeId": 1,
  "recommendations": [
    {
      "recommendationId": 3,
      "recommendation": "الإحالة إلى الإدارة العامة للمحاماة لاستكمال إجراءات التحقيق",
      "reason": "ظهور عدم اتساق بين الإفادة والمستندات",
      "label": "الإحالة إلى الإدارة العامة للمحاماة لاستكمال إجراءات التحقيق - ظهور عدم اتساق بين الإفادة والمستندات",
      "description": "تُقترح الإحالة إذا وردت الإفادة والمستندات وظهر تعارض أو عدم اتساق جوهري ...",
      "stage": "بعد الإفادة",
      "eligible": true,
      "score": 1,
      "recommended": true,
      "rationale": "أفاد المحامي بحضور الجلسات، بينما تُثبت المحاضر عدم حضور وكيل المدعي",
      "evidence": ["لم يحضر أي جلسة من الجلسات الثلاث المحددة"],
      "violationIds": [12],
      "otherReasons": []
    }
  ],
  "recommendationCount": 1,
  "isComposite": false,
  "scorecard": [
    { "...": "القاعدة السابقة" },
    {
      "recommendation": "حفظ الشكوى", "reason": "عدم الاختصاص", "label": "حفظ الشكوى - عدم الاختصاص",
      "stage": "الفحص أو الدراسة", "eligible": true, "score": 0, "recommended": false,
      "rationale": "النزاع يتعلق بأداء مهني لا بمطالبة مالية بحتة", "evidence": [], "violationIds": []
    }
  ],
  "violations": [
    {
      "violationId": 12, "violationName": "عدم التزام المحامي بالمواعيد المحددة نظاماً",
      "categoryId": 10, "categoryName": "...", "score": 0.9, "rationale": "...",
      "evidence": ["لم يحضر أي جلسة من الجلسات الثلاث المحددة"]
    }
  ],
  "classifications": [
    { "name": "عدم التزام المحامي بالمواعيد المحددة نظاماً", "violationId": 12, "categoryId": 10, "categoryName": "..." }
  ],
  "statementStatus": "received",
  "summary": "توصية بالإحالة إلى الإدارة العامة للمحاماة لاستكمال إجراءات التحقيق، لتعارض إفادة المشتكى عليه مع محاضر الجلسات.",
  "apiProcessingDuration": 21,
  "apiProcessingDurationFormatted": "00:21"
}

Errors

StatusCodeالسبب
400INVALID_INPUTfacts ناقص أو طوله خارج 20–50,000.
502ANALYSIS_FAILED / NO_RESULTلم تُنتج التوصية.
502 / 503CATALOGUE_EMPTY / CATALOGUE_UNAVAILABLEقائمة المخالفات، كما في الخدمة 2.
502RECOMMENDATIONS_EMPTYإنصاف لم تنشر قرارات لنوع الطلب هذا.
503RECOMMENDATIONS_UNAVAILABLElookup التوصيات عند إنصاف غير متاح.
503SERVICE_BUSYالـ upstream مشغول بعد المحاولات. أعد نفس الطلب.