المشاريع

مشاريع الشركة، ومنها الخاصة.

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

شكل المورد

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

idstring

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

urlstring | null

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

namestring
descriptionstring | null
is_publicboolean
archivedboolean
start_datestring (date) | null
end_datestring (date) | null
task_lists_countinteger

عدد قوائم المهام.

tasks_countinteger

عدد المهام في كل قوائم المشروع.

created_atstring (date-time)
updated_atstring (date-time)
Project
{
  "id": "prj-8f3kd",
  "url": "https://app.fareeqy.com/projects/prj-8f3kd",
  "name": "تطوير الموقع",
  "description": "إعادة بناء الموقع التعريفي وربطه بالمنتج.",
  "is_public": false,
  "archived": false,
  "start_date": "2026-07-01",
  "end_date": "2026-09-30",
  "task_lists_count": 4,
  "tasks_count": 27,
  "created_at": "2026-07-01T09:15:00.000+03:00",
  "updated_at": "2026-07-14T12:22:31.000+03:00"
}

عرض مشاريع الشركة

GET/projectsيتطلب projects:read

كل مشاريع شركة المفتاح، ومنها الخاصة، الأحدث أولاً. والاستثناء الوحيد مشروع العرض التجريبي، فهو يبقى خاصاً بمن أُنشئ له. وتستثني المؤرشفة ما لم تفعّل include_archived.

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

include_archivedboolean

تضمين المشاريع المؤرشفة.

الافتراضي: false

limitinteger

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

الافتراضي: 50

offsetinteger

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

الافتراضي: 0

مثال الطلب

cURL
curl "https://app.fareeqy.com/api/v1/projects" \
  -H "Authorization: Bearer $FAREEQY_API_KEY"

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

200
{
  "data": [
    {
      "id": "prj-8f3kd",
      "url": "https://app.fareeqy.com/projects/prj-8f3kd",
      "name": "تطوير الموقع",
      "description": "إعادة بناء الموقع التعريفي وربطه بالمنتج.",
      "is_public": false,
      "archived": false,
      "start_date": "2026-07-01",
      "end_date": "2026-09-30",
      "task_lists_count": 4,
      "tasks_count": 27,
      "created_at": "2026-07-01T09:15:00.000+03:00",
      "updated_at": "2026-07-14T12:22:31.000+03:00"
    }
  ],
  "meta": {
    "total": 4,
    "limit": 50,
    "offset": 0,
    "count": 4
  }
}
حالات الرفض:401403404429اعرض أمثلة الرفض
401default

Missing or invalid API key.

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

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. رقِّ إلى «المتطور» أو «الإنتاجي» لتفعيله."
  }
}
404not_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."
  }
}
429rate_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."
}
الأخطاء

إنشاء مشروع

POST/projectsيتطلب projects:write

جسم الطلب

namestringمطلوب
descriptionstring | null
start_datestring | null

تاريخ بصيغة ISO 8601.

end_datestring | null

تاريخ بصيغة ISO 8601.

is_publicboolean

مثال الطلب

cURL
curl -X POST "https://app.fareeqy.com/api/v1/projects" \
  -H "Authorization: Bearer $FAREEQY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"تطوير الموقع","description":"إعادة بناء الموقع التعريفي وربطه بالمنتج.","start_date":"2026-07-01","end_date":"2026-09-30","is_public":false}'

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

201
{
  "data": {
    "id": "prj-8f3kd",
    "url": "https://app.fareeqy.com/projects/prj-8f3kd",
    "name": "تطوير الموقع",
    "description": "إعادة بناء الموقع التعريفي وربطه بالمنتج.",
    "is_public": false,
    "archived": false,
    "start_date": "2026-07-01",
    "end_date": "2026-09-30",
    "task_lists_count": 4,
    "tasks_count": 27,
    "created_at": "2026-07-01T09:15:00.000+03:00",
    "updated_at": "2026-07-14T12:22:31.000+03:00"
  }
}
حالات الرفض:401403404409422429اعرض أمثلة الرفض
401default

Missing or invalid API key.

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

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. رقِّ إلى «المتطور» أو «الإنتاجي» لتفعيله."
  }
}
404not_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."
  }
}
409default

A uniqueness/record conflict; retry.

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

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

default
{
  "error": {
    "code": "unprocessable_entity",
    "message": "قيمة due_at غير صالحة؛ أرسل تاريخاً مثل 2026-07-20. المهمة تُستحق في يوم، وأي وقت ترسله يُهمل."
  }
}
429rate_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."
}
الأخطاء

عرض مشروع

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

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

idstringمطلوب

المعرّف الثابت للمشروع (prj-8f3kd)، أو الـ slug الخاص به، وهو فريد داخل الشركة.

مثال الطلب

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

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

200
{
  "data": {
    "id": "prj-8f3kd",
    "url": "https://app.fareeqy.com/projects/prj-8f3kd",
    "name": "تطوير الموقع",
    "description": "إعادة بناء الموقع التعريفي وربطه بالمنتج.",
    "is_public": false,
    "archived": false,
    "start_date": "2026-07-01",
    "end_date": "2026-09-30",
    "task_lists_count": 4,
    "tasks_count": 27,
    "created_at": "2026-07-01T09:15:00.000+03:00",
    "updated_at": "2026-07-14T12:22:31.000+03:00"
  }
}
حالات الرفض:401403404429اعرض أمثلة الرفض
401default

Missing or invalid API key.

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

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. رقِّ إلى «المتطور» أو «الإنتاجي» لتفعيله."
  }
}
404not_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."
  }
}
429rate_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."
}
الأخطاء

تعديل مشروع

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

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

idstringمطلوب

المعرّف الثابت للمشروع (prj-8f3kd)، أو الـ slug الخاص به، وهو فريد داخل الشركة.

جسم الطلب

namestring
descriptionstring | null
start_datestring | null
end_datestring | null
is_publicboolean

مثال الطلب

cURL
curl -X PATCH "https://app.fareeqy.com/api/v1/projects/prj-8f3kd" \
  -H "Authorization: Bearer $FAREEQY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"description":"إعادة بناء الموقع التعريفي وربطه بالمنتج وبلوحة القياس.","end_date":"2026-10-15"}'

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

200
{
  "data": {
    "id": "prj-8f3kd",
    "url": "https://app.fareeqy.com/projects/prj-8f3kd",
    "name": "تطوير الموقع",
    "description": "إعادة بناء الموقع التعريفي وربطه بالمنتج.",
    "is_public": false,
    "archived": false,
    "start_date": "2026-07-01",
    "end_date": "2026-09-30",
    "task_lists_count": 4,
    "tasks_count": 27,
    "created_at": "2026-07-01T09:15:00.000+03:00",
    "updated_at": "2026-07-14T12:22:31.000+03:00"
  }
}
حالات الرفض:401403404409422429اعرض أمثلة الرفض
401default

Missing or invalid API key.

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

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. رقِّ إلى «المتطور» أو «الإنتاجي» لتفعيله."
  }
}
404not_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."
  }
}
409default

A uniqueness/record conflict; retry.

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

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

default
{
  "error": {
    "code": "unprocessable_entity",
    "message": "قيمة due_at غير صالحة؛ أرسل تاريخاً مثل 2026-07-20. المهمة تُستحق في يوم، وأي وقت ترسله يُهمل."
  }
}
429rate_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."
}
الأخطاء

حذف مشروع

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

حذف نهائي ومتسلسل، والأرشفة أفضل. ترجع الاستجابة أعداد ما حُذف. والمشروع الذي يغذّيه تكامل موصول يُرفض حذفه بالرمز 409 وproject_in_use حتى تفصل التكامل أو توجّهه إلى مشروع آخر.

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

idstringمطلوب

المعرّف الثابت للمشروع (prj-8f3kd)، أو الـ slug الخاص به، وهو فريد داخل الشركة.

مثال الطلب

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

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

200
{
  "data": {
    "deleted": true,
    "project": {
      "name": "تطوير الموقع",
      "id": "prj-8f3kd"
    },
    "destroyed": {
      "task_lists": 4,
      "tasks": 27,
      "discussions": 3,
      "files": 12,
      "folders": 2
    }
  }
}
حالات الرفض:401403404409429اعرض أمثلة الرفض
401default

Missing or invalid API key.

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

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. رقِّ إلى «المتطور» أو «الإنتاجي» لتفعيله."
  }
}
404not_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."
  }
}
409default

The project cannot be deleted because a connected integration sends its work there. Nothing was deleted. Disconnect the integration, or point it at another project, then delete again. Retrying as-is will not help.

default
{
  "error": {
    "code": "project_in_use",
    "message": "هذا المشروع وجهة تكامل موصول (Sentry). حذفه لا يوقف وصول الأخطاء، بل يجعلها تصل إلى لا مكان. افصل التكامل من «الإعدادات ← التكاملات»، أو وجّهه إلى مشروع آخر، ثم احذف هذا المشروع."
  }
}
429rate_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."
}
الأخطاء

أرشفة مشروع

POST/projects/{id}/archiveيتطلب projects:write

إبعاد قابل للتراجع: يسجّل حدثاً في الخط الزمني، ويجمّد الكتابة في المشروع كله. فضّله على الحذف.

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

idstringمطلوب

المعرّف الثابت للمشروع (prj-8f3kd)، أو الـ slug الخاص به، وهو فريد داخل الشركة.

مثال الطلب

cURL
curl -X POST "https://app.fareeqy.com/api/v1/projects/prj-8f3kd/archive" \
  -H "Authorization: Bearer $FAREEQY_API_KEY"

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

200
{
  "data": {
    "id": "prj-8f3kd",
    "url": "https://app.fareeqy.com/projects/prj-8f3kd",
    "name": "تطوير الموقع",
    "description": "إعادة بناء الموقع التعريفي وربطه بالمنتج.",
    "is_public": false,
    "archived": false,
    "start_date": "2026-07-01",
    "end_date": "2026-09-30",
    "task_lists_count": 4,
    "tasks_count": 27,
    "created_at": "2026-07-01T09:15:00.000+03:00",
    "updated_at": "2026-07-14T12:22:31.000+03:00"
  }
}
حالات الرفض:401403404409422429اعرض أمثلة الرفض
401default

Missing or invalid API key.

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

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. رقِّ إلى «المتطور» أو «الإنتاجي» لتفعيله."
  }
}
404not_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."
  }
}
409default

A uniqueness/record conflict; retry.

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

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

default
{
  "error": {
    "code": "unprocessable_entity",
    "message": "قيمة due_at غير صالحة؛ أرسل تاريخاً مثل 2026-07-20. المهمة تُستحق في يوم، وأي وقت ترسله يُهمل."
  }
}
429rate_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."
}
الأخطاء

إلغاء أرشفة مشروع

POST/projects/{id}/unarchiveيتطلب projects:write

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

idstringمطلوب

المعرّف الثابت للمشروع (prj-8f3kd)، أو الـ slug الخاص به، وهو فريد داخل الشركة.

مثال الطلب

cURL
curl -X POST "https://app.fareeqy.com/api/v1/projects/prj-8f3kd/unarchive" \
  -H "Authorization: Bearer $FAREEQY_API_KEY"

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

200
{
  "data": {
    "id": "prj-8f3kd",
    "url": "https://app.fareeqy.com/projects/prj-8f3kd",
    "name": "تطوير الموقع",
    "description": "إعادة بناء الموقع التعريفي وربطه بالمنتج.",
    "is_public": false,
    "archived": false,
    "start_date": "2026-07-01",
    "end_date": "2026-09-30",
    "task_lists_count": 4,
    "tasks_count": 27,
    "created_at": "2026-07-01T09:15:00.000+03:00",
    "updated_at": "2026-07-14T12:22:31.000+03:00"
  }
}
حالات الرفض:401403404409422429اعرض أمثلة الرفض
401default

Missing or invalid API key.

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

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. رقِّ إلى «المتطور» أو «الإنتاجي» لتفعيله."
  }
}
404not_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."
  }
}
409default

A uniqueness/record conflict; retry.

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

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

default
{
  "error": {
    "code": "unprocessable_entity",
    "message": "قيمة due_at غير صالحة؛ أرسل تاريخاً مثل 2026-07-20. المهمة تُستحق في يوم، وأي وقت ترسله يُهمل."
  }
}
429rate_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."
}
الأخطاء