Skip to main content

Tasks

The Tasks API provides CRUD access to project tasks, plus ancillary actions for status, assignment, tags, archive/activate, clone, comments and timers.
New to the API? Start with Getting started (base URL, response envelope, errors, pagination) and Authentication (API keys). Those conventions apply to every endpoint below and are not repeated here.
Identifier note: tasks are addressed by their numeric task_id and always belong to a project (task_projectid). task_status is a taskstatus_id and task_priority is a taskpriority_id.
Scope: starting/stopping individual timers, recurring settings, task dependencies, per-user notes, attachments/cover image, kanban position, bulk actions and pinning are managed in-app and are not part of this API. Checklists on a task are handled by the Checklists API (resource_type=task). Timers are read-only here, plus a stop-all command.

The task object

{
  "id": 120,
  "title": "Design homepage",
  "description": "First draft.",
  "status": { "id": 1, "title": "To do", "color": "#4f8cff" },
  "priority": { "id": 2, "title": "High", "color": "#ff5b5b" },
  "active_state": "active",
  "client_visibility": "no",
  "billable": "yes",
  "project": { "id": 7, "title": "Website Redesign" },
  "client": { "id": 12, "name": "Acme Inc" },
  "milestone": { "id": 21, "name": "Uncategorised" },
  "dates": { "start": "2026-06-01", "due": "2026-06-30", "created": "...", "updated": "..." },
  "time_logged": 3600,
  "assigned": [ { "id": 53, "name": "Sam Lee" } ],
  "tags": ["priority"]
}
FieldTypeNotes
idintegerTask id.
titlestring
descriptionstring|null
statusobject{ id, title, color }id is the taskstatus_id.
priorityobject{ id, title, color }id is the taskpriority_id.
active_statestringactive or archived.
client_visibilitystringyes/no (visible to the client).
billablestringyes/no.
projectobject{ id, title }.
clientobject{ id, name } (derived from the project).
milestoneobject{ id, name }.
datesobjectstart, due, created, updated.
time_loggedintegerTotal logged time (seconds).
assignedarrayAssigned team members — set via the assigned action.
tagsarrayTag titles.

List / search tasks

GET /api/tasks
ParameterTypeDescription
project_idintegerFilter by project.
client_idintegerFilter by client.
statusintegerFilter by taskstatus_id.
priorityintegerFilter by taskpriority_id.
milestone_idintegerFilter by milestone.
active_statestringactive or archived.
assigned_user_idintegerFilter by an assigned team user.
searchstringFree-text on the title.
sortstringtask_title, task_date_due, task_created, task_position.
orderstringasc or desc (default desc).
limit / pageintegerPagination (limit max 100).
curl -G https://your-domain/api/tasks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d project_id=7 -d limit=25
<?php
$query = http_build_query(['project_id' => 7, 'limit' => 25]);
$ch = curl_init("https://your-domain/api/tasks?$query");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer YOUR_API_KEY'],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
Returns { data, meta, message } (200).

Get a task

GET /api/tasks/{id}
curl https://your-domain/api/tasks/120 -H "Authorization: Bearer YOUR_API_KEY"
<?php
$ch = curl_init('https://your-domain/api/tasks/120');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer YOUR_API_KEY'],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
Returns the task (200), message “Task retrieved successfully.”

Create a task

POST /api/tasks
The client is derived from the project; the milestone defaults to the project’s uncategorised milestone when omitted. Assignment is set separately via the assigned action.
ParameterTypeRequiredNotes
task_projectidintegeryesExisting project id.
task_titlestringyes
task_statusintegeryesA taskstatus_id.
task_priorityintegeryesA taskpriority_id.
task_milestoneidintegernoMust belong to the project. Defaults to uncategorised.
task_date_start / task_date_duedatenoDue must be on/after start.
task_descriptionstringno
task_client_visibilitystringnoon to make visible to the client.
task_billablestringnoon to mark billable.
curl -X POST https://your-domain/api/tasks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d task_projectid=7 -d task_title="Design homepage" \
  -d task_status=1 -d task_priority=2
<?php
$ch = curl_init('https://your-domain/api/tasks');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer YOUR_API_KEY'],
    CURLOPT_POSTFIELDS     => http_build_query([
        'task_projectid' => 7,
        'task_title'     => 'Design homepage',
        'task_status'    => 1,
        'task_priority'  => 2,
    ]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
Returns the new task (201), message “Task created successfully.”

Update a task

PATCH /api/tasks/{id}
Full update of the editable fields (same parameters as Create, except the project is fixed). Assignment is managed via the assigned action.
curl -X PATCH https://your-domain/api/tasks/120 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d task_title="Design homepage v2" -d task_status=1 -d task_priority=2
<?php
$ch = curl_init('https://your-domain/api/tasks/120');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PATCH',
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer YOUR_API_KEY'],
    CURLOPT_POSTFIELDS     => http_build_query([
        'task_title'    => 'Design homepage v2',
        'task_status'   => 1,
        'task_priority' => 2,
    ]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
Returns the task (200), message “Task updated successfully.”

Delete a task

DELETE /api/tasks/{id}
curl -X DELETE https://your-domain/api/tasks/120 -H "Authorization: Bearer YOUR_API_KEY"
Returns { "data": { "id": 120 }, "message": "Task deleted successfully." }.

Change status

PUT /api/tasks/{id}/status
Sets the status (and stamps the status-change date; marks the completer when set to the completed status).
ParameterTypeRequiredNotes
statusintegeryesA taskstatus_id.
curl -X PUT https://your-domain/api/tasks/120/status \
  -H "Authorization: Bearer YOUR_API_KEY" -d status=2
Returns the task (200), message “Task status updated successfully.”

Set assigned team members

PUT /api/tasks/{id}/assigned
Full-set replace (empty array clears).
ParameterTypeRequiredNotes
assignedarray of integersyesTeam user ids.
curl -X PUT https://your-domain/api/tasks/120/assigned \
  -H "Authorization: Bearer YOUR_API_KEY" -d "assigned[]=53"
Returns the task (200), message “Task assignees updated successfully.”

Set tags

PUT /api/tasks/{id}/tags
Full-set replace (empty array clears).
curl -X PUT https://your-domain/api/tasks/120/tags \
  -H "Authorization: Bearer YOUR_API_KEY" -d "tags[]=priority"

Archive / activate

PUT /api/tasks/{id}/archive
PUT /api/tasks/{id}/activate
No body. Toggles active_state between archived and active.
curl -X PUT https://your-domain/api/tasks/120/archive -H "Authorization: Bearer YOUR_API_KEY"

Clone a task

POST /api/tasks/{id}/clone
Clones the task into a target project + milestone.
ParameterTypeRequiredNotes
task_titlestringyes
task_statusintegeryesA taskstatus_id.
project_idintegeryesTarget project.
task_milestoneidintegeryesMust belong to the target project.
copy_checkliststringnoon to copy checklist items.
copy_filesstringnoon to copy files.
curl -X POST https://your-domain/api/tasks/120/clone \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d task_title="Design homepage (copy)" -d task_status=1 \
  -d project_id=7 -d task_milestoneid=21
Returns the new task (201), message “Task cloned successfully.”

Timers

Timers are read-only via the API, plus a stop-all command.

List timers

GET /api/tasks/{id}/timers
Returns the task’s time entries: [{ id, user: {id,name}, started, stopped, time, status, billing_status }].
curl https://your-domain/api/tasks/120/timers -H "Authorization: Bearer YOUR_API_KEY"

Stop all running timers

PUT /api/tasks/{id}/stop-timers
No body. Stops any running timers on the task. Returns { "data": { "id": 120 }, "message": "..." }.
curl -X PUT https://your-domain/api/tasks/120/stop-timers -H "Authorization: Bearer YOUR_API_KEY"

Comments

List comments

GET /api/tasks/{id}/comments

Add a comment

POST /api/tasks/{id}/comments
ParameterTypeRequiredNotes
commentstringyesThe comment text.
curl -X POST https://your-domain/api/tasks/120/comments \
  -H "Authorization: Bearer YOUR_API_KEY" -d comment="Looks good"

Delete a comment

DELETE /api/tasks/{id}/comments/{comment_id}

Errors

See Getting started for the shared error format. Task-specific:
StatusMeaning
404 Not FoundThe task (or comment) id does not exist.
409 ConflictInvalid milestone for the project, or the project has no default milestone.
422 Unprocessable EntityValidation failed (e.g. missing project/title/status/priority).