Skip to content

Tasks ​

Creating a task and changing one. Both routes take the bodies the web app sends, so their field names follow the stored task. To read tasks, use Everything or the Read-only token API.

Create a task ​

POST /api/v2/tasks · beta

Creates a task, or a subtask when data.ParentTaskId names a parent.

The body is the one the web app sends: the task under data and the project it goes into under projectData. The server sets the company and the acting person itself, whatever the body says. Under a parent, the project, list and folder are taken from the parent, and the parent must be in the project the body names.

The task's key is assigned after the task is saved, from the project's code and its next number. Read the task back to learn it.

AuthSession or API token with the write scope
Token limited to projectsRefused
Permissiontask.task_create

Body

FieldTypeRequiredDescription
data.TaskNamestringyesThe task's name.
data.TaskKeystringyesA placeholder such as -. The server replaces it with the real key.
data.TaskTypestringyesOne of the project's task types, by its value.
data.TaskTypeKeynumberThe key of that task type.
data.ProjectIDidyesThe project the task goes into.
data.sprintIdidThe list the task goes into.
data.sprintArrayobject{ id, name } of that list, with folderId and folderName when the list sits in a folder.
data.folderObjIdidThe folder, when the list sits in one.
data.statusobjectThe status as the project defines it: { text, key, type }.
data.statusKeynumberThe key of that status.
data.statusTypestringThe type of that status, for example default_active.
data.Task_PrioritystringThe priority, for example MEDIUM.
data.AssigneeUserIdid[]The assignees. Each must hold a seat in the workspace.
data.watchersid[]The watchers. Each must hold a seat in the workspace.
data.Task_LeaderidThe task's lead. Must hold a seat in the workspace.
data.DueDatedateThe due date, or an empty string. With a date, send data.dueDateDeadLine as [{ date }].
data.startDatedateThe start date.
data.ParentTaskIdidThe parent, for a subtask. Empty for a top-level task.
data.isParentTaskbooleantrue for a top-level task, false for a subtask.
data.deletedStatusKeynumber0 for a live task.
projectData._ididThe same project as data.ProjectID.
projectData.ProjectNamestringThe project's name, used in the notification.
projectData.ProjectCodestringThe project's code. The task's key starts with it.
indexObjobjectWhere the task sits in the web app's grouped lists: { indexName, searchKey, searchValue }. indexName is one of groupByStatusIndex, groupByPriorityIndex, groupByAssigneeIndex, groupByDueDateIndex.

data may carry any other field a stored task has. A field a task does not have is dropped. _id, createdBy and createdAt are refused.

Request

http
POST /api/v2/tasks
Authorization: Bearer <token>
companyid: <company id>
Content-Type: application/json

{
  "data": {
    "TaskName": "Write the release notes",
    "TaskKey": "-",
    "TaskType": "task",
    "TaskTypeKey": 1,
    "ProjectID": "<project id>",
    "sprintId": "<list id>",
    "sprintArray": { "id": "<list id>", "name": "Sprint 12" },
    "status": { "text": "To Do", "key": 1, "type": "default_active" },
    "statusKey": 1,
    "statusType": "default_active",
    "Task_Priority": "MEDIUM",
    "AssigneeUserId": [],
    "watchers": [],
    "DueDate": "",
    "dueDateDeadLine": [],
    "ParentTaskId": "",
    "isParentTask": true,
    "deletedStatusKey": 0
  },
  "projectData": { "_id": "<project id>", "ProjectName": "Website", "ProjectCode": "WEB" },
  "indexObj": { "indexName": "groupByStatusIndex", "searchKey": "statusKey", "searchValue": 1 }
}

Response

json
{ "status": true, "statusText": "Task created successfully.", "id": "<task id>" }

The new task's id is in id, beside status, not inside data.

Errors

StatusWhen
400The body is not an object, carries a key that is not accepted, names something that is not an id where an id is expected, names a person who holds no seat in the workspace, the parent cannot take another level of subtasks, or the workspace's plan allows no more tasks in the list.
401No token, a token that is invalid, expired or revoked, or no valid companyid header.
403The token lacks the write scope, or its person is no longer a member of the workspace. A token limited to projects is refused here. The person's role lacks the permission the route needs.
404The parent task does not exist, or is not in the project the body names.
429Too many requests from this address. Wait retryAfter seconds and send it again.

Change a task ​

PATCH /api/v2/tasks · beta

Changes one task. action names the change, and the other keys of the body depend on it.

Each action reads the task it changes from the id shown under Ids, and answers 404 when the caller cannot see that task. The first id listed is the task; the others are the further tasks, people or projects the action names.

The server fills in the acting person, the company and, where an action uses them, the stored names of the task and its project. Keys an action does not use are dropped rather than refused, so the bodies the web app sends keep working. Where a key is followed by names in brackets, those are the only fields of that object the action writes.

Some actions take isUpdateTask. Leave it out. Sent as false it records history for a change another request already made, and is refused with 409 unless the stored task already holds that value.

AuthSession or API token with the write scope
Token limited to projectsRefused
PermissionOne per action, in the table below

Body

FieldTypeRequiredDescription
actionstringyesOne of the actions in the table below.

Actions

actionPermissionIdsBody keys keptNotes
updateStatustask.task_statustask._id, prevStatus.taskIdnewStatus (status, statusKey, statusType), prevStatus, projectData, task, isUpdateTaskSets the status. newStatus holds the status as the project defines it.
updatePrioritytask.task_prioritytaskData._id, priorityObj.taskIdfirebaseObj (Task_Priority, Updated_At), projectData, taskData, priorityObj, isUpdateTaskSets the priority.
updateAssigneetask.task_assigneetaskData._idfirebaseObj (AssigneeUserId), projectData, taskData, employeeName, type, isUpdateTasktype is assigneeAdd, assigneRemove or replace.
updateDueDatetask.task_due_datetask._idcommonDateFormatString, timeZone, firebaseObj (DueDate, dueDateDeadLine), project, task, obj, isUpdateTask
updateStartDatetask.task_due_datetask._idcommonDateFormatString, timeZone, firebaseObj (startDate), project, task, obj, isUpdateTask, isHistory
updateTaskTypetask.task_typetaskData._idnewStatus (TaskType, TaskTypeKey, taskTypeImage, oldTaskTypeImage, taskTypeName), prevStatus, projectData, taskData, isUpdateTask
updateDescriptiontask.task_descriptiontask._idcompanyId, projectData, sprintId, task, textSets the description from text.blocks and text.text.
updateTaskTotalEstimatetask.task_estimated_hourstaskData._idfirebaseObj (totalEstimatedTime), projectData, taskData, obj
updatePointstask.task_estimated_hourstaskData._idfirebaseObj (points), projectData, taskData
createSubTaskWithAiDepends on the bodyparentTask.id, parentTask.ProjectIDcompanyId, userId, subTitles, sprintObj, projectData, parentTask, typeNeeds task.sub_task_create when type is subTask, otherwise task.task_create.
updateTaskNametask.task_name_edittaskData._idfirebaseObj (TaskName), projectData, taskData, objRenames the task.
updateDatestask.task_due_datetaskData._idfirebaseObj (startDate, DueDate), projectData, taskData
updateStartDateAndDueDatetask.task_due_date, task.task_start_datetask._idcommonDateFormatString, timeZone, notificationObj, firebaseObj (DueDate, dueDateDeadLine, startDate), task, project
updateTaskLeadertask.task_assigneetaskData._id, firebaseObj.Task_LeaderfirebaseObj (Task_Leader), projectData, taskData, employeeName, isUpdateTask
updateWatchertask.task_listtaskId, userIdcompanyId, projectId, sprintId, taskId, userId, add, employeeName
updateTagstask.task_tagtaskIdcompanyId, projectId, sprintId, taskId, tagId, operation
updateChecklistsDepends on the bodytaskIdcompanyId, projectId, sprintId, taskId, operation, data, historyObj, taskDataAssigning or unassigning an item needs task.task_checklist_assign_remove. Every other operation needs task.task_checklist.
AddAiChecklisttask.task_checklisttaskIdcompanyId, taskId, checklistArray, sprintId, projectId
updateAttachmentstask.task_attachmentstaskId, taskData._idcompanyId, sprintId, taskId, taskData, id, operation, data, projectData
updateTaskCustomFieldtask.task_custom_fieldtaskIdcompanyId, taskId, updateDetail, customFieldIdSets one custom field's value: customFieldId, and updateDetail with the field's id as _id and the value as fieldValue. A value that does not fit the field's type is refused.
updateMarkAsFavouritetask.task_listtaskId, updateDetailcompanyId, taskId, updateDetail, type
updateLastMessageTimechat.one_to_one_chattaskIdcompanyId, taskId, msgObj
updateQueueListtask.queue_listtaskId, userIdCompanyId, projectId, sprintId, taskId, userId, actionType, taskName
updateArchiveDeleteDepends on the bodytask._id, task.ParentTaskIdcompanyId, projectData, sprintId, task, deletedStatusKeydeletedStatusKey 1 deletes and needs task.task_delete, 2 archives and needs task.task_archive, 0 restores and needs task.task_list.
convertToSubTasktask.task_convert_to_subtask, task.sub_task_createselectedTaskId, taskIdcompanyId, projectData, sprintId, selectedTaskId, taskId, oldProject, isSubTask
convertToTasktask.convert_to_task, task.task_createtaskId, parentTaskId, projectData.idcompanyId, projectData, taskId, sprintObj, parentTaskId, oldSprintObj, oldProject
convertToListtask.task_convert_to_list, project.project_sprint_createtaskId, projectData.idcompanyId, projectData, taskId, folderData, sprintObj, isSubTask
moveTasktask.task_movemoveTaskId, projectData.idcompanyId, projectData, sprintObj, moveTaskId, oldSprintObj, oldProject, isSubTask, assignee, watcherThe key is also needed in the project the task moves to.
mergeTasktask.task_mergetaskId, mergeTaskIdcompanyId, projectData, taskId, mergeTaskId, oldProject, isSubTaskThe key is also needed in the destination project.
duplicateTasktask.task_duplicateselectedTaskId, projectData.idcompanyId, projectData, sprintObj, selectedTaskId, oldProject, isSubTask, duplicateData, assignee, watcher, taskName, oldSprintObjThe key is also needed in the project the copy goes to.
addToListtask.task_movetaskId, sprintIdcompanyId, CompanyId, taskId, sprintId
removeFromListtask.task_listtaskId, sprintIdcompanyId, CompanyId, taskId, sprintId

Request

http
PATCH /api/v2/tasks
Authorization: Bearer <token>
companyid: <company id>
Content-Type: application/json

{
  "action": "updateStatus",
  "task": { "_id": "<task id>", "sprintId": "<list id>" },
  "newStatus": {
    "status": { "key": 2, "text": "Doing", "type": "active" },
    "statusKey": 2,
    "statusType": "active"
  },
  "prevStatus": { "taskId": "<task id>" },
  "projectData": { "_id": "<project id>" }
}

Response

json
{
  "status": true,
  "statusText": "Task updated successfully.",
  "data": { "status": true, "statusText": "Status updated successfully" }
}

data is what the action itself answered, and differs from action to action. An action that found nothing to change answers status: false with its reason.

Example: rename a task

http
PATCH /api/v2/tasks
Authorization: Bearer <token>
companyid: <company id>
Content-Type: application/json

{
  "action": "updateTaskName",
  "taskData": { "_id": "<task id>", "sprintId": "<list id>" },
  "firebaseObj": { "TaskName": "Write and review the release notes" },
  "obj": {},
  "projectData": { "_id": "<project id>" }
}

Example: add an assignee

http
PATCH /api/v2/tasks
Authorization: Bearer <token>
companyid: <company id>
Content-Type: application/json

{
  "action": "updateAssignee",
  "type": "assigneeAdd",
  "taskData": { "_id": "<task id>", "sprintId": "<list id>" },
  "firebaseObj": { "AssigneeUserId": "<user id>" },
  "projectData": { "_id": "<project id>" }
}

Example: set a custom field's value

http
PATCH /api/v2/tasks
Authorization: Bearer <token>
companyid: <company id>
Content-Type: application/json

{
  "action": "updateTaskCustomField",
  "taskId": "<task id>",
  "customFieldId": "<custom field id>",
  "updateDetail": { "_id": "<custom field id>", "fieldValue": "In review" }
}

Errors

StatusWhen
400No action, an action that is not accepted, something that is not an id where an id is expected, a key that is not accepted, a value that does not fit the field, or a person named who holds no seat in the workspace.
401No token, a token that is invalid, expired or revoked, or no valid companyid header.
403The token lacks the write scope, or its person is no longer a member of the workspace. A token limited to projects is refused here. The person's role lacks the permission the route needs.
404The task does not exist or the caller cannot see it. For a move or a copy, the destination project does not exist.
409isUpdateTask was false and the stored task does not hold the value the request names.
429Too many requests from this address. Wait retryAfter seconds and send it again.

List a task's extra lists ​

GET /api/v2/tasks/:id/lists · beta

Lists the other lists a task has been added to, besides its own.

The ids are always given. A list's name and its project's name are given only for a live list the caller can open.

AuthSession or API token with the read scope
Token limited to projectsRefused
PermissionThe task must be one the caller can open

Path parameters

NameTypeDescription
ididThe task.

Request

http
GET /api/v2/tasks/<id>/lists
Authorization: Bearer <token>
companyid: <company id>

Response

json
{
  "status": true,
  "statusText": "Task lists.",
  "data": {
    "taskId": "<task id>",
    "extraLists": [
      {
        "projectId": "<project id>",
        "sprintId": "<list id>",
        "addedBy": "<user id>",
        "addedAt": "2026-10-01T09:30:00.000Z",
        "name": "Sprint 12",
        "projectName": "Website"
      }
    ]
  }
}

Paging

None.

Errors

StatusWhen
400The id is not an id.
401No token, a token that is invalid, expired or revoked, or no valid companyid header.
403The token lacks the read scope, or its person is no longer a member of the workspace. A token limited to projects is refused here.
404The task does not exist, or the caller cannot open it.
429Too many requests from this address. Wait retryAfter seconds and send it again.

Released under the AGPL-3.0 licence.