الخدمة 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
| الحقل | النوع | مطلوب | الشرح |
|---|---|---|---|
facts | string | إجباري | الوقائع، من 20 إلى 50,000 حرف. الحقل الإجباري الوحيد. |
request_type | string | اختياري | نفس قيم الخدمة 2. الافتراضي complaint. يحدد قائمة المخالفات والقرارات المسموحة. |
complainant | object | اختياري | بيانات المشتكي: name, capacity, identityType, nationality (كلها اختيارية). capacity فقط يدخل في التحليل حالياً. |
respondent | object | اختياري | بيانات المشتكى عليه، بنفس الشكل. |
requests | string | اختياري | الطلبات، حتى 20,000 حرف. |
classifications | string[] | اختياري | نصوص المخالفات المرفقة بالشكوى. |
hasContractualRelationship | boolean | اختياري | هل توجد علاقة تعاقدية؟ عدم الإرسال = "غير محدد" وليس false. |
underConsiderationElsewhere | boolean | اختياري | هل الموضوع منظور أمام جهة أخرى؟ نفس المعاملة. |
systematicAnalysis | string | اختياري | التحليل النظامي، حتى 50,000 حرف. |
attachments | object[] | اختياري | ناتج صفحة، object لكل ملف. |
statementRequestedAt | string | اختياري | تاريخ طلب الإفادة، حتى 100 حرف. |
respondentStatement | string | اختياري | إفادة المشتكى عليه إن وصلت، حتى 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
| الحقل | النوع | الشرح |
|---|---|---|
requestTypeId | number | 1 أو 2 أو 3. |
recommendations[] | object[] | عنصر لكل قرار مقترح (score ≥ 0.5)، الأعلى أولاً، بحد أقصى 5. إن وُجد أكثر من سبب لنفس القرار يبقى الأعلى عنصراً والباقي في otherReasons[] ({ reason, score, rationale }) مع description من الـ rubric. |
recommendationCount | number | عدد recommendations. |
isComposite | boolean | true إذا وُجد أكثر من قرار مختلف. |
scorecard[] | object[] | القواعد الـ 19 كلها، الأعلى أولاً، وذات score = null في الآخر. |
violations[] | object[] | المخالفات المقيّمة في الملف، الأعلى أولاً: violationId, violationName, categoryId, categoryName, score (0–1), rationale, evidence[] (حرفي). |
classifications[] | object[] | كل نص في classifications بالطلب ومقابله في القائمة: name, violationId, categoryId, categoryName (null إن لم يوجد مقابل). |
statementStatus | string | محسوبة من الملف: not_requested أو requested_no_reply أو received. |
summary | string | جملة أو جملتان بالعربية تلخّص القرار. |
عنصر recommendations[] و scorecard[]
| Field | الشرح |
|---|---|
recommendationId | id القرار في lookup التوصيات عند إنصاف، أو null. |
recommendation, reason, label | القرار (بالاسم في lookup إنصاف إن وجد) وسببه، و label هو الاثنان معاً. |
stage | مرحلة القاعدة (مثلاً "الفحص أو الدراسة"، "بعد الإفادة"). |
eligible | false إذا كانت المرحلة تستبعد القاعدة، أو القرار غير منشور عند إنصاف لنوع الطلب. |
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
| Status | Code | السبب |
|---|---|---|
| 400 | INVALID_INPUT | facts ناقص أو طوله خارج 20–50,000. |
| 502 | ANALYSIS_FAILED / NO_RESULT | لم تُنتج التوصية. |
| 502 / 503 | CATALOGUE_EMPTY / CATALOGUE_UNAVAILABLE | قائمة المخالفات، كما في الخدمة 2. |
| 502 | RECOMMENDATIONS_EMPTY | إنصاف لم تنشر قرارات لنوع الطلب هذا. |
| 503 | RECOMMENDATIONS_UNAVAILABLE | lookup التوصيات عند إنصاف غير متاح. |
| 503 | SERVICE_BUSY | الـ upstream مشغول بعد المحاولات. أعد نفس الطلب. |