المهام

البنود القابلة للتنفيذ داخل قائمة المهام. معرّفات ثابتة (tsk-)، ويبقى الـ slug مقبولاً.

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

شكل المورد

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

idstring

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

urlstring | null

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

titlestring
notesstring | null

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

completedboolean
completed_atstring (date-time) | null
due_atstring (date) | null

تاريخ الاستحقاق، بلا وقت.

time_spent_minutesinteger | null

How long the task took, in whole minutes. Always present, null when nobody has measured it — null is not zero. Reading it is ungated; writing needs a plan that carries time tracking.

project_slugstring

المعرّف الثابت للمشروع. واسم الحقل يقول _slug حفاظاً على التوافق.

task_list_slugstring

المعرّف الثابت لقائمة المهام. واسم الحقل يقول _slug حفاظاً على التوافق.

assigneeobject | any | null
created_atstring (date-time)
Task
{
  "id": "tsk-9wb7t",
  "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",
  "title": "تصميم الهيدر",
  "notes": "نحتاج نسخة للجوال ونسخة للديسكتوب.",
  "completed": false,
  "completed_at": null,
  "due_at": "2026-08-10",
  "time_spent_minutes": 90,
  "project_slug": "prj-8f3kd",
  "task_list_slug": "lst-4m2qp",
  "assignee": {
    "name": "عبدالله المطيري",
    "email": "abdullah@example.com"
  },
  "created_at": "2026-07-03T11:40:09.000+03:00"
}

عرض مهام قائمة

GET/projects/{project_id}/lists/{task_list_id}/tasksيتطلب tasks:read

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

project_idstringمطلوب

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

task_list_idstringمطلوب

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

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

limitinteger

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

الافتراضي: 50

offsetinteger

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

الافتراضي: 0

مثال الطلب

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

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

200
{
  "data": [
    {
      "id": "tsk-9wb7t",
      "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",
      "title": "تصميم الهيدر",
      "notes": "نحتاج نسخة للجوال ونسخة للديسكتوب.",
      "completed": false,
      "completed_at": null,
      "due_at": "2026-08-10",
      "time_spent_minutes": 90,
      "project_slug": "prj-8f3kd",
      "task_list_slug": "lst-4m2qp",
      "assignee": {
        "name": "عبدالله المطيري",
        "email": "abdullah@example.com"
      },
      "created_at": "2026-07-03T11:40:09.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/{project_id}/lists/{task_list_id}/tasksيتطلب tasks:write

ينشئ مهمة داخل القائمة. ويجب أن يكون assignee_email لعضو يمكن إسناد العمل إليه، راجع أعضاء المشروع.

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

project_idstringمطلوب

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

task_list_idstringمطلوب

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

جسم الطلب

titlestringمطلوب
notesstring | null

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

due_atstring | null

تاريخ الاستحقاق بصيغة YYYY-MM-DD، مثل 2026-07-20. والمهمة تُستحق في يوم لا في لحظة: العمود من نوع date، فتُقبل القيمة التي تحمل وقتاً ثم يُسقَط الوقت. أرسل 2026-07-20T14:00 ويعود إليك 2026-07-20.

assignee_emailstring (email) | null

بريد عضو يمكن إسناد العمل إليه.

مثال الطلب

cURL
curl -X POST "https://app.fareeqy.com/api/v1/projects/prj-8f3kd/lists/lst-4m2qp/tasks" \
  -H "Authorization: Bearer $FAREEQY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"تصميم الهيدر","notes":"نحتاج نسخة للجوال ونسخة للديسكتوب.","due_at":"2026-08-10","assignee_email":"abdullah@example.com"}'

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

201
{
  "data": {
    "id": "tsk-9wb7t",
    "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",
    "title": "تصميم الهيدر",
    "notes": "نحتاج نسخة للجوال ونسخة للديسكتوب.",
    "completed": false,
    "completed_at": null,
    "due_at": "2026-08-10",
    "time_spent_minutes": 90,
    "project_slug": "prj-8f3kd",
    "task_list_slug": "lst-4m2qp",
    "assignee": {
      "name": "عبدالله المطيري",
      "email": "abdullah@example.com"
    },
    "created_at": "2026-07-03T11:40:09.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/{project_id}/lists/{task_list_id}/tasks/{id}يتطلب tasks:read

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

project_idstringمطلوب

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

task_list_idstringمطلوب

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

idstringمطلوب

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

مثال الطلب

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

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

200
{
  "data": {
    "id": "tsk-9wb7t",
    "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",
    "title": "تصميم الهيدر",
    "notes": "نحتاج نسخة للجوال ونسخة للديسكتوب.",
    "completed": false,
    "completed_at": null,
    "due_at": "2026-08-10",
    "time_spent_minutes": 90,
    "project_slug": "prj-8f3kd",
    "task_list_slug": "lst-4m2qp",
    "assignee": {
      "name": "عبدالله المطيري",
      "email": "abdullah@example.com"
    },
    "created_at": "2026-07-03T11:40:09.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/{project_id}/lists/{task_list_id}/tasks/{id}يتطلب tasks:write

لا يتغير إلا ما ترسله. وإرسال assignee_email يعيد الإسناد، وإرسالها فارغة يلغيه.

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

project_idstringمطلوب

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

task_list_idstringمطلوب

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

idstringمطلوب

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

جسم الطلب

titlestring
notesstring | null
due_atstring | null

New due DATE (YYYY-MM-DD). Any time component is dropped — see the create operation.

assignee_emailstring | null

بريد عضو يمكن إسناد العمل إليه. والقيمة الفارغة تلغي الإسناد، ولهذا لا يحمل الحقل صيغة email: الفراغ هنا قيمة مقبولة فعلاً.

مثال الطلب

cURL
curl -X PATCH "https://app.fareeqy.com/api/v1/projects/prj-8f3kd/lists/lst-4m2qp/tasks/tsk-9wb7t" \
  -H "Authorization: Bearer $FAREEQY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"","notes":null,"due_at":null,"assignee_email":null}'

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

200
{
  "data": {
    "id": "tsk-9wb7t",
    "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",
    "title": "تصميم الهيدر",
    "notes": "نحتاج نسخة للجوال ونسخة للديسكتوب.",
    "completed": false,
    "completed_at": null,
    "due_at": "2026-08-10",
    "time_spent_minutes": 90,
    "project_slug": "prj-8f3kd",
    "task_list_slug": "lst-4m2qp",
    "assignee": {
      "name": "عبدالله المطيري",
      "email": "abdullah@example.com"
    },
    "created_at": "2026-07-03T11:40:09.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/{project_id}/lists/{task_list_id}/tasks/{id}يتطلب tasks:destructive

حذف نهائي.

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

project_idstringمطلوب

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

task_list_idstringمطلوب

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

idstringمطلوب

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

مثال الطلب

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

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

200
{
  "data": {
    "deleted": true,
    "task": {
      "title": "تصميم الهيدر",
      "id": "tsk-9wb7t"
    }
  }
}
حالات الرفض: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/{project_id}/lists/{task_list_id}/tasks/{id}/completeيتطلب tasks:write

تكرار الطلب بلا أثر: إتمام مهمة متمّة أصلاً لا يغيّر شيئاً.

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

project_idstringمطلوب

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

task_list_idstringمطلوب

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

idstringمطلوب

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

مثال الطلب

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

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

200
{
  "data": {
    "id": "tsk-9wb7t",
    "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",
    "title": "تصميم الهيدر",
    "notes": "نحتاج نسخة للجوال ونسخة للديسكتوب.",
    "completed": false,
    "completed_at": null,
    "due_at": "2026-08-10",
    "time_spent_minutes": 90,
    "project_slug": "prj-8f3kd",
    "task_list_slug": "lst-4m2qp",
    "assignee": {
      "name": "عبدالله المطيري",
      "email": "abdullah@example.com"
    },
    "created_at": "2026-07-03T11:40:09.000+03:00"
  }
}
حالات الرفض: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

A uniqueness/record conflict; retry.

default
{
  "error": {
    "code": "conflict",
    "message": "تعذّر إتمام العملية بسبب تعارض. أعد المحاولة."
  }
}
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/{project_id}/lists/{task_list_id}/tasks/{id}/incompleteيتطلب tasks:write

تكرار الطلب بلا أثر.

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

project_idstringمطلوب

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

task_list_idstringمطلوب

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

idstringمطلوب

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

مثال الطلب

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

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

200
{
  "data": {
    "id": "tsk-9wb7t",
    "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",
    "title": "تصميم الهيدر",
    "notes": "نحتاج نسخة للجوال ونسخة للديسكتوب.",
    "completed": false,
    "completed_at": null,
    "due_at": "2026-08-10",
    "time_spent_minutes": 90,
    "project_slug": "prj-8f3kd",
    "task_list_slug": "lst-4m2qp",
    "assignee": {
      "name": "عبدالله المطيري",
      "email": "abdullah@example.com"
    },
    "created_at": "2026-07-03T11:40:09.000+03:00"
  }
}
حالات الرفض: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

A uniqueness/record conflict; retry.

default
{
  "error": {
    "code": "conflict",
    "message": "تعذّر إتمام العملية بسبب تعارض. أعد المحاولة."
  }
}
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/{project_id}/lists/{task_list_id}/tasks/{id}/moveيتطلب tasks:write

ينقل المهمة إلى قائمة أخرى داخل المشروع نفسه، وتُضاف في آخر القائمة. وتُحلّ الوجهة داخل المشروع الذي في المسار، فيقبل target_task_list_slug معرّفها الثابت أو الـ slug أو المعرّف الرقمي. ولنقل المهمة إلى مشروع آخر استخدم العنوان المسطّح.

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

project_idstringمطلوب

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

task_list_idstringمطلوب

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

idstringمطلوب

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

جسم الطلب

target_task_list_slugstringمطلوب

قائمة المهام الوجهة. في العنوان المتداخل: معرّفها الثابت، أو الـ slug، أو المعرّف الرقمي، داخل المشروع نفسه. وفي العنوان المسطّح: معرّفها الثابت وحده، ويجوز أن تكون في مشروع آخر. واسم الحقل يقول _slug حفاظاً على التوافق.

مثال الطلب

cURL
curl -X POST "https://app.fareeqy.com/api/v1/projects/prj-8f3kd/lists/lst-4m2qp/tasks/tsk-9wb7t/move" \
  -H "Authorization: Bearer $FAREEQY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"target_task_list_slug":"lst-7hx2r"}'

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

200
{
  "data": {
    "id": "tsk-9wb7t",
    "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",
    "title": "تصميم الهيدر",
    "notes": "نحتاج نسخة للجوال ونسخة للديسكتوب.",
    "completed": false,
    "completed_at": null,
    "due_at": "2026-08-10",
    "time_spent_minutes": 90,
    "project_slug": "prj-8f3kd",
    "task_list_slug": "lst-4m2qp",
    "assignee": {
      "name": "عبدالله المطيري",
      "email": "abdullah@example.com"
    },
    "created_at": "2026-07-03T11:40:09.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/{project_id}/lists/{task_list_id}/tasks/{id}/timeيتطلب tasks:write

فعل مستقل عن التعديل، كما هو في تطبيق الويب. يحتاج tasks:write وخطة تحمل تتبّع الوقت، وإلا 403 بلا تسجيل.

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

project_idstringمطلوب

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

task_list_idstringمطلوب

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

idstringمطلوب

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

مثال الطلب

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

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

200
{
  "data": {
    "id": "tsk-9wb7t",
    "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",
    "title": "تصميم الهيدر",
    "notes": "نحتاج نسخة للجوال ونسخة للديسكتوب.",
    "completed": false,
    "completed_at": null,
    "due_at": "2026-08-10",
    "time_spent_minutes": 90,
    "project_slug": "prj-8f3kd",
    "task_list_slug": "lst-4m2qp",
    "assignee": {
      "name": "عبدالله المطيري",
      "email": "abdullah@example.com"
    },
    "created_at": "2026-07-03T11:40:09.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/lists/{task_list_id}/tasksيتطلب tasks:read

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

task_list_idstringمطلوب

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

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

limitinteger

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

الافتراضي: 50

offsetinteger

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

الافتراضي: 0

مثال الطلب

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

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

200
{
  "data": [
    {
      "id": "tsk-9wb7t",
      "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",
      "title": "تصميم الهيدر",
      "notes": "نحتاج نسخة للجوال ونسخة للديسكتوب.",
      "completed": false,
      "completed_at": null,
      "due_at": "2026-08-10",
      "time_spent_minutes": 90,
      "project_slug": "prj-8f3kd",
      "task_list_slug": "lst-4m2qp",
      "assignee": {
        "name": "عبدالله المطيري",
        "email": "abdullah@example.com"
      },
      "created_at": "2026-07-03T11:40:09.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/lists/{task_list_id}/tasksيتطلب tasks:write

ينشئ مهمة داخل القائمة. ويجب أن يكون assignee_email لعضو يمكن إسناد العمل إليه، راجع أعضاء المشروع.

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

task_list_idstringمطلوب

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

جسم الطلب

titlestringمطلوب
notesstring | null

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

due_atstring | null

تاريخ الاستحقاق بصيغة YYYY-MM-DD، مثل 2026-07-20. والمهمة تُستحق في يوم لا في لحظة: العمود من نوع date، فتُقبل القيمة التي تحمل وقتاً ثم يُسقَط الوقت. أرسل 2026-07-20T14:00 ويعود إليك 2026-07-20.

assignee_emailstring (email) | null

بريد عضو يمكن إسناد العمل إليه.

مثال الطلب

cURL
curl -X POST "https://app.fareeqy.com/api/v1/lists/lst-4m2qp/tasks" \
  -H "Authorization: Bearer $FAREEQY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"تصميم الهيدر","notes":"نحتاج نسخة للجوال ونسخة للديسكتوب.","due_at":"2026-08-10","assignee_email":"abdullah@example.com"}'

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

201
{
  "data": {
    "id": "tsk-9wb7t",
    "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",
    "title": "تصميم الهيدر",
    "notes": "نحتاج نسخة للجوال ونسخة للديسكتوب.",
    "completed": false,
    "completed_at": null,
    "due_at": "2026-08-10",
    "time_spent_minutes": 90,
    "project_slug": "prj-8f3kd",
    "task_list_slug": "lst-4m2qp",
    "assignee": {
      "name": "عبدالله المطيري",
      "email": "abdullah@example.com"
    },
    "created_at": "2026-07-03T11:40:09.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/tasks/{id}يتطلب tasks:read

أقصر عنوان في هذه الواجهة، وهو الذي ينسخه الإنسان من شريط المتصفح.

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

idstringمطلوب

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

مثال الطلب

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

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

200
{
  "data": {
    "id": "tsk-9wb7t",
    "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",
    "title": "تصميم الهيدر",
    "notes": "نحتاج نسخة للجوال ونسخة للديسكتوب.",
    "completed": false,
    "completed_at": null,
    "due_at": "2026-08-10",
    "time_spent_minutes": 90,
    "project_slug": "prj-8f3kd",
    "task_list_slug": "lst-4m2qp",
    "assignee": {
      "name": "عبدالله المطيري",
      "email": "abdullah@example.com"
    },
    "created_at": "2026-07-03T11:40:09.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/tasks/{id}يتطلب tasks:write

لا يتغير إلا ما ترسله. وإرسال assignee_email يعيد الإسناد، وإرسالها فارغة يلغيه.

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

idstringمطلوب

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

جسم الطلب

titlestring
notesstring | null
due_atstring | null

New due DATE (YYYY-MM-DD). Any time component is dropped — see the create operation.

assignee_emailstring | null

بريد عضو يمكن إسناد العمل إليه. والقيمة الفارغة تلغي الإسناد، ولهذا لا يحمل الحقل صيغة email: الفراغ هنا قيمة مقبولة فعلاً.

مثال الطلب

cURL
curl -X PATCH "https://app.fareeqy.com/api/v1/tasks/tsk-9wb7t" \
  -H "Authorization: Bearer $FAREEQY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"","notes":null,"due_at":null,"assignee_email":null}'

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

200
{
  "data": {
    "id": "tsk-9wb7t",
    "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",
    "title": "تصميم الهيدر",
    "notes": "نحتاج نسخة للجوال ونسخة للديسكتوب.",
    "completed": false,
    "completed_at": null,
    "due_at": "2026-08-10",
    "time_spent_minutes": 90,
    "project_slug": "prj-8f3kd",
    "task_list_slug": "lst-4m2qp",
    "assignee": {
      "name": "عبدالله المطيري",
      "email": "abdullah@example.com"
    },
    "created_at": "2026-07-03T11:40:09.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/tasks/{id}يتطلب tasks:destructive

حذف نهائي.

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

idstringمطلوب

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

مثال الطلب

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

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

200
{
  "data": {
    "deleted": true,
    "task": {
      "title": "تصميم الهيدر",
      "id": "tsk-9wb7t"
    }
  }
}
حالات الرفض: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/tasks/{id}/completeيتطلب tasks:write

تكرار الطلب بلا أثر.

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

idstringمطلوب

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

مثال الطلب

cURL
curl -X POST "https://app.fareeqy.com/api/v1/tasks/tsk-9wb7t/complete" \
  -H "Authorization: Bearer $FAREEQY_API_KEY"

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

200
{
  "data": {
    "id": "tsk-9wb7t",
    "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",
    "title": "تصميم الهيدر",
    "notes": "نحتاج نسخة للجوال ونسخة للديسكتوب.",
    "completed": false,
    "completed_at": null,
    "due_at": "2026-08-10",
    "time_spent_minutes": 90,
    "project_slug": "prj-8f3kd",
    "task_list_slug": "lst-4m2qp",
    "assignee": {
      "name": "عبدالله المطيري",
      "email": "abdullah@example.com"
    },
    "created_at": "2026-07-03T11:40:09.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/tasks/{id}/incompleteيتطلب tasks:write

تكرار الطلب بلا أثر.

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

idstringمطلوب

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

مثال الطلب

cURL
curl -X POST "https://app.fareeqy.com/api/v1/tasks/tsk-9wb7t/incomplete" \
  -H "Authorization: Bearer $FAREEQY_API_KEY"

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

200
{
  "data": {
    "id": "tsk-9wb7t",
    "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",
    "title": "تصميم الهيدر",
    "notes": "نحتاج نسخة للجوال ونسخة للديسكتوب.",
    "completed": false,
    "completed_at": null,
    "due_at": "2026-08-10",
    "time_spent_minutes": 90,
    "project_slug": "prj-8f3kd",
    "task_list_slug": "lst-4m2qp",
    "assignee": {
      "name": "عبدالله المطيري",
      "email": "abdullah@example.com"
    },
    "created_at": "2026-07-03T11:40:09.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/tasks/{id}/moveيتطلب tasks:write

ينقل المهمة إلى قائمة مهام أخرى، وتُضاف في آخرها. ويجوز أن تكون الوجهة في مشروع آخر من الشركة. ولأن المسار بلا مشروع، يجب أن يكون target_task_list_slug المعرّف الثابت للقائمة (lst-4m2qp)، ولا يُقبل الـ slug هنا.

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

idstringمطلوب

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

جسم الطلب

target_task_list_slugstringمطلوب

قائمة المهام الوجهة. في العنوان المتداخل: معرّفها الثابت، أو الـ slug، أو المعرّف الرقمي، داخل المشروع نفسه. وفي العنوان المسطّح: معرّفها الثابت وحده، ويجوز أن تكون في مشروع آخر. واسم الحقل يقول _slug حفاظاً على التوافق.

مثال الطلب

cURL
curl -X POST "https://app.fareeqy.com/api/v1/tasks/tsk-9wb7t/move" \
  -H "Authorization: Bearer $FAREEQY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"target_task_list_slug":"lst-7hx2r"}'

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

200
{
  "data": {
    "id": "tsk-9wb7t",
    "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",
    "title": "تصميم الهيدر",
    "notes": "نحتاج نسخة للجوال ونسخة للديسكتوب.",
    "completed": false,
    "completed_at": null,
    "due_at": "2026-08-10",
    "time_spent_minutes": 90,
    "project_slug": "prj-8f3kd",
    "task_list_slug": "lst-4m2qp",
    "assignee": {
      "name": "عبدالله المطيري",
      "email": "abdullah@example.com"
    },
    "created_at": "2026-07-03T11:40:09.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/tasks/{id}/timeيتطلب tasks:write

فعل مستقل عن التعديل، كما هو في تطبيق الويب. يحتاج tasks:write وخطة تحمل تتبّع الوقت، وإلا 403 بلا تسجيل.

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

idstringمطلوب

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

مثال الطلب

cURL
curl -X POST "https://app.fareeqy.com/api/v1/tasks/tsk-9wb7t/time" \
  -H "Authorization: Bearer $FAREEQY_API_KEY"

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

200
{
  "data": {
    "id": "tsk-9wb7t",
    "url": "https://app.fareeqy.com/tasks/tsk-9wb7t",
    "title": "تصميم الهيدر",
    "notes": "نحتاج نسخة للجوال ونسخة للديسكتوب.",
    "completed": false,
    "completed_at": null,
    "due_at": "2026-08-10",
    "time_spent_minutes": 90,
    "project_slug": "prj-8f3kd",
    "task_list_slug": "lst-4m2qp",
    "assignee": {
      "name": "عبدالله المطيري",
      "email": "abdullah@example.com"
    },
    "created_at": "2026-07-03T11:40:09.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."
}
الأخطاء