---
title: "Create a task"
method: POST
path: "/tasks"
tags: ["Tasks"]
---

# Create a task

`POST /tasks`

## Request

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

Caller must be a project member with a role other than `viewer`. The task is appended to its section, the creator and assignee auto-watch it and the assignee is notified. Subtasks nest up to 5 levels and inherit `blocked` if the parent has incomplete dependencies.

## Request body

- object
  - `title` string, required
  - `description` string
  - `section_id` string, uuid: Must belong to the task's project.
  - `assignee_id` string, uuid: Must be a member of the project.
  - `start_date` string: Any value `new Date()` accepts; use `YYYY-MM-DD`.
  - `due_date` string: 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
  - `relative_offset_from_task_id` string, uuid: 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'
  - `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
  - `recurrence` 'daily' | 'weekly' | 'fortnightly' | 'monthly': 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.
  - `primary_project_id` string, uuid, required
  - `parent_task_id` string, uuid: Create as a subtask of this task (same project).

## Response `201`

Created.

- 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)
