Tasks API
All endpoints require authentication and tasks tool permissions. Data scoping applies: employees/leads see own tasks (assigned, reported, created, or watched), managers see own + squad, executives/heads see all.
List Tasks
Section titled “List Tasks”GET /api/tasksQuery parameters:
| Param | Type | Description |
|---|---|---|
assignee_id | string | Filter by assignee (comma-separated for multiple) |
status_id | string | Filter by status config item ID (comma-separated) |
priority_id | string | Filter by priority config item ID (comma-separated) |
type_id | string | Filter by type config item ID (comma-separated) |
squad | string | Filter by squad name (comma-separated) |
resource_type | string | Filter by linked resource type (e.g. project) |
resource_id | string | Filter by linked resource ID |
roadmap_item_id | string | Filter by roadmap item ID |
parent_id | string | Filter by parent task ID. Use null or empty string for top-level tasks only |
show_subtasks | string | Include subtasks in results (default true). Set to false to hide them |
due | string | Due date filter: today, upcoming (this week), or overdue |
overdue | string | Legacy overdue filter — set to true (prefer due=overdue instead) |
search | string | Search title and description |
Response:
{ "tasks": [ { "id": "string", "title": "string", "description": "string | null", "resource_type": "string | null", "resource_id": "string | null", "status_id": "string | null", "priority_id": "string | null", "type_id": "string | null", "phase_id": "string | null", "assignee_id": "string | null", "reporter_id": "string | null", "parent_task_id": "string | null", "roadmap_item_id": "string | null", "due_date": "string | null", "start_date": "string | null", "estimated_hours": "number | null", "internal_hours": "number | null", "is_private": 0, "sort_order": "number | null", "assignee_name": "string | null", "assignee_picture": "string | null", "reporter_name": "string | null", "created_by_name": "string | null", "status_label": "string | null", "status_color": "string | null", "status_value": "string | null", "priority_label": "string | null", "priority_color": "string | null", "priority_value": "string | null", "type_label": "string | null", "type_value": "string | null", "phase_label": "string | null", "phase_color": "string | null", "approved_by_name": "string | null", "subtask_count": "number", "todo_count": "number", "todo_done_count": "number" } ]}Sorted by sort_order, then due_date, then created_at descending.
Get Task Detail
Section titled “Get Task Detail”GET /api/tasks/:idReturns the task with related data: todos (checklist items), subtasks, and watchers.
Response:
{ "task": { "..." }, "todos": [ { "id": "string", "task_id": "string", "title": "string", "is_done": 0, "position": 0, "assignee_id": "string | null", "assignee_name": "string | null", "assignee_picture": "string | null", "due_date": "string | null" } ], "subtasks": [ { "id": "string", "title": "string", "assignee_name": "string | null", "assignee_picture": "string | null", "status_label": "string | null", "status_color": "string | null", "status_value": "string | null", "priority_label": "string | null", "priority_color": "string | null" } ], "watchers": [ { "id": "string", "name": "string", "picture": "string | null" } ]}Returns 404 if the task does not exist.
Create Task
Section titled “Create Task”POST /api/tasksRequires tasks update permission.
Body:
{ "title": "string (required)", "description": "string", "resource_type": "string", "resource_id": "string", "type_id": "string", "status_id": "string", "priority_id": "string", "assignee_id": "string", "parent_task_id": "string", "due_date": "string (YYYY-MM-DD)", "start_date": "string (YYYY-MM-DD)", "estimated_hours": "number", "internal_hours": "number", "is_private": "boolean", "reported_by_contact_id": "string"}If status_id is omitted, defaults to the configured default task status (typically “To Do”).
Side effects:
- Logs a
createdhistory event - Sends a
task_assignednotification to the assignee (if different from creator) - Auto-creates
agent_task_metarow if the task type isagent_task - Auto-assigns SLA if the task is linked to a support project
Response: 201 with { task }
Duplicate Task
Section titled “Duplicate Task”POST /api/tasks/:id/duplicateRequires tasks update permission. Creates a copy of the specified task with (copy) appended to the title. The status resets to the default, and the reporter is set to the current user. All other fields (description, assignee, priority, dates, etc.) are copied from the original.
Response: 201 with { task }
Returns 404 if the original task does not exist.
Update Task
Section titled “Update Task”PUT /api/tasks/:idRequires tasks update permission.
Body: Any combination of updatable fields:
| Field | Type | Notes |
|---|---|---|
title | string | |
description | string | |
resource_type | string | |
resource_id | string | |
type_id | string | |
status_id | string | Logs history on change |
priority_id | string | |
assignee_id | string | Logs history + notifies new assignee |
parent_task_id | string | |
sprint_id | string | |
roadmap_item_id | string | |
phase_id | string | |
due_date | string | |
start_date | string | |
estimated_hours | number | |
internal_hours | number | |
is_private | boolean | |
sort_order | number | |
reported_by_contact_id | string | |
requirements | string | |
scope | string | |
estimate_compute_hours | number | |
estimate_total_cost | number | |
approved_by_user_id | string | |
approved_at | string | |
delivery_notes | string | |
testing_notes | string |
Side effects:
- Sets
updated_atto current timestamp - Logs
status_changedhistory event when status changes - Logs
assignedhistory event and sendstask_assignednotification when assignee changes - Auto-creates
agent_task_metarow if type is changed toagent_task
Response: { task } with joined status, priority, and type labels.
Returns 400 if no fields are provided. Returns 404 if the task does not exist.
Delete Task
Section titled “Delete Task”DELETE /api/tasks/:idRequires tasks manage permission.
Response: { ok: true }
Returns 404 if the task does not exist.
Todos (Checklist Items)
Section titled “Todos (Checklist Items)”Update Todos
Section titled “Update Todos”PUT /api/tasks/:id/todosRequires tasks update permission. Replaces the full set of todos for the task — send the complete list each time. Todos not present in the request are deleted. New todos (without id) are created; existing todos (with id) are upserted.
Body:
{ "todos": [ { "id": "string (optional — omit for new items)", "title": "string", "is_done": false, "position": 0, "assignee_id": "string | null", "due_date": "string | null" } ]}Side effects:
- Sends
todo_assignednotification when a todo is newly assigned to someone other than the current user
Response:
{ "todos": [ { "id": "string", "task_id": "string", "title": "string", "is_done": 0, "position": 0, "assignee_id": "string | null", "assignee_name": "string | null", "assignee_picture": "string | null", "due_date": "string | null" } ]}Returns 404 if the task does not exist.
Subtasks
Section titled “Subtasks”List Subtasks
Section titled “List Subtasks”GET /api/tasks/:id/subtasksReturns subtasks for the given parent task, sorted by sort_order then created_at.
Response:
{ "subtasks": [ { "id": "string", "title": "string", "assignee_name": "string | null", "assignee_picture": "string | null", "status_label": "string | null", "status_color": "string | null", "status_value": "string | null" } ]}Create Subtask
Section titled “Create Subtask”POST /api/tasks/:id/subtasksRequires tasks update permission. Creates a new task as a child of the specified parent.
Body:
{ "title": "string (required)", "assignee_id": "string", "due_date": "string"}Response: 201 with { task }
Returns 404 if the parent task does not exist. Returns 400 if title is empty.
Watchers
Section titled “Watchers”Watch Task
Section titled “Watch Task”POST /api/tasks/:id/watchAdds the current user as a watcher. Idempotent — calling again has no effect.
Response: { watching: true }
Returns 404 if the task does not exist.
Unwatch Task
Section titled “Unwatch Task”DELETE /api/tasks/:id/watchRemoves the current user from watchers.
Response: { watching: false }
Resources (Links)
Section titled “Resources (Links)”List Resources
Section titled “List Resources”GET /api/tasks/:id/resourcesReturns links/documents attached to a task, sorted by sort_order then created_at.
Response:
{ "resources": [ { "id": "string", "task_id": "string", "type": "link", "url": "string", "title": "string", "description": "string | null", "icon": "string", "sort_order": "number | null", "created_by": "string", "created_by_name": "string | null", "created_at": "string" } ]}The icon field is auto-detected from the URL domain (e.g. figma, github, google-docs, slack, notion, linear, loom, youtube, etc.). Falls back to link.
Add Resource
Section titled “Add Resource”POST /api/tasks/:id/resourcesRequires tasks update permission.
Body:
{ "url": "string (required)", "title": "string (required)", "description": "string"}Response: 201 with { resource }
Returns 400 if url or title is missing.
Delete Resource
Section titled “Delete Resource”DELETE /api/tasks/:id/resources/:resourceIdRequires tasks update permission.
Response: { ok: true }
Reorder Resources
Section titled “Reorder Resources”PUT /api/tasks/:id/resources/reorderRequires tasks update permission.
Body:
{ "order": ["resourceId1", "resourceId2", "resourceId3"]}Sets sort_order based on array position.
Response: { ok: true }
Returns 400 if order array is empty.