---
title: "المجلس: دليل API فريقي"
description: "مواضيع النقاش داخل المشروع. معرّفات ثابتة (mjl-)، ويبقى الـ slug مقبولاً. مسارات المجلس في REST API فريقي: البارامترات، وجسم الطلب، وأمثلة الاستجابة"
url: https://fareeqy.com/api/v1/docs/discussions
language: ar
---

# المجلس

مواضيع النقاش داخل المشروع. معرّفات ثابتة (mjl-)، ويبقى الـ slug مقبولاً.

عنوان الخدمة `https://app.fareeqy.com/api/v1`

المحتويات

في هذه الصفحة

-   شكل المورد
-   عرض مواضيع مجلس المشروع
-   إنشاء موضوع في المجلس ونشره
-   عرض موضوع في المجلس
-   تعديل موضوع في المجلس
-   حذف موضوع من المجلس
-   الرد على موضوع في المجلس
-   عرض موضوع في المجلس بمعرّفه الثابت
-   تعديل موضوع في المجلس بمعرّفه الثابت
-   حذف موضوع من المجلس بمعرّفه الثابت
-   الرد على موضوع في المجلس بمعرّفه الثابت

المسارات

-   [الحساب](https://fareeqy.com/api/v1/docs/account)
-   [الأحداث](https://fareeqy.com/api/v1/docs/events)
-   [المشاريع](https://fareeqy.com/api/v1/docs/projects)
-   [الأعضاء](https://fareeqy.com/api/v1/docs/members)
-   [قوائم المهام](https://fareeqy.com/api/v1/docs/task-lists)
-   [المهام](https://fareeqy.com/api/v1/docs/tasks)
-   [التعليقات](https://fareeqy.com/api/v1/docs/comments)
-   [المجلس](https://fareeqy.com/api/v1/docs/discussions)
-   [الملفات](https://fareeqy.com/api/v1/docs/files)
-   [المجلدات](https://fareeqy.com/api/v1/docs/folders)

المزيد

-   [سجل التغييرات](https://fareeqy.com/api/v1/docs/changelog)

في هذه الصفحة

-   شكل المورد
-   عرض مواضيع مجلس المشروع
-   إنشاء موضوع في المجلس ونشره
-   عرض موضوع في المجلس
-   تعديل موضوع في المجلس
-   حذف موضوع من المجلس
-   الرد على موضوع في المجلس
-   عرض موضوع في المجلس بمعرّفه الثابت
-   تعديل موضوع في المجلس بمعرّفه الثابت
-   حذف موضوع من المجلس بمعرّفه الثابت
-   الرد على موضوع في المجلس بمعرّفه الثابت

المسارات

-   [الحساب](https://fareeqy.com/api/v1/docs/account)
-   [الأحداث](https://fareeqy.com/api/v1/docs/events)
-   [المشاريع](https://fareeqy.com/api/v1/docs/projects)
-   [الأعضاء](https://fareeqy.com/api/v1/docs/members)
-   [قوائم المهام](https://fareeqy.com/api/v1/docs/task-lists)
-   [المهام](https://fareeqy.com/api/v1/docs/tasks)
-   [التعليقات](https://fareeqy.com/api/v1/docs/comments)
-   [المجلس](https://fareeqy.com/api/v1/docs/discussions)
-   [الملفات](https://fareeqy.com/api/v1/docs/files)
-   [المجلدات](https://fareeqy.com/api/v1/docs/folders)

المزيد

-   [سجل التغييرات](https://fareeqy.com/api/v1/docs/changelog)

## شكل المورد

الحقول التي ترجع داخل `data` في مسارات هذه المجموعة.

`id` string

المعرّف الثابت لموضوع المجلس. ويبقى الـ slug مقبولاً في كل موضع يُعاد إرساله فيه.

`url` string | null

العنوان الكامل للصفحة التي يفتحها الشخص في فريقي.

`title` string

`body` string | null

النص العادي المقابل للمتن المنسّق.

`category` string | null

`author` string | null

`replies_count` integer

`created_at` string (date-time)

Discussion نسخ

 `{   "id": "mjl-6khz2",   "url": "https://app.fareeqy.com/majlis/mjl-6khz2",   "title": "اقتراح لتحسين صفحة التسعير",   "body": "أقترح نعرض الباقات في جدول مقارنة واحد بدل البطاقات المنفصلة.",   "category": "فكرة",   "author": "سارة العتيبي",   "replies_count": 4,   "created_at": "2026-07-08T14:02:55.000+03:00" }`

### عرض مواضيع مجلس المشروع

GET /projects/ {project\_id} /discussions يتطلب `discussions:read`

المواضيع المنشورة وحدها، فلا تظهر المسودات ولا المحذوفة. الأحدث أولاً.

#### بارامترات المسار

`project_id` string مطلوب

المعرّف الثابت للمشروع، أو الـ slug الخاص به.

#### بارامترات الاستعلام

`limit` integer

حجم الصفحة. الافتراضي 50، والحد الأقصى 100، وما زاد عنه يُقصَر عليه.

الافتراضي: `50`

`offset` integer

عدد السجلات التي تُتخطّى. الافتراضي 0.

الافتراضي: `0`

#### مثال الطلب

cURL نسخ

 `curl "https://app.fareeqy.com/api/v1/projects/prj-8f3kd/discussions" \   -H "Authorization: Bearer $FAREEQY_API_KEY"`

#### مثال الاستجابة

200 نسخ

 `{   "data": [     {       "id": "mjl-2wq7d",       "url": "https://app.fareeqy.com/majlis/mjl-2wq7d",       "title": "قرار: توحيد هوية التقارير المُصدَّرة",       "body": "اتفقنا في اجتماع الاثنين على أن كل تقرير يخرج من فريقي يحمل هوية الشركة نفسها: الشعار في الترويسة، ولون العناوين #00674F، والتاريخ بالهجري والميلادي معاً في الصفحة الأولى.\n\nالسبب أن التقارير التي أرسلناها للمستثمرين الربع الماضي خرجت بثلاثة أشكال مختلفة لأن كل واحد منا صدّرها من شاشة مختلفة، فبدت وكأنها من ثلاث شركات.\n\nالتنفيذ على فريق التصميم قبل نهاية الشهر، والمرجع ملف الهوية المرفق في مجلد «الهوية البصرية». من عنده اعتراض فليكتبه هنا قبل الأحد، وبعدها يصير القرار نافذاً.",       "category": "قرار",       "author": "سارة العتيبي",       "replies_count": 7,       "created_at": "2026-07-21T09:12:44.000+03:00"     },     {       "id": "mjl-6khz2",       "url": "https://app.fareeqy.com/majlis/mjl-6khz2",       "title": "اقتراح لتحسين صفحة التسعير",       "body": "أقترح نعرض الباقات في جدول مقارنة واحد بدل البطاقات المنفصلة.\n\nلاحظت من تسجيلات الجلسات أن الزائر يفتح البطاقات الأربع واحدة بعد الأخرى ثم يعود للأعلى، وهذا يعني أنه يحاول المقارنة ولا تسعفه الواجهة. الجدول يحل هذا في نظرة واحدة.",       "category": "فكرة",       "author": "عبدالله المطيري",       "replies_count": 4,       "created_at": "2026-07-08T14:02:55.000+03:00"     },     {       "id": "mjl-9nc4t",       "url": "https://app.fareeqy.com/majlis/mjl-9nc4t",       "title": "إجازة فريق التطوير الأسبوع القادم",       "body": "فريق التطوير في إجازة من الأحد إلى الثلاثاء. أي طلب عاجل يُرفع هنا وسنتابعه، وما عدا ذلك يُجدول بعد العودة.",       "category": "إعلان",       "author": "نورة الحربي",       "replies_count": 2,       "created_at": "2026-07-02T08:30:10.000+03:00"     }   ],   "meta": {     "total": 3,     "limit": 50,     "offset": 0,     "count": 3   } }`

حالات الرفض: 401 403 404 429 اعرض أمثلة الرفض أخفِ أمثلة الرفض

401 `default`

Missing or invalid API key.

default نسخ

 `{   "error": {     "code": "unauthorized",     "message": "مفتاح الـ API غير صالح أو غير مُرسَل."   } }`

403 `forbidden`

Two different refusals share this status, and a client must tell them apart by `error.code`. `forbidden` means the key's scope or allowlist does not permit this operation, or Pundit denied the action. `plan_upgrade_required` means the company's plan carries no API access at all, so no key on it can ever succeed and there is nothing to retry.

This key may not perform this operation نسخ

 `{   "error": {     "code": "forbidden",     "message": "هذا الـ API key لا يملك صلاحية تنفيذ هذه العملية."   } }`

The company's plan carries no API access نسخ

 `{   "error": {     "code": "plan_upgrade_required",     "message": "خطة «الاحترافي» لا تشمل الوصول إلى API. رقِّ إلى «المتطور» أو «الإنتاجي» لتفعيله."   } }`

404 `not_found`

Resource not found or not accessible — also returned for EVERY endpoint when the company's `rest_api` feature flag is disabled (the surface is hidden). Lookups drill through the URL hierarchy, so another company's record is a 404 and never a leak. A path that matches no route at all answers 404 with the distinct code `unknown_endpoint` and echoes the path back, so a mistyped or half-built URL is told apart from a record that is missing or out of reach.

A record that is missing or out of reach نسخ

 `{   "error": {     "code": "not_found",     "message": "غير موجود، أو لا تملك صلاحية الوصول إليه."   } }`

A path that matches no endpoint نسخ

 `{   "error": {     "code": "unknown_endpoint",     "message": "لا يوجد endpoint يطابق GET /api/v1/projcts. راجع المسار في توثيق الـ API."   } }`

429 `rate_limit_exceeded`

Either the company's daily API allowance is spent ( `rate_limit_exceeded` ), or the per-key / per-IP burst throttle of 300 requests per minute fired. Both come back after a wait, so `Retry-After` is honest here. **The two bodies are not the same shape.** The daily-quota refusal uses the standard error envelope. The burst throttle is served by Rack::Attack ahead of the application, so its body is a flat `{"error": "<string>"}` with no `code`. A client that reads `error.code` has to tolerate `error` being a plain string.

Today's daily allowance is spent (application envelope) نسخ

 `{   "error": {     "code": "rate_limit_exceeded",     "message": "استهلكت رصيد اليوم من طلبات API في خطة «المتطور» (1000 طلب يوميًا). يتجدد الرصيد عند منتصف الليل بتوقيت Asia/Riyadh."   } }`

Over 300 requests in a minute (Rack::Attack body, flat error) نسخ

 `{   "error": "Rate limit exceeded. Please try again later." }`

[الأخطاء](https://fareeqy.com/api/v1/docs#errors)

### إنشاء موضوع في المجلس ونشره

POST /projects/ {project\_id} /discussions يتطلب `discussions:write`

ينشئ الموضوع وينشره في خطوة واحدة: يشترك جمهوره، ويصلهم الإشعار، ويُسجَّل الحدث في الخط الزمني.

#### بارامترات المسار

`project_id` string مطلوب

المعرّف الثابت للمشروع، أو الـ slug الخاص به.

#### جسم الطلب

`title` string مطلوب

`body` string | null

متن بنص منسّق، ويُرسل نصاً عادياً.

#### مثال الطلب

cURL نسخ

 `curl -X POST "https://app.fareeqy.com/api/v1/projects/prj-8f3kd/discussions" \   -H "Authorization: Bearer $FAREEQY_API_KEY" \   -H "Content-Type: application/json" \   -d '{"title":"اقتراح لتحسين صفحة التسعير","body":"أقترح نعرض الباقات في جدول مقارنة واحد بدل البطاقات المنفصلة."}'`

#### مثال الاستجابة

201 نسخ

 `{   "data": {     "id": "mjl-6khz2",     "url": "https://app.fareeqy.com/majlis/mjl-6khz2",     "title": "اقتراح لتحسين صفحة التسعير",     "body": "أقترح نعرض الباقات في جدول مقارنة واحد بدل البطاقات المنفصلة.",     "category": "فكرة",     "author": "سارة العتيبي",     "replies_count": 4,     "created_at": "2026-07-08T14:02:55.000+03:00"   } }`

حالات الرفض: 401 403 404 409 422 429 اعرض أمثلة الرفض أخفِ أمثلة الرفض

401 `default`

Missing or invalid API key.

default نسخ

 `{   "error": {     "code": "unauthorized",     "message": "مفتاح الـ API غير صالح أو غير مُرسَل."   } }`

403 `forbidden`

Two different refusals share this status, and a client must tell them apart by `error.code`. `forbidden` means the key's scope or allowlist does not permit this operation, or Pundit denied the action. `plan_upgrade_required` means the company's plan carries no API access at all, so no key on it can ever succeed and there is nothing to retry.

This key may not perform this operation نسخ

 `{   "error": {     "code": "forbidden",     "message": "هذا الـ API key لا يملك صلاحية تنفيذ هذه العملية."   } }`

The company's plan carries no API access نسخ

 `{   "error": {     "code": "plan_upgrade_required",     "message": "خطة «الاحترافي» لا تشمل الوصول إلى API. رقِّ إلى «المتطور» أو «الإنتاجي» لتفعيله."   } }`

404 `not_found`

Resource not found or not accessible — also returned for EVERY endpoint when the company's `rest_api` feature flag is disabled (the surface is hidden). Lookups drill through the URL hierarchy, so another company's record is a 404 and never a leak. A path that matches no route at all answers 404 with the distinct code `unknown_endpoint` and echoes the path back, so a mistyped or half-built URL is told apart from a record that is missing or out of reach.

A record that is missing or out of reach نسخ

 `{   "error": {     "code": "not_found",     "message": "غير موجود، أو لا تملك صلاحية الوصول إليه."   } }`

A path that matches no endpoint نسخ

 `{   "error": {     "code": "unknown_endpoint",     "message": "لا يوجد endpoint يطابق GET /api/v1/projcts. راجع المسار في توثيق الـ API."   } }`

409 `default`

A uniqueness/record conflict; retry.

default نسخ

 `{   "error": {     "code": "conflict",     "message": "تعذّر إتمام العملية بسبب تعارض. أعد المحاولة."   } }`

422 `default`

A caller-fixable bad request (validation error, bad date, bad enum).

default نسخ

 `{   "error": {     "code": "unprocessable_entity",     "message": "قيمة due_at غير صالحة؛ أرسل تاريخاً مثل 2026-07-20. المهمة تُستحق في يوم، وأي وقت ترسله يُهمل."   } }`

429 `rate_limit_exceeded`

Either the company's daily API allowance is spent ( `rate_limit_exceeded` ), or the per-key / per-IP burst throttle of 300 requests per minute fired. Both come back after a wait, so `Retry-After` is honest here. **The two bodies are not the same shape.** The daily-quota refusal uses the standard error envelope. The burst throttle is served by Rack::Attack ahead of the application, so its body is a flat `{"error": "<string>"}` with no `code`. A client that reads `error.code` has to tolerate `error` being a plain string.

Today's daily allowance is spent (application envelope) نسخ

 `{   "error": {     "code": "rate_limit_exceeded",     "message": "استهلكت رصيد اليوم من طلبات API في خطة «المتطور» (1000 طلب يوميًا). يتجدد الرصيد عند منتصف الليل بتوقيت Asia/Riyadh."   } }`

Over 300 requests in a minute (Rack::Attack body, flat error) نسخ

 `{   "error": "Rate limit exceeded. Please try again later." }`

[الأخطاء](https://fareeqy.com/api/v1/docs#errors)

### عرض موضوع في المجلس

GET /projects/ {project\_id} /discussions/ {id} يتطلب `discussions:read`

#### بارامترات المسار

`project_id` string مطلوب

المعرّف الثابت للمشروع، أو الـ slug الخاص به.

`id` string مطلوب

المعرّف الثابت لموضوع المجلس (mjl-8f3kd)، أو الـ slug الخاص به، وهو فريد داخل مشروعه.

#### مثال الطلب

cURL نسخ

 `curl "https://app.fareeqy.com/api/v1/projects/prj-8f3kd/discussions/mjl-6khz2" \   -H "Authorization: Bearer $FAREEQY_API_KEY"`

#### مثال الاستجابة

200 نسخ

 `{   "data": {     "id": "mjl-6khz2",     "url": "https://app.fareeqy.com/majlis/mjl-6khz2",     "title": "اقتراح لتحسين صفحة التسعير",     "body": "أقترح نعرض الباقات في جدول مقارنة واحد بدل البطاقات المنفصلة.",     "category": "فكرة",     "author": "سارة العتيبي",     "replies_count": 4,     "created_at": "2026-07-08T14:02:55.000+03:00"   } }`

حالات الرفض: 401 403 404 429 اعرض أمثلة الرفض أخفِ أمثلة الرفض

401 `default`

Missing or invalid API key.

default نسخ

 `{   "error": {     "code": "unauthorized",     "message": "مفتاح الـ API غير صالح أو غير مُرسَل."   } }`

403 `forbidden`

Two different refusals share this status, and a client must tell them apart by `error.code`. `forbidden` means the key's scope or allowlist does not permit this operation, or Pundit denied the action. `plan_upgrade_required` means the company's plan carries no API access at all, so no key on it can ever succeed and there is nothing to retry.

This key may not perform this operation نسخ

 `{   "error": {     "code": "forbidden",     "message": "هذا الـ API key لا يملك صلاحية تنفيذ هذه العملية."   } }`

The company's plan carries no API access نسخ

 `{   "error": {     "code": "plan_upgrade_required",     "message": "خطة «الاحترافي» لا تشمل الوصول إلى API. رقِّ إلى «المتطور» أو «الإنتاجي» لتفعيله."   } }`

404 `not_found`

Resource not found or not accessible — also returned for EVERY endpoint when the company's `rest_api` feature flag is disabled (the surface is hidden). Lookups drill through the URL hierarchy, so another company's record is a 404 and never a leak. A path that matches no route at all answers 404 with the distinct code `unknown_endpoint` and echoes the path back, so a mistyped or half-built URL is told apart from a record that is missing or out of reach.

A record that is missing or out of reach نسخ

 `{   "error": {     "code": "not_found",     "message": "غير موجود، أو لا تملك صلاحية الوصول إليه."   } }`

A path that matches no endpoint نسخ

 `{   "error": {     "code": "unknown_endpoint",     "message": "لا يوجد endpoint يطابق GET /api/v1/projcts. راجع المسار في توثيق الـ API."   } }`

429 `rate_limit_exceeded`

Either the company's daily API allowance is spent ( `rate_limit_exceeded` ), or the per-key / per-IP burst throttle of 300 requests per minute fired. Both come back after a wait, so `Retry-After` is honest here. **The two bodies are not the same shape.** The daily-quota refusal uses the standard error envelope. The burst throttle is served by Rack::Attack ahead of the application, so its body is a flat `{"error": "<string>"}` with no `code`. A client that reads `error.code` has to tolerate `error` being a plain string.

Today's daily allowance is spent (application envelope) نسخ

 `{   "error": {     "code": "rate_limit_exceeded",     "message": "استهلكت رصيد اليوم من طلبات API في خطة «المتطور» (1000 طلب يوميًا). يتجدد الرصيد عند منتصف الليل بتوقيت Asia/Riyadh."   } }`

Over 300 requests in a minute (Rack::Attack body, flat error) نسخ

 `{   "error": "Rate limit exceeded. Please try again later." }`

[الأخطاء](https://fareeqy.com/api/v1/docs#errors)

### تعديل موضوع في المجلس

PATCH /projects/ {project\_id} /discussions/ {id} يتطلب `discussions:write`

#### بارامترات المسار

`project_id` string مطلوب

المعرّف الثابت للمشروع، أو الـ slug الخاص به.

`id` string مطلوب

المعرّف الثابت لموضوع المجلس (mjl-8f3kd)، أو الـ slug الخاص به، وهو فريد داخل مشروعه.

#### جسم الطلب

`title` string

`body` string | null

#### مثال الطلب

cURL نسخ

 `curl -X PATCH "https://app.fareeqy.com/api/v1/projects/prj-8f3kd/discussions/mjl-6khz2" \   -H "Authorization: Bearer $FAREEQY_API_KEY" \   -H "Content-Type: application/json" \   -d '{"body":"أقترح نعرض الباقات في جدول مقارنة واحد، ونثبت زر التجربة أعلى الصفحة."}'`

#### مثال الاستجابة

200 نسخ

 `{   "data": {     "id": "mjl-6khz2",     "url": "https://app.fareeqy.com/majlis/mjl-6khz2",     "title": "اقتراح لتحسين صفحة التسعير",     "body": "أقترح نعرض الباقات في جدول مقارنة واحد بدل البطاقات المنفصلة.",     "category": "فكرة",     "author": "سارة العتيبي",     "replies_count": 4,     "created_at": "2026-07-08T14:02:55.000+03:00"   } }`

حالات الرفض: 401 403 404 409 422 429 اعرض أمثلة الرفض أخفِ أمثلة الرفض

401 `default`

Missing or invalid API key.

default نسخ

 `{   "error": {     "code": "unauthorized",     "message": "مفتاح الـ API غير صالح أو غير مُرسَل."   } }`

403 `forbidden`

Two different refusals share this status, and a client must tell them apart by `error.code`. `forbidden` means the key's scope or allowlist does not permit this operation, or Pundit denied the action. `plan_upgrade_required` means the company's plan carries no API access at all, so no key on it can ever succeed and there is nothing to retry.

This key may not perform this operation نسخ

 `{   "error": {     "code": "forbidden",     "message": "هذا الـ API key لا يملك صلاحية تنفيذ هذه العملية."   } }`

The company's plan carries no API access نسخ

 `{   "error": {     "code": "plan_upgrade_required",     "message": "خطة «الاحترافي» لا تشمل الوصول إلى API. رقِّ إلى «المتطور» أو «الإنتاجي» لتفعيله."   } }`

404 `not_found`

Resource not found or not accessible — also returned for EVERY endpoint when the company's `rest_api` feature flag is disabled (the surface is hidden). Lookups drill through the URL hierarchy, so another company's record is a 404 and never a leak. A path that matches no route at all answers 404 with the distinct code `unknown_endpoint` and echoes the path back, so a mistyped or half-built URL is told apart from a record that is missing or out of reach.

A record that is missing or out of reach نسخ

 `{   "error": {     "code": "not_found",     "message": "غير موجود، أو لا تملك صلاحية الوصول إليه."   } }`

A path that matches no endpoint نسخ

 `{   "error": {     "code": "unknown_endpoint",     "message": "لا يوجد endpoint يطابق GET /api/v1/projcts. راجع المسار في توثيق الـ API."   } }`

409 `default`

A uniqueness/record conflict; retry.

default نسخ

 `{   "error": {     "code": "conflict",     "message": "تعذّر إتمام العملية بسبب تعارض. أعد المحاولة."   } }`

422 `default`

A caller-fixable bad request (validation error, bad date, bad enum).

default نسخ

 `{   "error": {     "code": "unprocessable_entity",     "message": "قيمة due_at غير صالحة؛ أرسل تاريخاً مثل 2026-07-20. المهمة تُستحق في يوم، وأي وقت ترسله يُهمل."   } }`

429 `rate_limit_exceeded`

Either the company's daily API allowance is spent ( `rate_limit_exceeded` ), or the per-key / per-IP burst throttle of 300 requests per minute fired. Both come back after a wait, so `Retry-After` is honest here. **The two bodies are not the same shape.** The daily-quota refusal uses the standard error envelope. The burst throttle is served by Rack::Attack ahead of the application, so its body is a flat `{"error": "<string>"}` with no `code`. A client that reads `error.code` has to tolerate `error` being a plain string.

Today's daily allowance is spent (application envelope) نسخ

 `{   "error": {     "code": "rate_limit_exceeded",     "message": "استهلكت رصيد اليوم من طلبات API في خطة «المتطور» (1000 طلب يوميًا). يتجدد الرصيد عند منتصف الليل بتوقيت Asia/Riyadh."   } }`

Over 300 requests in a minute (Rack::Attack body, flat error) نسخ

 `{   "error": "Rate limit exceeded. Please try again later." }`

[الأخطاء](https://fareeqy.com/api/v1/docs#errors)

### حذف موضوع من المجلس

DELETE /projects/ {project\_id} /discussions/ {id} يتطلب `discussions:destructive`

حذف مبدئي، يستطيع المدير استعادته.

#### بارامترات المسار

`project_id` string مطلوب

المعرّف الثابت للمشروع، أو الـ slug الخاص به.

`id` string مطلوب

المعرّف الثابت لموضوع المجلس (mjl-8f3kd)، أو الـ slug الخاص به، وهو فريد داخل مشروعه.

#### مثال الطلب

cURL نسخ

 `curl -X DELETE "https://app.fareeqy.com/api/v1/projects/prj-8f3kd/discussions/mjl-6khz2" \   -H "Authorization: Bearer $FAREEQY_API_KEY"`

#### مثال الاستجابة

200 نسخ

 `{   "data": {     "deleted": true,     "recoverable": true,     "discussion": {       "title": "اقتراح لتحسين صفحة التسعير",       "id": "mjl-6khz2"     }   } }`

حالات الرفض: 401 403 404 429 اعرض أمثلة الرفض أخفِ أمثلة الرفض

401 `default`

Missing or invalid API key.

default نسخ

 `{   "error": {     "code": "unauthorized",     "message": "مفتاح الـ API غير صالح أو غير مُرسَل."   } }`

403 `forbidden`

Two different refusals share this status, and a client must tell them apart by `error.code`. `forbidden` means the key's scope or allowlist does not permit this operation, or Pundit denied the action. `plan_upgrade_required` means the company's plan carries no API access at all, so no key on it can ever succeed and there is nothing to retry.

This key may not perform this operation نسخ

 `{   "error": {     "code": "forbidden",     "message": "هذا الـ API key لا يملك صلاحية تنفيذ هذه العملية."   } }`

The company's plan carries no API access نسخ

 `{   "error": {     "code": "plan_upgrade_required",     "message": "خطة «الاحترافي» لا تشمل الوصول إلى API. رقِّ إلى «المتطور» أو «الإنتاجي» لتفعيله."   } }`

404 `not_found`

Resource not found or not accessible — also returned for EVERY endpoint when the company's `rest_api` feature flag is disabled (the surface is hidden). Lookups drill through the URL hierarchy, so another company's record is a 404 and never a leak. A path that matches no route at all answers 404 with the distinct code `unknown_endpoint` and echoes the path back, so a mistyped or half-built URL is told apart from a record that is missing or out of reach.

A record that is missing or out of reach نسخ

 `{   "error": {     "code": "not_found",     "message": "غير موجود، أو لا تملك صلاحية الوصول إليه."   } }`

A path that matches no endpoint نسخ

 `{   "error": {     "code": "unknown_endpoint",     "message": "لا يوجد endpoint يطابق GET /api/v1/projcts. راجع المسار في توثيق الـ API."   } }`

429 `rate_limit_exceeded`

Either the company's daily API allowance is spent ( `rate_limit_exceeded` ), or the per-key / per-IP burst throttle of 300 requests per minute fired. Both come back after a wait, so `Retry-After` is honest here. **The two bodies are not the same shape.** The daily-quota refusal uses the standard error envelope. The burst throttle is served by Rack::Attack ahead of the application, so its body is a flat `{"error": "<string>"}` with no `code`. A client that reads `error.code` has to tolerate `error` being a plain string.

Today's daily allowance is spent (application envelope) نسخ

 `{   "error": {     "code": "rate_limit_exceeded",     "message": "استهلكت رصيد اليوم من طلبات API في خطة «المتطور» (1000 طلب يوميًا). يتجدد الرصيد عند منتصف الليل بتوقيت Asia/Riyadh."   } }`

Over 300 requests in a minute (Rack::Attack body, flat error) نسخ

 `{   "error": "Rate limit exceeded. Please try again later." }`

[الأخطاء](https://fareeqy.com/api/v1/docs#errors)

### الرد على موضوع في المجلس

POST /projects/ {project\_id} /discussions/ {id} /reply يتطلب `discussions:write`

يضيف رداً، ويُرجَع الرد بالشكل نفسه الذي يُرجَع به التعليق.

#### بارامترات المسار

`project_id` string مطلوب

المعرّف الثابت للمشروع، أو الـ slug الخاص به.

`id` string مطلوب

المعرّف الثابت لموضوع المجلس (mjl-8f3kd)، أو الـ slug الخاص به، وهو فريد داخل مشروعه.

#### جسم الطلب

`content` string مطلوب

متن الرد بنص منسّق، ويُرسل نصاً عادياً.

#### مثال الطلب

cURL نسخ

 `curl -X POST "https://app.fareeqy.com/api/v1/projects/prj-8f3kd/discussions/mjl-6khz2/reply" \   -H "Authorization: Bearer $FAREEQY_API_KEY" \   -H "Content-Type: application/json" \   -d '{"content":"أتفق. الجدول أوضح، بشرط نبقي الأسعار ظاهرة بدون ضغط إضافي."}'`

#### مثال الاستجابة

201 نسخ

 `{   "data": {     "id": 512,     "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",     "content": "راجعت النسخة الأخيرة، ينقصنا حالة الخطأ في النموذج.",     "author": "عبدالله المطيري",     "created_at": "2026-07-15T09:48:03.000+03:00",     "updated_at": "2026-07-15T09:48:03.000+03:00",     "attachments": [       {         "id": 9031,         "name": "error-state.png",         "content_type": "image/png",         "byte_size": 184320       }     ]   } }`

حالات الرفض: 401 403 404 409 422 429 اعرض أمثلة الرفض أخفِ أمثلة الرفض

401 `default`

Missing or invalid API key.

default نسخ

 `{   "error": {     "code": "unauthorized",     "message": "مفتاح الـ API غير صالح أو غير مُرسَل."   } }`

403 `forbidden`

Two different refusals share this status, and a client must tell them apart by `error.code`. `forbidden` means the key's scope or allowlist does not permit this operation, or Pundit denied the action. `plan_upgrade_required` means the company's plan carries no API access at all, so no key on it can ever succeed and there is nothing to retry.

This key may not perform this operation نسخ

 `{   "error": {     "code": "forbidden",     "message": "هذا الـ API key لا يملك صلاحية تنفيذ هذه العملية."   } }`

The company's plan carries no API access نسخ

 `{   "error": {     "code": "plan_upgrade_required",     "message": "خطة «الاحترافي» لا تشمل الوصول إلى API. رقِّ إلى «المتطور» أو «الإنتاجي» لتفعيله."   } }`

404 `not_found`

Resource not found or not accessible — also returned for EVERY endpoint when the company's `rest_api` feature flag is disabled (the surface is hidden). Lookups drill through the URL hierarchy, so another company's record is a 404 and never a leak. A path that matches no route at all answers 404 with the distinct code `unknown_endpoint` and echoes the path back, so a mistyped or half-built URL is told apart from a record that is missing or out of reach.

A record that is missing or out of reach نسخ

 `{   "error": {     "code": "not_found",     "message": "غير موجود، أو لا تملك صلاحية الوصول إليه."   } }`

A path that matches no endpoint نسخ

 `{   "error": {     "code": "unknown_endpoint",     "message": "لا يوجد endpoint يطابق GET /api/v1/projcts. راجع المسار في توثيق الـ API."   } }`

409 `default`

A uniqueness/record conflict; retry.

default نسخ

 `{   "error": {     "code": "conflict",     "message": "تعذّر إتمام العملية بسبب تعارض. أعد المحاولة."   } }`

422 `default`

A caller-fixable bad request (validation error, bad date, bad enum).

default نسخ

 `{   "error": {     "code": "unprocessable_entity",     "message": "قيمة due_at غير صالحة؛ أرسل تاريخاً مثل 2026-07-20. المهمة تُستحق في يوم، وأي وقت ترسله يُهمل."   } }`

429 `rate_limit_exceeded`

Either the company's daily API allowance is spent ( `rate_limit_exceeded` ), or the per-key / per-IP burst throttle of 300 requests per minute fired. Both come back after a wait, so `Retry-After` is honest here. **The two bodies are not the same shape.** The daily-quota refusal uses the standard error envelope. The burst throttle is served by Rack::Attack ahead of the application, so its body is a flat `{"error": "<string>"}` with no `code`. A client that reads `error.code` has to tolerate `error` being a plain string.

Today's daily allowance is spent (application envelope) نسخ

 `{   "error": {     "code": "rate_limit_exceeded",     "message": "استهلكت رصيد اليوم من طلبات API في خطة «المتطور» (1000 طلب يوميًا). يتجدد الرصيد عند منتصف الليل بتوقيت Asia/Riyadh."   } }`

Over 300 requests in a minute (Rack::Attack body, flat error) نسخ

 `{   "error": "Rate limit exceeded. Please try again later." }`

[الأخطاء](https://fareeqy.com/api/v1/docs#errors)

### عرض موضوع في المجلس بمعرّفه الثابت

GET /discussions/ {id} يتطلب `discussions:read`

#### بارامترات المسار

`id` string مطلوب

المعرّف الثابت لموضوع المجلس (mjl-6khz2). ولا يُقبل الـ slug هنا.

#### مثال الطلب

cURL نسخ

 `curl "https://app.fareeqy.com/api/v1/discussions/mjl-6khz2" \   -H "Authorization: Bearer $FAREEQY_API_KEY"`

#### مثال الاستجابة

200 نسخ

 `{   "data": {     "id": "mjl-6khz2",     "url": "https://app.fareeqy.com/majlis/mjl-6khz2",     "title": "اقتراح لتحسين صفحة التسعير",     "body": "أقترح نعرض الباقات في جدول مقارنة واحد بدل البطاقات المنفصلة.",     "category": "فكرة",     "author": "سارة العتيبي",     "replies_count": 4,     "created_at": "2026-07-08T14:02:55.000+03:00"   } }`

حالات الرفض: 401 403 404 429 اعرض أمثلة الرفض أخفِ أمثلة الرفض

401 `default`

Missing or invalid API key.

default نسخ

 `{   "error": {     "code": "unauthorized",     "message": "مفتاح الـ API غير صالح أو غير مُرسَل."   } }`

403 `forbidden`

Two different refusals share this status, and a client must tell them apart by `error.code`. `forbidden` means the key's scope or allowlist does not permit this operation, or Pundit denied the action. `plan_upgrade_required` means the company's plan carries no API access at all, so no key on it can ever succeed and there is nothing to retry.

This key may not perform this operation نسخ

 `{   "error": {     "code": "forbidden",     "message": "هذا الـ API key لا يملك صلاحية تنفيذ هذه العملية."   } }`

The company's plan carries no API access نسخ

 `{   "error": {     "code": "plan_upgrade_required",     "message": "خطة «الاحترافي» لا تشمل الوصول إلى API. رقِّ إلى «المتطور» أو «الإنتاجي» لتفعيله."   } }`

404 `not_found`

Resource not found or not accessible — also returned for EVERY endpoint when the company's `rest_api` feature flag is disabled (the surface is hidden). Lookups drill through the URL hierarchy, so another company's record is a 404 and never a leak. A path that matches no route at all answers 404 with the distinct code `unknown_endpoint` and echoes the path back, so a mistyped or half-built URL is told apart from a record that is missing or out of reach.

A record that is missing or out of reach نسخ

 `{   "error": {     "code": "not_found",     "message": "غير موجود، أو لا تملك صلاحية الوصول إليه."   } }`

A path that matches no endpoint نسخ

 `{   "error": {     "code": "unknown_endpoint",     "message": "لا يوجد endpoint يطابق GET /api/v1/projcts. راجع المسار في توثيق الـ API."   } }`

429 `rate_limit_exceeded`

Either the company's daily API allowance is spent ( `rate_limit_exceeded` ), or the per-key / per-IP burst throttle of 300 requests per minute fired. Both come back after a wait, so `Retry-After` is honest here. **The two bodies are not the same shape.** The daily-quota refusal uses the standard error envelope. The burst throttle is served by Rack::Attack ahead of the application, so its body is a flat `{"error": "<string>"}` with no `code`. A client that reads `error.code` has to tolerate `error` being a plain string.

Today's daily allowance is spent (application envelope) نسخ

 `{   "error": {     "code": "rate_limit_exceeded",     "message": "استهلكت رصيد اليوم من طلبات API في خطة «المتطور» (1000 طلب يوميًا). يتجدد الرصيد عند منتصف الليل بتوقيت Asia/Riyadh."   } }`

Over 300 requests in a minute (Rack::Attack body, flat error) نسخ

 `{   "error": "Rate limit exceeded. Please try again later." }`

[الأخطاء](https://fareeqy.com/api/v1/docs#errors)

### تعديل موضوع في المجلس بمعرّفه الثابت

PATCH /discussions/ {id} يتطلب `discussions:write`

لا يتغير إلا ما ترسله.

#### بارامترات المسار

`id` string مطلوب

المعرّف الثابت لموضوع المجلس (mjl-6khz2). ولا يُقبل الـ slug هنا.

#### جسم الطلب

`title` string

`body` string | null

#### مثال الطلب

cURL نسخ

 `curl -X PATCH "https://app.fareeqy.com/api/v1/discussions/mjl-6khz2" \   -H "Authorization: Bearer $FAREEQY_API_KEY" \   -H "Content-Type: application/json" \   -d '{"body":"أقترح نعرض الباقات في جدول مقارنة واحد، ونثبت زر التجربة أعلى الصفحة."}'`

#### مثال الاستجابة

200 نسخ

 `{   "data": {     "id": "mjl-6khz2",     "url": "https://app.fareeqy.com/majlis/mjl-6khz2",     "title": "اقتراح لتحسين صفحة التسعير",     "body": "أقترح نعرض الباقات في جدول مقارنة واحد بدل البطاقات المنفصلة.",     "category": "فكرة",     "author": "سارة العتيبي",     "replies_count": 4,     "created_at": "2026-07-08T14:02:55.000+03:00"   } }`

حالات الرفض: 401 403 404 409 422 429 اعرض أمثلة الرفض أخفِ أمثلة الرفض

401 `default`

Missing or invalid API key.

default نسخ

 `{   "error": {     "code": "unauthorized",     "message": "مفتاح الـ API غير صالح أو غير مُرسَل."   } }`

403 `forbidden`

Two different refusals share this status, and a client must tell them apart by `error.code`. `forbidden` means the key's scope or allowlist does not permit this operation, or Pundit denied the action. `plan_upgrade_required` means the company's plan carries no API access at all, so no key on it can ever succeed and there is nothing to retry.

This key may not perform this operation نسخ

 `{   "error": {     "code": "forbidden",     "message": "هذا الـ API key لا يملك صلاحية تنفيذ هذه العملية."   } }`

The company's plan carries no API access نسخ

 `{   "error": {     "code": "plan_upgrade_required",     "message": "خطة «الاحترافي» لا تشمل الوصول إلى API. رقِّ إلى «المتطور» أو «الإنتاجي» لتفعيله."   } }`

404 `not_found`

Resource not found or not accessible — also returned for EVERY endpoint when the company's `rest_api` feature flag is disabled (the surface is hidden). Lookups drill through the URL hierarchy, so another company's record is a 404 and never a leak. A path that matches no route at all answers 404 with the distinct code `unknown_endpoint` and echoes the path back, so a mistyped or half-built URL is told apart from a record that is missing or out of reach.

A record that is missing or out of reach نسخ

 `{   "error": {     "code": "not_found",     "message": "غير موجود، أو لا تملك صلاحية الوصول إليه."   } }`

A path that matches no endpoint نسخ

 `{   "error": {     "code": "unknown_endpoint",     "message": "لا يوجد endpoint يطابق GET /api/v1/projcts. راجع المسار في توثيق الـ API."   } }`

409 `default`

A uniqueness/record conflict; retry.

default نسخ

 `{   "error": {     "code": "conflict",     "message": "تعذّر إتمام العملية بسبب تعارض. أعد المحاولة."   } }`

422 `default`

A caller-fixable bad request (validation error, bad date, bad enum).

default نسخ

 `{   "error": {     "code": "unprocessable_entity",     "message": "قيمة due_at غير صالحة؛ أرسل تاريخاً مثل 2026-07-20. المهمة تُستحق في يوم، وأي وقت ترسله يُهمل."   } }`

429 `rate_limit_exceeded`

Either the company's daily API allowance is spent ( `rate_limit_exceeded` ), or the per-key / per-IP burst throttle of 300 requests per minute fired. Both come back after a wait, so `Retry-After` is honest here. **The two bodies are not the same shape.** The daily-quota refusal uses the standard error envelope. The burst throttle is served by Rack::Attack ahead of the application, so its body is a flat `{"error": "<string>"}` with no `code`. A client that reads `error.code` has to tolerate `error` being a plain string.

Today's daily allowance is spent (application envelope) نسخ

 `{   "error": {     "code": "rate_limit_exceeded",     "message": "استهلكت رصيد اليوم من طلبات API في خطة «المتطور» (1000 طلب يوميًا). يتجدد الرصيد عند منتصف الليل بتوقيت Asia/Riyadh."   } }`

Over 300 requests in a minute (Rack::Attack body, flat error) نسخ

 `{   "error": "Rate limit exceeded. Please try again later." }`

[الأخطاء](https://fareeqy.com/api/v1/docs#errors)

### حذف موضوع من المجلس بمعرّفه الثابت

DELETE /discussions/ {id} يتطلب `discussions:destructive`

حذف مبدئي، يستطيع المدير استعادته.

#### بارامترات المسار

`id` string مطلوب

المعرّف الثابت لموضوع المجلس (mjl-6khz2). ولا يُقبل الـ slug هنا.

#### مثال الطلب

cURL نسخ

 `curl -X DELETE "https://app.fareeqy.com/api/v1/discussions/mjl-6khz2" \   -H "Authorization: Bearer $FAREEQY_API_KEY"`

#### مثال الاستجابة

200 نسخ

 `{   "data": {     "deleted": true,     "recoverable": true,     "discussion": {       "title": "تسعير الباقات",       "id": "mjl-6khz2"     }   } }`

حالات الرفض: 401 403 404 429 اعرض أمثلة الرفض أخفِ أمثلة الرفض

401 `default`

Missing or invalid API key.

default نسخ

 `{   "error": {     "code": "unauthorized",     "message": "مفتاح الـ API غير صالح أو غير مُرسَل."   } }`

403 `forbidden`

Two different refusals share this status, and a client must tell them apart by `error.code`. `forbidden` means the key's scope or allowlist does not permit this operation, or Pundit denied the action. `plan_upgrade_required` means the company's plan carries no API access at all, so no key on it can ever succeed and there is nothing to retry.

This key may not perform this operation نسخ

 `{   "error": {     "code": "forbidden",     "message": "هذا الـ API key لا يملك صلاحية تنفيذ هذه العملية."   } }`

The company's plan carries no API access نسخ

 `{   "error": {     "code": "plan_upgrade_required",     "message": "خطة «الاحترافي» لا تشمل الوصول إلى API. رقِّ إلى «المتطور» أو «الإنتاجي» لتفعيله."   } }`

404 `not_found`

Resource not found or not accessible — also returned for EVERY endpoint when the company's `rest_api` feature flag is disabled (the surface is hidden). Lookups drill through the URL hierarchy, so another company's record is a 404 and never a leak. A path that matches no route at all answers 404 with the distinct code `unknown_endpoint` and echoes the path back, so a mistyped or half-built URL is told apart from a record that is missing or out of reach.

A record that is missing or out of reach نسخ

 `{   "error": {     "code": "not_found",     "message": "غير موجود، أو لا تملك صلاحية الوصول إليه."   } }`

A path that matches no endpoint نسخ

 `{   "error": {     "code": "unknown_endpoint",     "message": "لا يوجد endpoint يطابق GET /api/v1/projcts. راجع المسار في توثيق الـ API."   } }`

429 `rate_limit_exceeded`

Either the company's daily API allowance is spent ( `rate_limit_exceeded` ), or the per-key / per-IP burst throttle of 300 requests per minute fired. Both come back after a wait, so `Retry-After` is honest here. **The two bodies are not the same shape.** The daily-quota refusal uses the standard error envelope. The burst throttle is served by Rack::Attack ahead of the application, so its body is a flat `{"error": "<string>"}` with no `code`. A client that reads `error.code` has to tolerate `error` being a plain string.

Today's daily allowance is spent (application envelope) نسخ

 `{   "error": {     "code": "rate_limit_exceeded",     "message": "استهلكت رصيد اليوم من طلبات API في خطة «المتطور» (1000 طلب يوميًا). يتجدد الرصيد عند منتصف الليل بتوقيت Asia/Riyadh."   } }`

Over 300 requests in a minute (Rack::Attack body, flat error) نسخ

 `{   "error": "Rate limit exceeded. Please try again later." }`

[الأخطاء](https://fareeqy.com/api/v1/docs#errors)

### الرد على موضوع في المجلس بمعرّفه الثابت

POST /discussions/ {id} /reply يتطلب `discussions:write`

#### بارامترات المسار

`id` string مطلوب

المعرّف الثابت لموضوع المجلس (mjl-6khz2). ولا يُقبل الـ slug هنا.

#### جسم الطلب

`content` string مطلوب

متن الرد بنص منسّق، ويُرسل نصاً عادياً.

#### مثال الطلب

cURL نسخ

 `curl -X POST "https://app.fareeqy.com/api/v1/discussions/mjl-6khz2/reply" \   -H "Authorization: Bearer $FAREEQY_API_KEY" \   -H "Content-Type: application/json" \   -d '{"content":"أتفق. الجدول أوضح، بشرط نبقي الأسعار ظاهرة بدون ضغط إضافي."}'`

#### مثال الاستجابة

201 نسخ

 `{   "data": {     "id": 512,     "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",     "content": "راجعت النسخة الأخيرة، ينقصنا حالة الخطأ في النموذج.",     "author": "عبدالله المطيري",     "created_at": "2026-07-15T09:48:03.000+03:00",     "updated_at": "2026-07-15T09:48:03.000+03:00",     "attachments": [       {         "id": 9031,         "name": "error-state.png",         "content_type": "image/png",         "byte_size": 184320       }     ]   } }`

حالات الرفض: 401 403 404 409 422 429 اعرض أمثلة الرفض أخفِ أمثلة الرفض

401 `default`

Missing or invalid API key.

default نسخ

 `{   "error": {     "code": "unauthorized",     "message": "مفتاح الـ API غير صالح أو غير مُرسَل."   } }`

403 `forbidden`

Two different refusals share this status, and a client must tell them apart by `error.code`. `forbidden` means the key's scope or allowlist does not permit this operation, or Pundit denied the action. `plan_upgrade_required` means the company's plan carries no API access at all, so no key on it can ever succeed and there is nothing to retry.

This key may not perform this operation نسخ

 `{   "error": {     "code": "forbidden",     "message": "هذا الـ API key لا يملك صلاحية تنفيذ هذه العملية."   } }`

The company's plan carries no API access نسخ

 `{   "error": {     "code": "plan_upgrade_required",     "message": "خطة «الاحترافي» لا تشمل الوصول إلى API. رقِّ إلى «المتطور» أو «الإنتاجي» لتفعيله."   } }`

404 `not_found`

Resource not found or not accessible — also returned for EVERY endpoint when the company's `rest_api` feature flag is disabled (the surface is hidden). Lookups drill through the URL hierarchy, so another company's record is a 404 and never a leak. A path that matches no route at all answers 404 with the distinct code `unknown_endpoint` and echoes the path back, so a mistyped or half-built URL is told apart from a record that is missing or out of reach.

A record that is missing or out of reach نسخ

 `{   "error": {     "code": "not_found",     "message": "غير موجود، أو لا تملك صلاحية الوصول إليه."   } }`

A path that matches no endpoint نسخ

 `{   "error": {     "code": "unknown_endpoint",     "message": "لا يوجد endpoint يطابق GET /api/v1/projcts. راجع المسار في توثيق الـ API."   } }`

409 `default`

A uniqueness/record conflict; retry.

default نسخ

 `{   "error": {     "code": "conflict",     "message": "تعذّر إتمام العملية بسبب تعارض. أعد المحاولة."   } }`

422 `default`

A caller-fixable bad request (validation error, bad date, bad enum).

default نسخ

 `{   "error": {     "code": "unprocessable_entity",     "message": "قيمة due_at غير صالحة؛ أرسل تاريخاً مثل 2026-07-20. المهمة تُستحق في يوم، وأي وقت ترسله يُهمل."   } }`

429 `rate_limit_exceeded`

Either the company's daily API allowance is spent ( `rate_limit_exceeded` ), or the per-key / per-IP burst throttle of 300 requests per minute fired. Both come back after a wait, so `Retry-After` is honest here. **The two bodies are not the same shape.** The daily-quota refusal uses the standard error envelope. The burst throttle is served by Rack::Attack ahead of the application, so its body is a flat `{"error": "<string>"}` with no `code`. A client that reads `error.code` has to tolerate `error` being a plain string.

Today's daily allowance is spent (application envelope) نسخ

 `{   "error": {     "code": "rate_limit_exceeded",     "message": "استهلكت رصيد اليوم من طلبات API في خطة «المتطور» (1000 طلب يوميًا). يتجدد الرصيد عند منتصف الليل بتوقيت Asia/Riyadh."   } }`

Over 300 requests in a minute (Rack::Attack body, flat error) نسخ

 `{   "error": "Rate limit exceeded. Please try again later." }`

[الأخطاء](https://fareeqy.com/api/v1/docs#errors)

[السابق التعليقات](https://fareeqy.com/api/v1/docs/comments) [التالي الملفات](https://fareeqy.com/api/v1/docs/files)
