Tasks API Function
FluentBoards Core Some methods need ProThe Tasks API reads and creates tasks, manages assignees and labels, moves tasks between stages, updates task properties, and (with FluentBoards Pro) manages attachments and subtasks. All methods run as the current WordPress user. See PHP API classes for the rules on permissions and error handling that apply to every method.
Getting the API object
$tasksApi = FluentBoardsApi('tasks');FluentBoardsApi('tasks') returns a FluentBoards\App\Api\FBSApi proxy around FluentBoards\App\Api\Classes\Tasks. The class has no getInstance() method. For custom queries, use the FluentBoards\App\Models\Task model directly (see Models).
Methods
| Method | Permission | Returns |
|---|---|---|
getTasksByBoard() | Read | Collection of Task |
getTask() | Read | Task |
getTasksCreatedBy() | Read (per task) | array of Task |
create() | Write | Task |
createTask() | — | Not implemented |
addAssignees() | Board manager or admin | bool |
removeAssignees() | Board manager or admin | bool |
attachLabels() | Write | bool |
removeLabels() | Write | bool |
changeStage() | Write | Task |
updateProperty() | Write | Task |
createTaskAttachment() | Pro, write | See warning |
deleteTaskAttachment() | Pro, write | bool |
createSubtask() | Pro, write | Task |
updateSubtask() | Pro, write | Task |
deleteSubtask() | Pro, write | null / false |
Reading tasks
getTasksByBoard()
Returns the top-level, non-archived tasks of a board (subtasks are excluded), ordered by due_at ascending. Each task gets these extra attributes: isOverdue, isUpcoming, contact (the FluentCRM contact array, or empty when FluentCRM is inactive) and is_watching.
getTasksByBoard($board_id, $with = [])Parameters
$board_id(int|string): The board ID.$with(array): Relations to eager-load, for example['assignees', 'labels', 'stage'].
Return
- A collection of
Taskmodels. Returns[]for an empty ID andfalsewithout read access.
Example
$tasks = FluentBoardsApi('tasks')->getTasksByBoard(12, ['assignees', 'labels']);
foreach ($tasks as $task) {
if ($task->isOverdue) {
// ...
}
}getTask()
Returns a single task (or subtask) by ID.
getTask($id)Return
- The
Taskmodel, orfalsewhen the ID is empty, the task does not exist, or the user cannot read its board.
Example
$task = FluentBoardsApi('tasks')->getTask(345);getTasksCreatedBy()
Returns all tasks created by a user, filtered to the boards the current user can read. Archived tasks and subtasks are included.
getTasksCreatedBy($userId, $with = [])Parameters
$userId(int|string): The creator's WordPress user ID.$with(array): Relations to eager-load.
Return
- A plain PHP
arrayofTaskmodels (not a collection), orfalsefor an empty user ID.
Example
$tasks = FluentBoardsApi('tasks')->getTasksCreatedBy(get_current_user_id(), ['board']);Creating tasks
create()
Creates a task in a stage. The data passes through the fluent_boards/before_task_create filter. When the task is saved, fluent_boards/task_created fires (top-level tasks only). Assignees are also added as watchers and as board members.
create($data)Parameters
$data(array):
| Key | Type | Notes |
|---|---|---|
title | string | Required |
board_id | int | Required |
stage_id | int | Required. Must belong to board_id. |
description | string | Markdown/HTML, sanitized with fluent_boards_sanitize_description() |
priority | string | urgent, high, medium, low or '' (plus any keys added with the fluent_boards/task_priorities filter). Invalid values become ''. |
status | string | open or closed. Invalid values become open. |
due_at, started_at | string | Y-m-d H:i:s |
assignees | int[] / int / JSON string | WordPress user IDs. IDs that are not WordPress users are dropped. |
labels | array / int / JSON string | Label IDs, or label titles/slugs from the same board. Unknown labels are dropped. |
crm_contact_id | int | FluentCRM contact ID |
contact_email, contact_first_name, contact_last_name | string | Requires FluentCRM. Creates or updates a subscribed contact and links it when crm_contact_id is empty. Pass all three keys. |
source, source_id | string | Your own reference, for example 'my-addon' and an external ID |
parent_id | int | Makes the task a subtask. Prefer createSubtask(). |
Always pass assignees and labels
In version 2.1.0, create() reads $data['assignees'] and $data['labels'] without checking that they exist. Pass both keys (an empty array is fine) to avoid "Undefined array key" warnings on PHP 8.
Return
- The created
Taskmodel. Returnsfalsewhen a required key is missing, the user cannot write to the board, or the stage does not belong to the board.
Example
$task = FluentBoardsApi('tasks')->create([
'title' => 'Draft the launch email',
'board_id' => 12,
'stage_id' => 45,
'description' => 'Use the **new** template.',
'priority' => 'high',
'due_at' => '2026-10-15 17:00:00',
'assignees' => [3, 7],
'labels' => ['Marketing', 18],
'source' => 'my-addon',
'source_id' => 'order-1001',
]);
if (!$task) {
// Missing data, no permission, or the stage is not on this board
}createTask()
A placeholder in version 2.1.0. It lists the supported fields in its body but does not create anything, and always returns null. Use create() instead.
Assignees and labels
addAssignees()
Assigns users to a task and adds them as watchers. Only users who are already members of the task's board are assigned. Other IDs are skipped silently.
addAssignees($task_id, $assignees = [])Parameters
$task_id(int): The task ID.$assignees(int[]): WordPress user IDs.
Return
truewhen the call completes, even if some IDs were skipped. Returnsfalsefor empty arguments or when the current user is neither a board manager nor a FluentBoards admin.
Example
FluentBoardsApi('tasks')->addAssignees(345, [3, 7]);removeAssignees()
Removes users from a task's assignees and watchers.
removeAssignees($task_id, $assignees = [])Return
trueon success. Returnsfalsefor empty arguments, a missing task, or when the current user is neither a board manager nor an admin.
Example
FluentBoardsApi('tasks')->removeAssignees(345, [7]);attachLabels()
Attaches labels to a task. Only labels that belong to the task's board are attached.
attachLabels($taskId, $labelIds = [])Return
trueon success, orfalsewithout write access. Returnsnullif the task does not exist.
Example
FluentBoardsApi('tasks')->attachLabels(345, [18, 19]);removeLabels()
Detaches labels from a task.
removeLabels($taskId, $labelIds = [])Return
trueon success, orfalsewithout write access. Returnsnullif the task does not exist.
Example
FluentBoardsApi('tasks')->removeLabels(345, [19]);Moving and updating
changeStage()
Moves a task to another stage on the same board and places it at the end of that stage.
changeStage($task, $stageId)Parameters
$task(int|Task): A task ID or aTaskmodel.$stageId(int): The target stage ID.
Return
- The updated
Taskmodel. Returnsfalsewhen the task does not exist, the user cannot write to the board, or the stage belongs to another board.
TIP
This method only updates stage_id and position. It does not fire fluent_boards/task_stage_updated, does not apply the stage's default status or default assignees, and does not send notifications. Those side effects happen only when a task is moved in the app or through the REST API.
Example
FluentBoardsApi('tasks')->changeStage(345, 46);updateProperty()
Updates one task property through TaskService, so the normal activity logging and hooks for that property run.
updateProperty($taskId, $property, $value)Parameters
$taskId(int): The task ID.$property(string): One of the following:
| Property | Value |
|---|---|
title | string |
description | string (sanitized with fluent_boards_sanitize_description()) |
due_at | Y-m-d H:i:s, or null/'' to clear |
priority | An allowed priority key, or ''/null to clear. Unknown values return false. |
status | open or closed. Other values return false. |
source, source_id | string |
crm_contact_id | int, or null/'' to clear |
$value(mixed): The new value.
Return
- The updated
Taskmodel. Returnsfalsefor an invalid ID, a missing task, a property that is not allowed, an invalid value, or no write access.
Example
$tasksApi = FluentBoardsApi('tasks');
$tasksApi->updateProperty(345, 'priority', 'urgent');
$tasksApi->updateProperty(345, 'due_at', '2026-10-20 12:00:00');
$tasksApi->updateProperty(345, 'status', 'closed');Attachments Pro
createTaskAttachment()
Intended to add a URL attachment to a task.
createTaskAttachment(int $boardId, int $taskId, array $data = [])Parameters
$boardId(int),$taskId(int)$data(array):url(required) andtitle.
Broken in version 2.1.0
This method calls FluentBoardsPro\App\Services\AttachmentService::addTaskAttachment(), which does not exist in FluentBoards Pro 2.1.0. When the permission checks pass, the call ends in a fatal PHP Error that the API proxy does not catch. Until it is fixed, add URL attachments through the REST endpoint POST /wp-json/fluent-boards/v2/tasks/{task_id}/add-attachment (see the REST API).
It returns false when Pro is inactive, the user cannot write to the board, url is missing, or the task is not on the board.
deleteTaskAttachment()
Deletes an attachment from a task and fires fluent_boards/task_attachment_deleted.
deleteTaskAttachment(int $boardId, int $taskId, int $attachmentId)Return
trueon success. Returnsfalsewhen Pro is inactive, without write access, or when the task is not on the board. Returnsnullwhen the attachment does not exist.
Example
FluentBoardsApi('tasks')->deleteTaskAttachment(12, 345, 88);Subtasks Pro
Subtasks are rows in fbs_tasks with parent_id set to the parent task. Every subtask belongs to a subtask group. A group is a fbs_task_metas row on the parent task with the key group_name, and each subtask links to its group with a subtask_group_id meta row.
createSubtask()
Creates a subtask under a task. Internally it calls create() with board_id and parent_id filled in, so the same data keys and rules apply.
createSubtask(int $boardId, int $taskId, $data)Parameters
$boardId(int): The board ID.$taskId(int): The parent task ID. It must be on$boardId.$data(array): Task data as forcreate().titleandstage_idare required (use the parent'sstage_id). Also:group_id(int): A subtask group of the parent task. If it is missing or invalid, the first group of the parent is used. If the parent has no group, an "Untitled Group" is created.started_atis ignored.
Return
- The created subtask (
Taskmodel), orfalsewhen Pro is inactive, the user cannot write to the board, the parent task is not on the board, orcreate()fails.
Creating a subtask updates the parent's subtask count. It does not fire fluent_boards/task_created.
Example
$tasksApi = FluentBoardsApi('tasks');
$parent = $tasksApi->getTask(345);
$subtask = $tasksApi->createSubtask($parent->board_id, $parent->id, [
'title' => 'Write subject line',
'stage_id' => $parent->stage_id,
'assignees' => [3],
'labels' => [],
]);updateSubtask()
Updates one property of a subtask. It checks that the subtask belongs to $taskId on $boardId, then calls updateProperty(), so the same property list and validation apply.
updateSubtask($boardId, $taskId, $subtaskId, $property, $value)Return
- The updated subtask (
Taskmodel), orfalsewhen Pro is inactive, without write access, when the subtask is not a child of the task on that board, or when the property or value is not allowed.
Example
FluentBoardsApi('tasks')->updateSubtask(12, 345, 351, 'status', 'closed');deleteSubtask()
Deletes a subtask. Fires fluent_boards/before_task_deleted before the delete and fluent_boards/subtask_deleted_activity after it.
deleteSubtask($boardId, $taskId, $subtaskId)Return
falsewhen Pro is inactive, without write access, or when the subtask is not a child of the task on that board.nullotherwise. The method has no return value on success, so you cannot tell success from an exception by the return value alone. Verify withgetTask($subtaskId)if you need to.
Example
$result = FluentBoardsApi('tasks')->deleteSubtask(12, 345, 351);
if ($result === false) {
// Not allowed, or not a subtask of task 345
}