# Tasks

A **task** is the atomic unit of execution — one worker agent, one git worktree, one branch, one outcome. These operations create and read tasks, their comments, their verified review evidence, and their status stream.

Generated from contract version `1.0.0` — the same document [`/v1/api/openapi.json`](/api/openapi/) serves.

## Prerequisites

- An API key in `x-api-key`, or a browser session cookie
- `X-Organization-Id` naming the workspace to act in, unless the session already has an active one
- The base URL for your deployment, `https://server.hlix.ai` by default

## Operations

| Method | Path | Operation |
| --- | --- | --- |
| `GET` | `/v1/api/tasks` | [List tasks in the workspace](#list-tasks-in-the-workspace) |
| `POST` | `/v1/api/tasks` | [Create a standalone task](#create-a-standalone-task) |
| `GET` | `/v1/api/tasks/{id}` | [Get one task](#get-one-task) |
| `PATCH` | `/v1/api/tasks/{id}` | [Update a task's title, description or status](#update-a-tasks-title-description-or-status) |
| `GET` | `/v1/api/tasks/{id}/comments` | [List the comments on a task](#list-the-comments-on-a-task) |
| `POST` | `/v1/api/tasks/{id}/comments` | [Comment on a task](#comment-on-a-task) |
| `POST` | `/v1/api/tasks/{id}/execute` | [Execute a task standalone (not implemented)](#execute-a-task-standalone-not-implemented) |
| `GET` | `/v1/api/tasks/{id}/review` | [Get the verified review evidence for a task](#get-the-verified-review-evidence-for-a-task) |
| `GET` | `/v1/api/tasks/{id}/stream` | [Stream a task's status changes (SSE)](#stream-a-tasks-status-changes-sse) |

## List tasks in the workspace

`GET /v1/api/tasks` · operation ID `listTasks`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `projectId` | query | no | string | Only tasks in this project. |
| `status` | query | no | string | Only tasks in this status. |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | Task[] | The matching tasks. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |

## Create a standalone task

`POST /v1/api/tasks` · operation ID `createTask`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `CreateTask` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `description` | string | **yes** | min length 1, max length 5000 |
| `projectId` | string (uuid) | **yes** |  |
| `title` | string | no | min length 1, max length 200 |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `201` | Task | The created task. |
| `400` | ValidationError \| ApiError | The JSON body failed schema validation (`ValidationError`), or the request named no active organization (`ApiError`). |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such project in this workspace — or a client collaborator it was never shared with (existence is deliberately not revealed). |
| `500` | ApiError | The task could not be created. |

## Get one task

`GET /v1/api/tasks/{id}` · operation ID `getTask`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | Task | The task. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such task in this workspace. |

## Update a task's title, description or status

`PATCH /v1/api/tasks/{id}` · operation ID `updateTask`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `UpdateTask` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `description` | string | no | min length 1, max length 5000 |
| `status` | `queued` | `blocked` | `building` | `testing` | `reviewing` | `approved` | `merging` | `merged` | `pr_created` | `ci_passing` | `done` | `failed` | no |  |
| `title` | string | no | min length 1, max length 200 |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | Task | The updated task. |
| `400` | ValidationError \| ApiError | The JSON body failed schema validation (`ValidationError`), or the request named no active organization (`ApiError`). |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such task in this workspace. |

## List the comments on a task

`GET /v1/api/tasks/{id}/comments` · operation ID `listTaskComments`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | TaskComment[] | The task's comment thread, oldest first. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such task in this workspace. |

## Comment on a task

`POST /v1/api/tasks/{id}/comments` · operation ID `addTaskComment`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `AddTaskComment` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `body` | string | **yes** | min length 1, max length 10000 |
| `messageId` | string (uuid) | no |  |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `201` | TaskComment | The stored comment. |
| `400` | ValidationError \| ApiError | The JSON body failed schema validation (`ValidationError`), or the request named no active organization (`ApiError`). |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such task in this workspace. |
| `409` | ApiError | The supplied `messageId` is already in use — either on another conversation, or on this one with different content. |

## Execute a task standalone (not implemented)

`POST /v1/api/tasks/{id}/execute` · operation ID `executeTask`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such task in this workspace. |
| `501` | ApiError | There is no standalone single-task run. Execute the task's cycle instead. The task is left untouched. |

## Get the verified review evidence for a task

`GET /v1/api/tasks/{id}/review` · operation ID `getTaskReviewEvidence`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | TaskReviewEvidence | The same observation the QA evaluator reviews. Repo-backed, it is a three-dot compare of the task branch against the commit it was cut from; repo-less, it is the delivered workspace archive and there is no diff. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | No such task, or the task has no evidence to show (no branch, no recorded branch point). |
| `502` | ApiError | The repository host could not be reached. |

## Stream a task's status changes (SSE)

`GET /v1/api/tasks/{id}/stream` · operation ID `streamTask`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `id` | path | **yes** | string |  |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | string | One frame per status change, a `keepalive` event roughly every 30s, and the stream closes on a terminal status or after ~20 minutes. A task that does not exist is reported as a `&#123;"error":"Task not found"&#125;` FRAME on an open 200 stream, not as a 404. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Authenticated, but not a member of the named organization — or a client collaborator without the required access on this project. |
| `404` | ApiError | The task's project is out of reach — a client collaborator it was never shared with (existence is deliberately not revealed). |

## If a request fails

These apply to every operation on this page.

- `400` — the body failed schema validation, or the request named no active organization. A `ValidationError` body carries the failing fields; an `ApiError` body carries only `error`.
- `401` — no valid session or API key.
- `403` — authenticated, but not a member of the named organization, or a client collaborator without the required access.
- `404` — no such resource **in this workspace**. Absent and not-visible are deliberately the same answer; do not infer cross-tenant existence from it.
- `409` — the expected revision or state is stale, or another operation currently owns the transition.
- `500` — the operation failed server-side. Retry only where an idempotency key makes that safe.

## Next steps

[API reference](/api/reference/)
  [API & OpenAPI](/api/openapi/)
  [TypeScript SDK](/sdk/typescript/)
  [CLI reference](/reference/cli/)