---
title: "Update a task"
method: PATCH
path: "/tasks/{id}"
tags: ["Tasks"]
---

# Update a task

`PATCH /tasks/{id}`

## Request

- Base URL: `https://tasg.app/api/v1`
- URL: `https://tasg.app/api/v1/tasks/{id}`
- Auth: HTTP bearer

Partial update. Send `null` to clear a nullable field. Moving a task into a section whose name implies a status (e.g. "Done", "In progress", "Blocked") applies that status; completing a task stamps `completed_at`, moves it to the project's done column (the section named "Done" if present, else the first section whose name implies completed, e.g. "Finished" or "Shipped"), unblocks dependents and notifies watchers. Moving a completed task out of the done column reopens it like POST /tasks/{id}/reopen: status becomes `blocked` if any dependency is incomplete, else the section-implied status; an explicit `status` in the same request overrides this.

## Path parameters

- `id` string, uuid, required

## Request body

- object
  - `title` string
  - `description` string, nullable
  - `assignee_id` string, uuid, nullable: Must be a member of the project.
  - `section_id` string, uuid, nullable: Must belong to the task's project.
  - `start_date` string, nullable: Any value `new Date()` accepts; use `YYYY-MM-DD`.
  - `due_date` string, nullable: Any value `new Date()` accepts; use `YYYY-MM-DD`.
  - `due_date_type` 'fixed' | 'relative': `relative` tasks derive their due date from another task plus an offset.
  - `relative_offset_days` integer, nullable
  - `relative_offset_from_task_id` string, uuid, nullable: Anchor task for relative due dates; must be in the same project.
  - `priority` 'none' | 'low' | 'medium' | 'high' | 'urgent'
  - `status` 'not_started' | 'in_progress' | 'blocked' | 'completed'
  - `position` number: Reorder within the section.
  - `tag_ids` string[]: On PATCH this REPLACES the whole tag set. Duplicate ids are deduplicated; every id must be a tag of the task's workspace, else 400.
  - `category` string, nullable
  - `recurrence` 'daily' | 'weekly' | 'fortnightly' | 'monthly', nullable: Repeat rule. Completing a recurring task spawns the next occurrence exactly once: due (and start, keeping the same lead time) advanced by the rule, placed in the first not-done section, keeping assignee, priority, tags and subtasks (reset). Send null on PATCH to stop repeating.

## Response `200`

Updated.

- object
  - `task` Task, required
    - `id` string, uuid, required
    - `title` string, required
    - `description` string, nullable
    - `parent_task_id` string, uuid, nullable
    - `parent_task` object, nullable
      - `id` string, uuid, required
      - `title` string, required
    - `created_via` string: Which surface created the task: `app`, `mcp`, `assistant`, `api` …
    - `ai_touched_at` string, date-time, nullable: Last time an AI agent created or edited this task.
    - `nesting_level` integer: 0 = top-level; subtasks may nest 5 deep.
    - `position` number: Sort key within the section (ascending).
    - `primary_project_id` string, uuid, required
    - `section_id` string, uuid, nullable
    - `assignee_id` string, uuid, nullable
    - `assignee` object, nullable
      - `id` string, uuid, required
      - `full_name` string, required
      - `avatar_url` string, uri, nullable
    - `created_by` string, uuid
    - `creator` object, nullable
      - `id` string, uuid, required
      - `full_name` string, required
      - `avatar_url` string, uri, nullable
    - `start_date` string, date, nullable: Calendar date, YYYY-MM-DD
    - `due_date` string, date, nullable: Calendar date, YYYY-MM-DD
    - `due_date_type` 'fixed' | 'relative': `relative` tasks derive their due date from another task plus an offset.
    - `relative_offset_days` integer, nullable
    - `relative_offset_from_task_id` string, uuid, nullable
    - `recurrence` 'daily' | 'weekly' | 'fortnightly' | 'monthly', nullable
    - `next_occurrence_id` string, uuid, nullable: Set once this completion has spawned the next occurrence of a recurring task.
    - `completed_at` string, date-time, nullable
    - `category` string, nullable
    - `priority` 'none' | 'low' | 'medium' | 'high' | 'urgent', required
    - `status` 'not_started' | 'in_progress' | 'blocked' | 'completed', required: Lifecycle state. `blocked` is set automatically while a dependency is incomplete.
    - `subtask_count` integer
    - `comment_count` integer
    - `attachment_count` integer
    - `blocked_by_count` integer: Dependencies this task waits on.
    - `blocking_count` integer: Tasks waiting on this one.
    - `tags` Tag[]
      - `id` string, uuid, required
      - `name` string, required
      - `color` string, required: Hex colour, e.g. `#3b82f6`.
    - `watchers` object[]
      - `user_id` string, uuid, required
      - `full_name` string, required
      - `avatar_url` string, uri, nullable
    - `created_at` string, date-time, required
    - `updated_at` string, date-time, required

## Other responses

- `400`: Validation failed: the body or query did not match the schema, or a business rule was violated. `error` says which.
- `401`: Missing, invalid, expired or revoked credentials.
- `403`: Authenticated, but not allowed: not a member, insufficient project role or the API token lacks the required scope.
- `404`: Not found, or not visible to the caller (tenancy is enforced: foreign resources look identical to missing ones).
- `429`: Rate limited. Back off and retry after the window in the `RateLimit-*` headers.

---

[API](https://skmtc.dev/tasg/apis/tasg-api.md) · [All operations](https://skmtc.dev/tasg/apis/tasg-api/llms.txt) · [OpenAPI document](https://skmtc.dev/tasg/apis/tasg-api/revisions/cd2a1dbaf5cf?raw)
