---
title: "التعليقات: دليل API فريقي"
description: "التعليقات على قائمة مهام، أو على مهمة، قراءةً وكتابةً، ونص الملفات المرفقة بها. مسارات التعليقات في REST API فريقي: البارامترات، وجسم الطلب، وأمثلة الاستجابة"
url: https://fareeqy.com/api/v1/docs/comments
language: ar
---

# التعليقات

التعليقات على قائمة مهام، أو على مهمة، قراءةً وكتابةً، ونص الملفات المرفقة بها.

عنوان الخدمة `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` integer

معرّف رقمي، فالتعليقات بلا slug.

`url` string | null

الصفحة التي يُقرأ فيها التعليق، وهي صفحة أبيه. وكل تعليقات النقاش الواحد تحمل العنوان نفسه.

`content` string | null

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

`author` string | null

`created_at` string (date-time)

`updated_at` string (date-time)

يساوي `created_at` حتى يُعدَّل التعليق.

`attachments` object\[\]

الملفات المضمّنة في متن التعليق. فالنص العادي في `content` يُسقط المرفقات كلها، ولولا هذا الحقل لقرأت تعليقاً يشير إلى لقطة شاشة وكأنه يشير إلى لا شيء. ويكون فارغاً حين لا مرفقات. واقرأ المرفق النصي عبر مسار مرفق التعليق، بمعرّفه `id`.

Comment نسخ

 `{   "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     }   ] }`

### عرض تعليقات قائمة مهام

GET /projects/ {project\_id} /lists/ {task\_list\_id} /comments يتطلب `comments:read`

الأقدم أولاً.

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

`project_id` string مطلوب

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

`task_list_id` string مطلوب

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

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

`limit` integer

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

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

`offset` integer

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

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

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

cURL نسخ

 `curl "https://app.fareeqy.com/api/v1/projects/prj-8f3kd/lists/lst-4m2qp/comments" \   -H "Authorization: Bearer $FAREEQY_API_KEY"`

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

200 نسخ

 `{   "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         }       ]     }   ],   "meta": {     "total": 4,     "limit": 50,     "offset": 0,     "count": 4   } }`

حالات الرفض: 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} /lists/ {task\_list\_id} /comments يتطلب `comments:write`

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

`project_id` string مطلوب

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

`task_list_id` string مطلوب

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

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

`content` string مطلوب

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

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

cURL نسخ

 `curl -X POST "https://app.fareeqy.com/api/v1/projects/prj-8f3kd/lists/lst-4m2qp/comments" \   -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 /projects/ {project\_id} /lists/ {task\_list\_id} /comments/ {comment\_id} /attachments/ {id} يتطلب `comments:read`

يرجع نص ملف واحد مرفق داخل تعليق. و `id` المعرّف الرقمي للمرفق، وتقرؤه من حقل `attachments` في التعليق. ولا يُقرأ هنا إلا الملف النصي (بامتدادات مثل `md`، و `txt`، و `csv`، و `tsv`، و `json`، و `yml`، و `xml`، و `html`، و `log`، و `sql`، وملفات الشيفرة الشائعة)، حتى 256 كيلوبايت. والصورة، وملف PDF، والملف الأكبر من الحد، والملف الفارغ، والملف المفقود من التخزين، كلها تُرفض بالرمز 422 مع ذكر اسمه، فافتحه من صفحة التعليق. ومعرّف مرفق يتبع تعليقاً آخر يرجع 404.

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

`project_id` string مطلوب

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

`task_list_id` string مطلوب

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

`comment_id` integer مطلوب

المعرّف الرقمي للتعليق، فالتعليقات بلا معرّف ثابت وبلا slug.

`id` integer مطلوب

المعرّف الرقمي للمرفق، من حقل `attachments` في التعليق.

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

cURL نسخ

 `curl "https://app.fareeqy.com/api/v1/projects/prj-8f3kd/lists/lst-4m2qp/comments/4821/attachments/1937" \   -H "Authorization: Bearer $FAREEQY_API_KEY"`

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

200 نسخ

 `{   "data": {     "id": 9044,     "name": "أخطاء-الاستيراد.csv",     "content_type": "text/csv",     "byte_size": 412,     "comment_id": 518,     "comment_url": "https://app.fareeqy.com/tasks/tsk-9wb7t",     "content": "row,error\n14,missing due date\n22,unknown assignee\n"   } }`

حالات الرفض: 401 403 404 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."   } }`

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} /lists/ {task\_list\_id} /tasks/ {task\_id} /comments يتطلب `comments:read`

الأقدم أولاً.

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

`project_id` string مطلوب

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

`task_list_id` string مطلوب

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

`task_id` string مطلوب

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

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

`limit` integer

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

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

`offset` integer

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

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

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

cURL نسخ

 `curl "https://app.fareeqy.com/api/v1/projects/prj-8f3kd/lists/lst-4m2qp/tasks/tsk-9wb7t/comments" \   -H "Authorization: Bearer $FAREEQY_API_KEY"`

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

200 نسخ

 `{   "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": 518,       "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",       "content": "راجعت الهيدر على ثلاثة مقاسات، وعندي ثلاث ملاحظات. رفعت لقطة للحالات الثلاث.",       "author": "نورة الحربي",       "created_at": "2026-07-15T11:20:41.000+03:00",       "updated_at": "2026-07-15T11:34:09.000+03:00",       "attachments": [         {           "id": 9037,           "name": "الحالات-الثلاث.png",           "content_type": "image/png",           "byte_size": 612352         }       ]     },     {       "id": 524,       "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",       "content": "خذوا ملاحظات نورة كلها، وابدأوا بالثانية لأنها تكسر الاستخدام لا الشكل. نراجع الاثنين القادم.",       "author": "سارة العتيبي",       "created_at": "2026-07-15T14:05:12.000+03:00",       "updated_at": "2026-07-15T14:05:12.000+03:00",       "attachments": []     }   ],   "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} /lists/ {task\_list\_id} /tasks/ {task\_id} /comments يتطلب `comments:write`

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

`project_id` string مطلوب

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

`task_list_id` string مطلوب

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

`task_id` string مطلوب

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

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

`content` string مطلوب

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

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

cURL نسخ

 `curl -X POST "https://app.fareeqy.com/api/v1/projects/prj-8f3kd/lists/lst-4m2qp/tasks/tsk-9wb7t/comments" \   -H "Authorization: Bearer $FAREEQY_API_KEY" \   -H "Content-Type: application/json" \   -d '{"content":"خلصنا الهيدر، باقي قسم المزايا."}'`

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

201 · A quick reply نسخ

 `{   "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": []   } }`

201 · A long review comment from another member نسخ

 `{   "data": {     "id": 518,     "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",     "content": "راجعت الهيدر على ثلاثة مقاسات، وعندي ثلاث ملاحظات.\n\nالأولى أن الشعار يقفز سطراً كاملاً تحت 380 بكسل لأن العنصر المجاور له لا ينكمش، فيظهر فراغ أبيض في أعلى الصفحة على أجهزة قديمة ما زالت تمثل نسبة معتبرة من زوارنا.\n\nالثانية أن القائمة المنسدلة تفتح لليسار في الوضع العربي، وهذا يخالف اتجاه القراءة ويجعلها تخرج خارج الشاشة.\n\nالثالثة بسيطة: وزن الخط في الروابط 500 بينما بقية الموقع على 400، فيبدو الهيدر أثقل مما حوله. رفعت لقطة للحالات الثلاث في مجلد «التصاميم».",     "author": "نورة الحربي",     "created_at": "2026-07-15T11:20:41.000+03:00",     "updated_at": "2026-07-15T11:20:41.000+03:00",     "attachments": [       {         "id": 9037,         "name": "الحالات-الثلاث.png",         "content_type": "image/png",         "byte_size": 612352       }     ]   } }`

201 · A closing note from the project owner نسخ

 `{   "data": {     "id": 524,     "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",     "content": "خذوا ملاحظات نورة كلها، وابدأوا بالثانية لأنها تكسر الاستخدام لا الشكل. نراجع الاثنين القادم.",     "author": "سارة العتيبي",     "created_at": "2026-07-15T14:05:12.000+03:00",     "updated_at": "2026-07-15T14:05:12.000+03:00",     "attachments": []   } }`

حالات الرفض: 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} /lists/ {task\_list\_id} /tasks/ {task\_id} /comments/ {comment\_id} /attachments/ {id} يتطلب `comments:read`

يرجع نص ملف واحد مرفق داخل تعليق. و `id` المعرّف الرقمي للمرفق، وتقرؤه من حقل `attachments` في التعليق. ولا يُقرأ هنا إلا الملف النصي (بامتدادات مثل `md`، و `txt`، و `csv`، و `tsv`، و `json`، و `yml`، و `xml`، و `html`، و `log`، و `sql`، وملفات الشيفرة الشائعة)، حتى 256 كيلوبايت. والصورة، وملف PDF، والملف الأكبر من الحد، والملف الفارغ، والملف المفقود من التخزين، كلها تُرفض بالرمز 422 مع ذكر اسمه، فافتحه من صفحة التعليق. ومعرّف مرفق يتبع تعليقاً آخر يرجع 404.

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

`project_id` string مطلوب

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

`task_list_id` string مطلوب

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

`task_id` string مطلوب

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

`comment_id` integer مطلوب

المعرّف الرقمي للتعليق، فالتعليقات بلا معرّف ثابت وبلا slug.

`id` integer مطلوب

المعرّف الرقمي للمرفق، من حقل `attachments` في التعليق.

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

cURL نسخ

 `curl "https://app.fareeqy.com/api/v1/projects/prj-8f3kd/lists/lst-4m2qp/tasks/tsk-9wb7t/comments/4821/attachments/1937" \   -H "Authorization: Bearer $FAREEQY_API_KEY"`

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

200 نسخ

 `{   "data": {     "id": 9044,     "name": "أخطاء-الاستيراد.csv",     "content_type": "text/csv",     "byte_size": 412,     "comment_id": 518,     "comment_url": "https://app.fareeqy.com/tasks/tsk-9wb7t",     "content": "row,error\n14,missing due date\n22,unknown assignee\n"   } }`

حالات الرفض: 401 403 404 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."   } }`

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 /lists/ {task\_list\_id} /comments يتطلب `comments:read`

الأقدم أولاً.

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

`task_list_id` string مطلوب

المعرّف الثابت لقائمة المهام (lst-4m2qp). ولا يُقبل الـ slug هنا.

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

`limit` integer

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

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

`offset` integer

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

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

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

cURL نسخ

 `curl "https://app.fareeqy.com/api/v1/lists/lst-4m2qp/comments" \   -H "Authorization: Bearer $FAREEQY_API_KEY"`

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

200 نسخ

 `{   "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         }       ]     }   ],   "meta": {     "total": 4,     "limit": 50,     "offset": 0,     "count": 4   } }`

حالات الرفض: 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 /lists/ {task\_list\_id} /comments يتطلب `comments:write`

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

`task_list_id` string مطلوب

المعرّف الثابت لقائمة المهام (lst-4m2qp). ولا يُقبل الـ slug هنا.

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

`content` string مطلوب

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

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

cURL نسخ

 `curl -X POST "https://app.fareeqy.com/api/v1/lists/lst-4m2qp/comments" \   -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 /lists/ {task\_list\_id} /comments/ {comment\_id} /attachments/ {id} يتطلب `comments:read`

يرجع نص ملف واحد مرفق داخل تعليق. و `id` المعرّف الرقمي للمرفق، وتقرؤه من حقل `attachments` في التعليق. ولا يُقرأ هنا إلا الملف النصي (بامتدادات مثل `md`، و `txt`، و `csv`، و `tsv`، و `json`، و `yml`، و `xml`، و `html`، و `log`، و `sql`، وملفات الشيفرة الشائعة)، حتى 256 كيلوبايت. والصورة، وملف PDF، والملف الأكبر من الحد، والملف الفارغ، والملف المفقود من التخزين، كلها تُرفض بالرمز 422 مع ذكر اسمه، فافتحه من صفحة التعليق. ومعرّف مرفق يتبع تعليقاً آخر يرجع 404.

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

`task_list_id` string مطلوب

المعرّف الثابت لقائمة المهام (lst-4m2qp). ولا يُقبل الـ slug هنا.

`comment_id` integer مطلوب

المعرّف الرقمي للتعليق، فالتعليقات بلا معرّف ثابت وبلا slug.

`id` integer مطلوب

المعرّف الرقمي للمرفق، من حقل `attachments` في التعليق.

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

cURL نسخ

 `curl "https://app.fareeqy.com/api/v1/lists/lst-4m2qp/comments/4821/attachments/1937" \   -H "Authorization: Bearer $FAREEQY_API_KEY"`

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

200 نسخ

 `{   "data": {     "id": 9044,     "name": "أخطاء-الاستيراد.csv",     "content_type": "text/csv",     "byte_size": 412,     "comment_id": 518,     "comment_url": "https://app.fareeqy.com/tasks/tsk-9wb7t",     "content": "row,error\n14,missing due date\n22,unknown assignee\n"   } }`

حالات الرفض: 401 403 404 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."   } }`

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 /tasks/ {task\_id} /comments يتطلب `comments:read`

الأقدم أولاً.

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

`task_id` string مطلوب

المعرّف الثابت للمهمة (tsk-9wb7t). ولا يُقبل الـ slug هنا.

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

`limit` integer

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

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

`offset` integer

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

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

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

cURL نسخ

 `curl "https://app.fareeqy.com/api/v1/tasks/tsk-9wb7t/comments" \   -H "Authorization: Bearer $FAREEQY_API_KEY"`

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

200 نسخ

 `{   "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         }       ]     }   ],   "meta": {     "total": 4,     "limit": 50,     "offset": 0,     "count": 4   } }`

حالات الرفض: 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 /tasks/ {task\_id} /comments يتطلب `comments:write`

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

`task_id` string مطلوب

المعرّف الثابت للمهمة (tsk-9wb7t). ولا يُقبل الـ slug هنا.

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

`content` string مطلوب

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

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

cURL نسخ

 `curl -X POST "https://app.fareeqy.com/api/v1/tasks/tsk-9wb7t/comments" \   -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 /tasks/ {task\_id} /comments/ {comment\_id} /attachments/ {id} يتطلب `comments:read`

يرجع نص ملف واحد مرفق داخل تعليق. و `id` المعرّف الرقمي للمرفق، وتقرؤه من حقل `attachments` في التعليق. ولا يُقرأ هنا إلا الملف النصي (بامتدادات مثل `md`، و `txt`، و `csv`، و `tsv`، و `json`، و `yml`، و `xml`، و `html`، و `log`، و `sql`، وملفات الشيفرة الشائعة)، حتى 256 كيلوبايت. والصورة، وملف PDF، والملف الأكبر من الحد، والملف الفارغ، والملف المفقود من التخزين، كلها تُرفض بالرمز 422 مع ذكر اسمه، فافتحه من صفحة التعليق. ومعرّف مرفق يتبع تعليقاً آخر يرجع 404.

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

`task_id` string مطلوب

المعرّف الثابت للمهمة (tsk-9wb7t). ولا يُقبل الـ slug هنا.

`comment_id` integer مطلوب

المعرّف الرقمي للتعليق، فالتعليقات بلا معرّف ثابت وبلا slug.

`id` integer مطلوب

المعرّف الرقمي للمرفق، من حقل `attachments` في التعليق.

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

cURL نسخ

 `curl "https://app.fareeqy.com/api/v1/tasks/tsk-9wb7t/comments/4821/attachments/1937" \   -H "Authorization: Bearer $FAREEQY_API_KEY"`

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

200 نسخ

 `{   "data": {     "id": 9044,     "name": "أخطاء-الاستيراد.csv",     "content_type": "text/csv",     "byte_size": 412,     "comment_id": 518,     "comment_url": "https://app.fareeqy.com/tasks/tsk-9wb7t",     "content": "row,error\n14,missing due date\n22,unknown assignee\n"   } }`

حالات الرفض: 401 403 404 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."   } }`

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/tasks) [التالي المجلس](https://fareeqy.com/api/v1/docs/discussions)
