REST API

Subtasks

Nested subtasks under a parent task.

A subtask is a checklist item under a parent task. Subtasks have no standalone REST resource — every operation goes through /api/v1/tasks/{id}/subtasks/..., and they share the parent task's project visibility.

Subtasks are organized into groups. Every task has at least one group (a default group named for the creator's language). A subtask always belongs to exactly one group, exposed as groupId. Group management itself is not yet part of the public API — but you can target a group when creating a subtask, and the create endpoint stays backward compatible if you ignore groups entirely.

Endpoints

MethodPathNotes
GET/api/v1/tasks/{id}/subtasksList subtasks of a task, ordered by group, then by sortOrder within each group.
POST/api/v1/tasks/{id}/subtasksCreate. Accepts Idempotency-Key.
PATCH/api/v1/tasks/{id}/subtasks/{subId}Update, finalize, or reopen.
DELETE/api/v1/tasks/{id}/subtasks/{subId}Delete.

Subtasks are also returned inline with the parent task by GET /api/v1/tasks/{id}.

Subtask model

{
  "id": "s1…",
  "taskId": "t1…",
  "groupId": "g1…",
  "name": "Hook up the Google provider",
  "descriptionHtml": null,
  "sortOrder": 0,
  "finalizedAt": null,
  "finalizationDate": null,
  "assignees": [{ "user": { "id": "...", "name": "Alex" } }],
  "createdAt": "...",
  "updatedAt": "..."
}

sortOrder is scoped within a group, so two subtasks in different groups can share the same value. Order a full list by group first (the GET endpoint already does this).

Creating a subtask

POST /api/v1/tasks/{id}/subtasks
{
  "name": "Hook up the Google provider",
  "descriptionHtml": "<p>Use the existing config.</p>",
  "assigneeIds": ["..."],
  "groupId": "g1…"
}
FieldTypeNotes
namestring1–300 chars, required.
descriptionHtmlstring≤ 50 000 chars, sanitized server-side.
assigneeIdsUUID[]Must be org members. Triggers in-app + email notifications.
groupIdUUIDOptional. Must belong to the task. Omit it and the subtask lands in the task's first (default) group.

Response: 201 Created with the subtask.

Updating, finalizing, reopening

PATCH /api/v1/tasks/{id}/subtasks/{subId}
{ "name": "Hook up Google OAuth" }
FieldTypeNotes
namestring1–300 chars.
descriptionHtmlstring≤ 50 000 chars.
finalizationDateISO date | nullPass a date to finalize. Pass null to reopen a finalized subtask.

Invalid state transitions return 412 Precondition Failed:

  • Setting finalizationDate on an already-finalized subtask.
  • Setting finalizationDate: null on a subtask that isn't finalized.

Deleting a subtask

DELETE /api/v1/tasks/{id}/subtasks/{subId}

Returns { "data": { "success": true } }. Cascade-deletes the subtask's time entries.

On this page