Workflow (Task Management) API Task lists and tasks.
All workflow endpoints (except toggle) require the workflow feature to be enabled on the target workspace or share. Workflow GET endpoints support format=md query parameter for Markdown output (AI agent-friendly).
Share access: On shares, tasks require member or admin access — guests are blocked. Public guests remain blocked from everything. Toggle endpoints (enable/disable) remain Admin-only.
Endpoint Summary
Feature Toggle
| Method | Endpoint | Description |
|---|---|---|
| POST | /current/workspace/{workspace_id}/workflow/enable/ | Enable workflow on a workspace |
| POST | /current/workspace/{workspace_id}/workflow/disable/ | Disable workflow on a workspace |
| POST | /current/share/{share_id}/workflow/enable/ | Enable workflow on a share |
| POST | /current/share/{share_id}/workflow/disable/ | Disable workflow on a share |
Task Lists & Tasks
| Method | Endpoint | Description |
|---|---|---|
| GET | /current/workspace/{workspace_id}/tasks/ | List task lists in a workspace |
| GET | /current/share/{share_id}/tasks/ | List task lists in a share |
| POST | /current/workspace/{workspace_id}/tasks/create/ | Create a task list in a workspace |
| POST | /current/share/{share_id}/tasks/create/ | Create a task list in a share |
| GET | /current/tasks/{list_id}/details/ | Get task list details (includes tasks) |
| POST | /current/tasks/{list_id}/update/ | Update a task list |
| POST | /current/tasks/{list_id}/delete/ | Soft-delete a task list |
| POST | /current/tasks/{list_id}/restore/ | Restore a trashed task list |
| GET | /current/tasks/{list_id}/items/ | List tasks in a task list |
| POST | /current/tasks/{list_id}/items/create/ | Create a task |
| GET | /current/tasks/{list_id}/items/{task_id}/ | Get task details |
| POST | /current/tasks/{list_id}/items/{task_id}/update/ | Update a task |
| POST | /current/tasks/{list_id}/items/{task_id}/delete/ | Soft-delete a task |
| POST | /current/tasks/{list_id}/items/{task_id}/restore/ | Restore a trashed task |
| POST | /current/tasks/{list_id}/items/{task_id}/status/ | Change task status |
| POST | /current/tasks/{list_id}/items/{task_id}/assign/ | Assign/unassign a task |
| POST | /current/tasks/{list_id}/items/{task_id}/move/ | Move task to another list |
| GET | /current/tasks/{list_id}/items/{task_id}/attachments/ | List a task's attachments |
| POST | /current/tasks/{list_id}/items/{task_id}/attachments/ | Attach one or many objects to a task |
| POST | /current/tasks/{list_id}/items/{task_id}/attachments/detach/ | Detach an object from a task |
| GET | /current/tasks/{list_id}/items/{task_id}/comments/ | List a task's comments |
| POST | /current/tasks/{list_id}/items/{task_id}/comments/ | Post a comment on a task |
| POST | /current/tasks/{list_id}/items/bulk-status/ | Bulk update task statuses |
| POST | /current/tasks/{list_id}/items/reorder/ | Bulk reorder tasks in a task list |
| POST | /current/workspace/{workspace_id}/tasks/reorder/ | Bulk reorder task lists in a workspace |
| POST | /current/share/{share_id}/tasks/reorder/ | Bulk reorder task lists in a share |
| GET | /current/workspace/{workspace_id}/tasks/list/{filter}/ | Filtered task list for workspace (personal view) |
| GET | /current/share/{share_id}/tasks/list/{filter}/ | Filtered task list for share (group view, members/admins only) |
| GET | /current/workspace/{workspace_id}/tasks/summary/ | Task count summary for workspace |
| GET | /current/share/{share_id}/tasks/summary/ | Task count summary for share (members/admins only) |
Workflow Agent Templates (v3.5+, admin-only)
Workspace-scoped persona templates that pair an agent-step instruction prompt with a tool allowlist. v3.5 ships storage + admin CRUD; the agent runtime consumes these in a later release. Write methods require workspace admin; list/read require workspace view.
| Method | Endpoint | Description |
|---|---|---|
| POST | /current/workspace/{workspace_id}/workflow_agent_templates/ | Create an agent template |
| GET | /current/workspace/{workspace_id}/workflow_agent_templates/ | List agent templates in the workspace |
| GET | /current/workspace/{workspace_id}/workflow_agent_templates/{template_id}/ | Read one agent template |
| PATCH | /current/workspace/{workspace_id}/workflow_agent_templates/{template_id}/ | Update mutable fields (name, instruction_prompt, tool_allowlist) |
| DELETE | /current/workspace/{workspace_id}/workflow_agent_templates/{template_id}/ | Hard-delete an agent template |
Mutable fields via PATCH: name (max 128 chars), instruction_prompt (max 8192 chars), tool_allowlist (JSON array of tool id strings). Immutable: id, workspace_id, created_at, created_by_user_id.
Common Path Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| {workspace_id} | string | 19-digit numeric | Workspace profile ID |
| {share_id} | string | 19-digit numeric | Share profile ID |
| {list_id} | string | opaque alphanumeric string | Task list ID |
| {task_id} | string | opaque alphanumeric string | Task ID |
| {filter} | string | assigned, created, status | Task filtered-list filter |
Common Error Responses
These errors apply to all workflow endpoints (except toggle):
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
1650 (Authentication Invalid) | 401 | Authentication required | Missing or invalid JWT token |
1680 (Access Denied) | 403 | Workflow is not enabled | Workflow feature not enabled on entity |
1680 (Access Denied) | 403 | Insufficient permissions | User lacks required access level |
1651 (Invalid Request Type) | 400 | Invalid request | Wrong HTTP method |
1671 (Rate Limited) | 429 | Rate limit exceeded | Too many requests |
Share Workflow Access Levels
On shares, tasks require member or admin access — guests are blocked. Update, delete, and bulk operations require member or admin permissions.
| Role | Tasks | Toggle (Enable/Disable) |
|---|---|---|
| Owner / Admin | Full access | Allowed |
| Member | Full access | Denied |
| Guest | Denied | Denied |
| Public Guest | Denied | Denied |
Feature Toggle
Enable or disable workflow on a workspace or share. Requires admin-level access. These endpoints do not require workflow to already be enabled.
Enable Workflow on Workspace
/current/workspace/{workspace_id}/workflow/enable/
Enable workflow features on a workspace.
Auth: Required (JWT). Admin or owner.
Request Example
curl -X POST "https://api.fast.io/current/workspace/1234567890123456789/workflow/enable/" \
-H "Authorization: Bearer {jwt_token}"
Response
{
"result": true,
"message": "Workflow features enabled",
"workflow": true
}
Response Fields
| Field | Type | Description |
|---|---|---|
| response.message | string | Confirmation message |
| response.workflow | bool | true = enabled, false = disabled |
Access Levels
| Role | Access |
|---|---|
| Owner / Admin | Can enable/disable |
| Member / Guest | Denied |
Error Responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
1650 (Authentication Invalid) | 401 | Authentication required | Missing or invalid token |
1609 (Not Found) | 404 | Workspace not found | Workspace does not exist |
1680 (Access Denied) | 403 | Insufficient permissions | User is not owner or admin |
1605 (Invalid Input) | 400 | Workflow is already enabled | Already enabled |
1654 (Internal Error) | 500 | Failed to enable workflow | Internal error |
Disable Workflow on Workspace
/current/workspace/{workspace_id}/workflow/disable/
Disable workflow on a workspace. Existing data is preserved but inaccessible until re-enabled.
Request Example
curl -X POST "https://api.fast.io/current/workspace/1234567890123456789/workflow/disable/" \
-H "Authorization: Bearer {jwt_token}"
Response
{
"result": true,
"message": "Workflow features disabled",
"workflow": false
}
Error Responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
1650 (Authentication Invalid) | 401 | Authentication required | Missing or invalid token |
1609 (Not Found) | 404 | Workspace not found | Workspace does not exist |
1680 (Access Denied) | 403 | Insufficient permissions | User is not owner or admin |
1605 (Invalid Input) | 400 | Workflow is already disabled | Already disabled |
1654 (Internal Error) | 500 | Failed to disable workflow | Internal error |
Share Toggle Endpoints
/current/share/{share_id}/workflow/enable/
/current/share/{share_id}/workflow/disable/
Behave identically to the workspace variants above, using {share_id} instead. Requires Admin-level access on the share.
Disabling workflow does not delete any data. All entities are preserved and become accessible again when re-enabled.
Task Lists & Tasks
Task lists are containers for tasks, scoped to a workspace or share. Tasks support statuses, priorities, assignees, dependencies, and file/folder node links.
Task Status Values
| Value | Description |
|---|---|
pending | Not started |
in_progress | Actively being worked on |
complete | Finished |
blocked | Blocked by a dependency or issue |
Valid Status Transitions
| From | Allowed Transitions |
|---|---|
pending | in_progress, blocked |
in_progress | complete, blocked, pending |
complete | pending, in_progress |
blocked | pending, in_progress |
Task Priority (integer)
| Value | Meaning |
|---|---|
0 | None (default) |
1 | Low |
2 | Medium |
3 | High |
4 | Critical |
Task List Object
| Field | Type | Description |
|---|---|---|
| id | string | opaque alphanumeric ID (treat as opaque; do not assume fixed length) |
| profile_id | string | Workspace or share profile ID (19-digit numeric) |
| name | string | Task list name |
| description | string|null | Task list description |
| created_by | string | User profile ID of the creator |
| properties | object | Metadata properties (JSON) |
| sort_order | int | Display sort order |
| created | string | Timestamp (YYYY-MM-DD HH:MM:SS UTC) |
| updated | string | Timestamp (YYYY-MM-DD HH:MM:SS UTC) |
| deleted | string|null | Deletion timestamp (YYYY-MM-DD HH:MM:SS UTC), or null |
Task Object
| Field | Type | Description |
|---|---|---|
| id | string | opaque alphanumeric ID (treat as opaque; do not assume fixed length) |
| task_list_id | string | Parent task list ID |
| profile_id | string | Workspace or share profile ID (19-digit numeric) |
| created_by | string | User profile ID of the task creator |
| title | string | Task title |
| description | string|null | Task description |
| status | string | pending, in_progress, complete, blocked |
| assignee_id | string|null | Assigned user's profile ID, or null |
| priority | int | 0 (none) through 4 (critical) |
| sort_order | int | Display sort order |
| dependencies | array<string>|null | Task IDs this task depends on |
| node_id | string|null | Associated file/folder node ID |
| properties | object | Metadata properties (JSON) |
| attachment_count | int | Number of objects attached to the task (single-task detail and task list rows) |
| attachments | array | Hydrated attachment rows (see Task Attachments). Detail endpoint only |
| comment_count | int | Number of comments on the task (single-task detail and task list rows) |
| created | string | Timestamp (YYYY-MM-DD HH:MM:SS UTC) |
| updated | string | Timestamp (YYYY-MM-DD HH:MM:SS UTC) |
| deleted | string|null | Deletion timestamp (YYYY-MM-DD HH:MM:SS UTC), or null |
The live attachment_count and comment_count fields are returned by the single-task detail endpoint and on every task row of the task list endpoints (GET /current/tasks/{list_id}/details/, GET /current/tasks/{list_id}/items/). The hydrated attachments array is returned only by the single-task detail endpoint.
List Task Lists
/current/workspace/{workspace_id}/tasks/
/current/share/{share_id}/tasks/
List all task lists in a workspace or share.
Backwards compatibility: The previous routes (/current/tasks/workspace/{workspace_id}/ and /current/tasks/share/{share_id}/) continue to work via automatic redirect.
Auth: Required (JWT). Rate limited.
Query Parameters
| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
| limit | int | No | 50 | Max 200 | Number of task lists to return |
| offset | int | No | 0 | Min 0 | Number to skip |
| format | string | No | — | md | Markdown output |
Request Example
curl -X GET "https://api.fast.io/current/workspace/1234567890123456789/tasks/?limit=50" \
-H "Authorization: Bearer {jwt_token}"
Response
{
"result": true,
"task_lists": [
{
"id": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5",
"profile_id": "1234567890123456789",
"name": "Sprint 12 Tasks",
"description": "Tasks for the current sprint",
"created_by": "9876543210987654321",
"properties": {},
"sort_order": 0,
"created": "2025-06-01 09:00:00 UTC",
"updated": "2025-06-10 14:30:00 UTC",
"deleted": null
}
],
"pagination": {
"limit": 50,
"offset": 0,
"total": 1
}
}
Create Task List
/current/workspace/{workspace_id}/tasks/create/
/current/share/{share_id}/tasks/create/
Create a new task list.
Backwards compatibility: The previous routes (/current/tasks/workspace/{workspace_id}/create/ and /current/tasks/share/{share_id}/create/) continue to work via automatic redirect.
Auth: Required (JWT). Rate limited.
Request Body
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| name | string | Yes | 1-255 characters | Task list name |
| description | string | No | Max 65535 characters | Task list description |
| properties | object | No | — | Metadata properties |
| sort_order | int | No | Default 0 | Display sort order |
Request Example
curl -X POST "https://api.fast.io/current/workspace/1234567890123456789/tasks/create/" \
-H "Authorization: Bearer {jwt_token}" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "name=Sprint%2012%20Tasks&description=Tasks%20for%20the%20current%20sprint"
Response
{
"result": true,
"task_list": {
"id": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5",
"profile_id": "1234567890123456789",
"name": "Sprint 12 Tasks",
"description": "Tasks for the current sprint",
"created_by": "9876543210987654321",
"properties": {},
"sort_order": 0,
"created": "2025-06-01 09:00:00 UTC",
"updated": "2025-06-01 09:00:00 UTC",
"deleted": null
}
}
Get Task List Details
/current/tasks/{list_id}/details/
Get task list details including all tasks in the list.
Auth: Required (JWT). Rate limited.
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| format | string | No | — | md for Markdown output |
Response
{
"result": true,
"task_list": {
"id": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5",
"profile_id": "1234567890123456789",
"name": "Sprint 12 Tasks",
"description": "Tasks for the current sprint",
"created_by": "9876543210987654321",
"properties": {},
"sort_order": 0,
"created": "2025-06-01 09:00:00 UTC",
"updated": "2025-06-10 14:30:00 UTC",
"deleted": null
},
"tasks": [
{
"id": "x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5",
"task_list_id": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5",
"profile_id": "1234567890123456789",
"title": "Implement login flow",
"description": "Build the OAuth2 login flow",
"status": "in_progress",
"assignee_id": "9876543210987654321",
"priority": 3,
"sort_order": 0,
"dependencies": null,
"node_id": null,
"properties": {},
"attachment_count": 1,
"comment_count": 2,
"created": "2025-06-01 09:30:00 UTC",
"updated": "2025-06-10 14:30:00 UTC",
"deleted": null
}
]
}
Update Task List
/current/tasks/{list_id}/update/
Update a task list. Only provided fields are changed.
Auth: Required (JWT). Rate limited.
Request Body
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| name | string | No | 1-255 characters | Updated name |
| description | string|null | No | Max 65535 chars; null to clear | Updated description |
| properties | object | No | — | Updated properties |
| sort_order | int | No | — | Updated sort order |
Delete Task List
/current/tasks/{list_id}/delete/
Soft-delete a task list.
Auth: Required (JWT). Rate limited.
Restore Task List
/current/tasks/{list_id}/restore/
Restore a soft-deleted (trashed) task list, clearing its trashed state. Restoring a list also makes its tasks searchable again. A list that is already live returns an "is not deleted" validation error (HTTP 400).
Auth: Required (JWT). Rate limited.
Response
{
"result": true,
"task_list": {
"id": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5",
"profile_id": "1234567890123456789",
"name": "Sprint 12 Tasks",
"description": null,
"created_by": "9876543210987654321",
"properties": {},
"sort_order": 0,
"created": "2026-06-13 09:30:00 UTC",
"updated": "2026-06-13 16:37:29 UTC",
"deleted": null
}
}
List Tasks
/current/tasks/{list_id}/items/
List all tasks in a task list. Each task row includes the live attachment_count and comment_count fields (see Task Object).
Auth: Required (JWT). Rate limited.
Query Parameters
| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
| limit | int | No | 50 | Max 200 | Number of tasks to return |
| offset | int | No | 0 | Min 0 | Number to skip |
| format | string | No | — | md | Markdown output |
Create Task
/current/tasks/{list_id}/items/create/
Create a new task in a task list.
Auth: Required (JWT). Rate limited.
Request Body
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| title | string | Yes | 1-512 characters | Task title |
| description | string | No | Max 65535 characters | Task description |
| priority | int | No | 0-4 (default 0) | Priority: 0=none, 1=low, 2=medium, 3=high, 4=critical |
| assignee_id | string | No | 19-digit numeric profile ID | User to assign |
| node_id | string | No | Alphanumeric opaque ID | File/folder node to link |
| dependencies | array<string> | No | Array of task IDs | Tasks this task depends on |
| properties | object | No | — | Metadata properties |
| sort_order | int | No | Default 0 | Display sort order |
Request Example
curl -X POST "https://api.fast.io/current/tasks/a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5/items/create/" \
-H "Authorization: Bearer {jwt_token}" \
-d "title=Implement%20login%20flow&priority=3&assignee_id=9876543210987654321"
Response
{
"result": true,
"task": {
"id": "x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5",
"task_list_id": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5",
"profile_id": "1234567890123456789",
"title": "Implement login flow",
"description": null,
"status": "pending",
"assignee_id": "9876543210987654321",
"priority": 3,
"sort_order": 0,
"dependencies": null,
"node_id": null,
"properties": {},
"created": "2025-06-01 09:30:00 UTC",
"updated": "2025-06-01 09:30:00 UTC",
"deleted": null
}
}
Get Task Details
/current/tasks/{list_id}/items/{task_id}/
Get full details of a single task. This is the only endpoint that returns the hydrated attachments array; the live attachment_count and comment_count fields (computed fresh on each read) are returned here and on task list rows.
Auth: Required (JWT). Rate limited.
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| format | string | No | — | md for Markdown output |
Response
{
"result": true,
"task": {
"id": "x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5",
"task_list_id": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5",
"profile_id": "1234567890123456789",
"title": "Implement login flow",
"description": "Build the OAuth2 login flow",
"status": "in_progress",
"assignee_id": "9876543210987654321",
"priority": 3,
"sort_order": 0,
"dependencies": null,
"node_id": null,
"created_by": "9876543210987654321",
"properties": {},
"attachment_count": 1,
"attachments": [
{
"target_id": "n1o2p3q4r5s6t7u8v9w0x1y2z3a4b5",
"target_type": "node",
"kind": "node",
"display_name": "spec.pdf",
"available": true
}
],
"comment_count": 2,
"created": "2026-06-09 09:30:00 UTC",
"updated": "2026-06-09 14:30:00 UTC",
"deleted": null
}
}
Update Task
/current/tasks/{list_id}/items/{task_id}/update/
Update a task. Only provided fields are changed.
Auth: Required (JWT). Rate limited.
Request Body
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| title | string | No | 1-512 characters | Updated title |
| description | string|null | No | Max 65535 chars; null to clear | Updated description |
| priority | int | No | 0-4 | Updated priority |
| assignee_id | string|null | No | 19-digit numeric; null to unassign | Updated assignee |
| node_id | string|null | No | Opaque ID; null to clear | Updated node link |
| dependencies | array<string> | No | Array of task IDs | Updated dependencies |
| properties | object | No | — | Updated properties |
| sort_order | int | No | — | Updated sort order |
Delete Task
/current/tasks/{list_id}/items/{task_id}/delete/
Soft-delete a task.
Auth: Required (JWT). Rate limited.
Restore Task
/current/tasks/{list_id}/items/{task_id}/restore/
Restore a soft-deleted (trashed) task, clearing its trashed state. A restored task (and its comments) becomes searchable again. Restoring an already-live task returns an "is not deleted" validation error (HTTP 400). A task whose task list is itself trashed cannot be restored — restore the task list first; attempting to do so returns an input-validation error (HTTP 400) instructing you to restore the task list first.
Auth: Required (JWT). Rate limited.
Response
{
"result": true,
"task": {
"id": "x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5",
"task_list_id": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5",
"profile_id": "1234567890123456789",
"title": "Implement login flow",
"description": "Build the OAuth2 login flow",
"status": "in_progress",
"assignee_id": "9876543210987654321",
"priority": 3,
"sort_order": 0,
"dependencies": null,
"node_id": null,
"created_by": "9876543210987654321",
"properties": {},
"created": "2026-06-13 09:30:00 UTC",
"updated": "2026-06-13 16:37:29 UTC",
"deleted": null
}
}
Change Task Status
/current/tasks/{list_id}/items/{task_id}/status/
Change a task's status. Enforces valid transitions.
Auth: Required (JWT). Rate limited.
Request Body
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| status | string | Yes | pending, in_progress, complete, blocked | New status |
Request Example
curl -X POST "https://api.fast.io/current/tasks/a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5/items/x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5/status/" \
-H "Authorization: Bearer {jwt_token}" \
-d "status=in_progress"
Response
{
"result": true,
"task": {
"id": "x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5",
"status": "in_progress",
"...": "..."
},
"old_status": "pending",
"new_status": "in_progress"
}
Assign Task
/current/tasks/{list_id}/items/{task_id}/assign/
Assign or unassign a task.
Auth: Required (JWT). Rate limited.
Request Body
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| assignee_id | string|null | Yes | 19-digit numeric profile ID, or null | User to assign, or null to unassign |
The
assignee_idcan refer to a pending member (an invited user who has not yet signed up). Pending members have a valid user ID and can be assigned to tasks before they create their account. When the user claims their account, the assignment is preserved.
Move Task
/current/tasks/{list_id}/items/{task_id}/move/
Move a task from one task list to another within the same profile.
Auth: Required (JWT). Rate limited.
Request Body
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| target_task_list_id | string | Yes | opaque alphanumeric ID | Destination task list ID |
| sort_order | int | No | Default 0 | Sort order in the target list |
Constraints: Target list must exist, not be deleted, and belong to the same profile. Source and target list cannot be the same.
Example
curl -X POST "https://api.fast.io/current/tasks/a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5/items/x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5/move/" \
-H "Authorization: Bearer {jwt_token}" \
-H "Content-Type: application/json" \
-d '{"target_task_list_id": "p1q2r3s4t5u6v7w8x9y0z1a2b3c4d5"}'
Response: Updated task object with old_task_list_id and new_task_list_id.
Bulk Update Task Status
/current/tasks/{list_id}/items/bulk-status/
Update the status of multiple tasks at once.
Auth: Required (JWT). Rate limited.
Request Body
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| tasks | array | Yes | Max 100 items | Array of {"task_id": string, "status": string} objects |
Request Example
curl -X POST "https://api.fast.io/current/tasks/a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5/items/bulk-status/" \
-H "Authorization: Bearer {jwt_token}" \
-H "Content-Type: application/json" \
-d '{"tasks": [{"task_id": "x1y2z3...", "status": "complete"}, {"task_id": "p1q2r3...", "status": "in_progress"}]}'
Response
{
"result": true,
"success": true,
"updated_count": 2,
"failed_count": 0,
"total_count": 2,
"results": [
{"task_id": "x1y2z3...", "success": true, "error": null},
{"task_id": "p1q2r3...", "success": true, "error": null}
]
}
Response Fields
| Field | Type | Description |
|---|---|---|
| response.success | bool | true if all tasks updated successfully |
| response.updated_count | int | Number successfully updated |
| response.failed_count | int | Number that failed |
| response.total_count | int | Total number of tasks in request |
| response.results | array | Per-task results with task_id, success, and error |
Reorder Tasks
/current/tasks/{list_id}/items/reorder/
Bulk reorder tasks within a task list. Updates sort_order for each specified task atomically.
Auth: Required (JWT). Rate limited.
Request Body (JSON)
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| order | array | Yes | Non-empty array | Array of {"id": string, "sort_order": int} objects |
Each entry in the order array specifies a task ID and its new sort order. All task IDs must belong to the specified task list.
Request Example
curl -X POST "https://api.fast.io/current/tasks/a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5/items/reorder/" \
-H "Authorization: Bearer {jwt_token}" \
-H "Content-Type: application/json" \
-d '{"order": [{"id": "x1y2z3...", "sort_order": 0}, {"id": "p1q2r3...", "sort_order": 1}]}'
Response
{
"result": true,
"reordered": 2,
"list_id": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5"
}
Response Fields
| Field | Type | Description |
|---|---|---|
| response.reordered | int | Number of tasks reordered |
| response.list_id | string | The task list ID |
Reorder Task Lists
/current/workspace/{workspace_id}/tasks/reorder/
/current/share/{share_id}/tasks/reorder/
Bulk reorder task lists within a workspace or share. Updates sort_order for each specified task list atomically.
Backwards compatibility: The previous routes (/current/tasks/workspace/{workspace_id}/reorder/ and /current/tasks/share/{share_id}/reorder/) continue to work via automatic redirect.
Auth: Required (JWT). Rate limited.
Request Body (JSON)
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| order | array | Yes | Non-empty array | Array of {"id": string, "sort_order": int} objects |
Each entry in the order array specifies a task list ID and its new sort order. All task list IDs must belong to the specified workspace or share.
Request Example
curl -X POST "https://api.fast.io/current/workspace/1234567890123456789/tasks/reorder/" \
-H "Authorization: Bearer {jwt_token}" \
-H "Content-Type: application/json" \
-d '{"order": [{"id": "a1b2c3...", "sort_order": 0}, {"id": "d4e5f6...", "sort_order": 1}]}'
Response
{
"result": true,
"reordered": 2,
"profile_id": "1234567890123456789"
}
Response Fields
| Field | Type | Description |
|---|---|---|
| response.reordered | int | Number of task lists reordered |
| response.profile_id | string | The workspace or share profile ID |
Task Attachments
Attach arbitrary platform objects to a task to give it context — a file or folder, a note, a workflow, a sign-envelope, a share, a File Share, or another task. An attachment is a lightweight reference: it records what is attached, not a copy of it.
- A task can hold up to 100 attachments.
- Attaching is idempotent — re-attaching an object that is already attached is a no-op and does not count against the cap.
- Attaching does not verify that the target exists or is accessible; display names are resolved (and access-gated) on read.
- All attachment endpoints require the
workflowfeature on the owning workspace or share. On shares, member or admin access is required — guests are blocked. A soft-deleted task returns404.
Attachment Object (hydrated)
Every attachment returned by the API is hydrated and access-gated to the caller: an object the caller cannot see (or that no longer exists) is returned with available: false and display_name: null rather than leaking its name.
| Field | Type | Description |
|---|---|---|
| target_id | string | The attached object's ID (19-digit numeric for a workspace/share/workflow/envelope/File Share, or an opaque ID for a file/folder node or task) |
| target_type | string | Coarse object type: node, workflow, envelope, share, workspace, fileshare, or task |
| kind | string | Alias of target_type (same value) |
| display_name | string|null | The object's resolved display name, or null when the caller cannot see it or it has no name |
| available | bool | true when the caller can access the object (and display_name is authoritative); false when it is inaccessible, missing, or could not be resolved |
List Task Attachments
/current/tasks/{list_id}/items/{task_id}/attachments/
List all objects attached to a task, hydrated and access-gated to the caller.
Auth: Required (JWT). Rate limited.
Response
{
"result": true,
"task_id": "x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5",
"attachments": [
{
"target_id": "n1o2p3q4r5s6t7u8v9w0x1y2z3a4b5",
"target_type": "node",
"kind": "node",
"display_name": "spec.pdf",
"available": true
},
{
"target_id": "9876543210987654321",
"target_type": "share",
"kind": "share",
"display_name": null,
"available": false
}
],
"count": 2
}
Response Fields
| Field | Type | Description |
|---|---|---|
| task_id | string | The task the attachments belong to |
| attachments | array | Hydrated attachment objects (see Attachment Object) |
| count | int | Number of attachments returned |
Attach Objects to a Task
/current/tasks/{list_id}/items/{task_id}/attachments/
Attach one object (target_id) or many (target_ids) to a task. Idempotent; the new objects are committed atomically. Returns the full, updated hydrated attachment list.
Auth: Required (JWT). Rate limited. Content-Type: application/json.
Request Body
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| target_id | string | One of target_id / target_ids | Valid object ID | A single object to attach |
| target_ids | array<string> | One of target_id / target_ids | 1-100 items | Multiple objects to attach |
The target_id (or each entry in target_ids) is the ID of any file/folder node, note, workflow, sign-envelope, share, File Share, workspace, or task. A request whose new attachments would push the task over the 100-attachment cap is rejected before anything is written.
Request Example — single
curl -X POST "https://api.fast.io/current/tasks/a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5/items/x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5/attachments/" \
-H "Authorization: Bearer {jwt_token}" \
-H "Content-Type: application/json" \
-d '{"target_id": "n1o2p3q4r5s6t7u8v9w0x1y2z3a4b5"}'
Request Example — bulk
curl -X POST "https://api.fast.io/current/tasks/a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5/items/x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5/attachments/" \
-H "Authorization: Bearer {jwt_token}" \
-H "Content-Type: application/json" \
-d '{"target_ids": ["n1o2p3q4r5s6t7u8v9w0x1y2z3a4b5", "9876543210987654321"]}'
Response
{
"result": true,
"task_id": "x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5",
"attached": 1,
"attachments": [
{
"target_id": "n1o2p3q4r5s6t7u8v9w0x1y2z3a4b5",
"target_type": "node",
"kind": "node",
"display_name": "spec.pdf",
"available": true
}
],
"count": 1
}
Response Fields
| Field | Type | Description |
|---|---|---|
| task_id | string | The task the attachments belong to |
| attached | int | Number of objects newly attached by this request (0 when every target was already attached) |
| attachments | array | The full hydrated attachment list after the operation |
| count | int | Number of attachments in the list |
Error Responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
1605 (Invalid Input) | 400 | A target_id or non-empty target_ids array is required | No target supplied |
1605 (Invalid Input) | 400 | target_ids exceeds the maximum of 100 | Batch larger than the cap |
1605 (Invalid Input) | 400 | Invalid attachment target | A target ID could not be decoded |
1605 (Invalid Input) | 400 | Attachment limit reached (maximum 100 per task) | The new attachments would exceed the cap |
1609 (Not Found) | 404 | Task not found | Task does not exist or is soft-deleted |
Detach an Object from a Task
/current/tasks/{list_id}/items/{task_id}/attachments/detach/
Remove an attachment by its target_id. Idempotent — detaching an object that is not attached returns success with removed: false. Returns the updated hydrated attachment list.
Auth: Required (JWT). Rate limited. Content-Type: application/json.
Request Body
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| target_id | string | Yes | Valid object ID | The object to detach |
Request Example
curl -X POST "https://api.fast.io/current/tasks/a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5/items/x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5/attachments/detach/" \
-H "Authorization: Bearer {jwt_token}" \
-H "Content-Type: application/json" \
-d '{"target_id": "n1o2p3q4r5s6t7u8v9w0x1y2z3a4b5"}'
Response
{
"result": true,
"task_id": "x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5",
"removed": true,
"attachments": [],
"count": 0
}
Response Fields
| Field | Type | Description |
|---|---|---|
| task_id | string | The task the attachment belonged to |
| removed | bool | true if an attachment was actually removed; false if the object was not attached |
| attachments | array | The full hydrated attachment list after the operation |
| count | int | Number of attachments remaining |
Task Comments
Collaborate on a task with a dedicated comment thread. Task comments support the full comment feature set — threaded replies, @-mentions, emoji reactions, edit/delete, and edited/created timestamps. The comment shape and threading/mention/reference semantics match the Comments reference; only the list/create surface is task-specific.
- Task comments require the
workflowfeature on the owning workspace or share. On shares, member or admin access is required — guests are blocked. A soft-deleted task returns404. - Task comments are private to the task: they are not returned by the general comment listing (
GET /current/comments/{entity_type}/{parent_id}/) and do not appear in the global comment search. - Reactions, edit, and delete of a task comment use the existing comment-by-id endpoints (
POST /current/comments/{comment_id}/reactions/,POST /current/comments/{comment_id}/update/to edit,DELETE /current/comments/{comment_id}/delete/). See the Comments reference. - The single-task detail endpoint and task list rows return a live
comment_count. - Realtime routing: comment events (
comment_created,comment_updated,comment_deleted,comment_reaction, mention/reply notifications) for a task comment carrylinked_entity_type: "task"andlinked_entity_id(the task id) in their payload, so clients can route them to the right task thread.
List Task Comments
/current/tasks/{list_id}/items/{task_id}/comments/
List the task's comment thread, paginated.
Auth: Required (JWT). Rate limited.
Query Parameters
| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
| limit | int | No | 50 | Min 2, Max 200 | Number of comments to return |
| offset | int | No | 0 | Min 0 | Number to skip |
Response
{
"result": true,
"task_id": "x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5",
"comments": [
{
"id": "cmt1opaqueid",
"entity": "x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5",
"user_id": "9876543210987654321",
"parent_id": null,
"body": "Started on this — first draft is in spec.pdf.",
"profile_type": "workspace",
"profile_id": "1234567890123456789",
"linked_entity_type": "task",
"linked_entity_id": "x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5",
"reference": null,
"mentions": [],
"reactions": {"👍": 1},
"user_reaction": null,
"version": 1,
"can_edit": false,
"can_delete": false,
"can_reply": true,
"created": "2026-06-09 10:00:00 UTC",
"updated": "2026-06-09 10:00:00 UTC"
}
],
"count": 1,
"limit": 50,
"offset": 0
}
Response Fields
| Field | Type | Description |
|---|---|---|
| task_id | string | The task the comments belong to |
| comments | array | Comment objects (full schema in the Comments reference) |
| count | int | Number of comments returned |
| limit | int | Limit used in the query |
| offset | int | Offset used in the query |
Post a Task Comment
/current/tasks/{list_id}/items/{task_id}/comments/
Post a comment on the task, or reply to an existing task comment.
Auth: Required (JWT). Rate limited. Content-Type: application/json.
Request Body
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| body | string | Yes | 1-8192 characters (raw); display text excluding mentions max 500 characters | Comment text (may include mention markup) |
| parent_id | string | No | Valid comment opaque ID | Parent comment to reply to (single-level threading). The parent must already belong to this task's thread |
| reference | object | No | See the Comments reference | Anchoring reference to a position in a file |
| properties | object | No | — | Arbitrary key-value metadata to attach |
Mentions are parsed from the body markup and validated against the task's workspace/share membership; client-supplied mention lists are ignored.
This endpoint is create-only: a body containing a comment_id field is rejected with 400 Invalid Input (it never edits and never creates a duplicate), and trailing path segments after …/comments/ return 404. To edit a task comment use POST /current/comments/{comment_id}/update/.
Request Example
curl -X POST "https://api.fast.io/current/tasks/a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5/items/x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5/comments/" \
-H "Authorization: Bearer {jwt_token}" \
-H "Content-Type: application/json" \
-d '{"body": "Looks good — @[user:1234567890123456789:Jane Smith] can you take the review?"}'
Response
201 Created with the created comment object:
{
"result": true,
"comment": {
"id": "cmt2opaqueid",
"entity": "x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5",
"user_id": "9876543210987654321",
"parent_id": null,
"body": "Looks good — @[user:1234567890123456789:Jane Smith] can you take the review?",
"profile_type": "workspace",
"profile_id": "1234567890123456789",
"linked_entity_type": "task",
"linked_entity_id": "x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5",
"reference": null,
"mentions": ["1234567890123456789"],
"reactions": {},
"user_reaction": null,
"version": 1,
"can_edit": true,
"can_delete": true,
"can_reply": true,
"created": "2026-06-09 10:05:00 UTC",
"updated": "2026-06-09 10:05:00 UTC"
}
}
Error Responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
1605 (Invalid Input) | 400 | Comment body must be between 1 and 8192 characters | Body length out of range |
1605 (Invalid Input) | 400 | Comment text (excluding mentions) must not exceed 500 characters… | Display text too long |
1605 (Invalid Input) | 400 | Your comment appears to contain spam content and cannot be posted | Spam detected |
1605 (Invalid Input) | 400 | This endpoint only creates comments… | Body contained a comment_id field (use POST /current/comments/{comment_id}/update/ to edit) |
1609 (Not Found) | 404 | Parent comment not found | parent_id is not a comment in this task's thread |
1609 (Not Found) | 404 | Task not found | Task does not exist or is soft-deleted |
Profile-Scoped Filtered Lists & Summaries
Tasks support profile-scoped filtered list and summary endpoints. Workspace context provides a personal view (filtered to the current user). Share context provides a group view for members and admins. Tasks on shares are restricted to members and admins. All endpoints support ?limit= (default 50, max 100) and ?offset= (default 0).
Task Filtered Lists
/current/workspace/{workspace_id}/tasks/list/{filter}/
/current/share/{share_id}/tasks/list/{filter}/
Filters: assigned (optional ?status=), created (optional ?status=), status (requires ?status=). Share endpoint shows group view. Members and admins only — guests are blocked.
Task Summaries
/current/workspace/{workspace_id}/tasks/summary/
/current/share/{share_id}/tasks/summary/
Returns total count, counts by status, tasks assigned to current user, and tasks created by current user. Members and admins only on share.
Workflow Events
Tasks emit events on all state changes. Filter with:
GET /current/events/search/?workspace_id={id}&category=workflow
Task Events
task_list_createdtask_list_updatedtask_list_deletedtask_list_restoredtask_createdtask_updatedtask_deletedtask_restoredtask_status_changedtask_assignedtask_movedtask_completedtasks_reorderedtask_lists_reorderedtask_attachment_addedtask_attachment_removed
All workflow events use event category workflow and subcategory workflow.