> ## Documentation Index
> Fetch the complete documentation index at: https://hubify.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Tasks

> Create, assign, and manage tasks on the Kanban board, with status transitions, review workflows, priorities, and dependencies.

# Tasks API

<Note>
  Shipped today: `GET /v1/tasks`, `POST /v1/tasks`, `DELETE /v1/tasks/{taskId}`. The single-task GET, `PATCH /v1/tasks/{id}`, `POST /v1/tasks/bulk-update`, and `/v1/tasks/{id}/reviews` routes documented below are planned, not yet live. Update tasks via the Kanban board or Convex `tasks` mutations for now.
</Note>

Tasks are the unit of work in Hubify Labs. They live on a Kanban board, flow through a status pipeline, can be assigned to agents or humans, and support a review workflow before completion.

## Task Status Lifecycle

```
backlog → todo → in_progress → review → done
```

| Status        | Description                                         |
| ------------- | --------------------------------------------------- |
| `backlog`     | Captured but not yet planned for work               |
| `todo`        | Planned and ready to be picked up                   |
| `in_progress` | Actively being worked on by an agent or human       |
| `review`      | Work complete, awaiting cross-agent or human review |
| `done`        | Reviewed and accepted                               |

## Create a Task

<ParamField body="labId" type="string" required>
  Lab this task belongs to.
</ParamField>

<ParamField body="title" type="string" required>
  Task title (e.g., "Run MCMC convergence diagnostics").
</ParamField>

<ParamField body="description" type="string">
  Detailed description of the work to be done.
</ParamField>

<ParamField body="priority" type="string" default="medium">
  Priority level: `urgent`, `high`, `medium`, `low`.
</ParamField>

<ParamField body="assignedTo" type="string">
  Convex ID of the agent to assign this task to. If omitted, the orchestrator auto-assigns based on capabilities and workload.
</ParamField>

<ParamField body="experimentId" type="string">
  Link this task to an experiment by its display ID (e.g., "EXP-054").
</ParamField>

<ParamField body="dueDate" type="number">
  Due date as Unix timestamp in milliseconds.
</ParamField>

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://www.hubify.com/api/v1/tasks \
    -H "Authorization: Bearer $HUBIFY_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "labId": "j57a8k9m2n3p4q5r",
      "title": "Run MCMC convergence diagnostics",
      "description": "Compute Gelman-Rubin R-hat for all 6 chains in the Planck+BAO dataset",
      "priority": "high",
      "assignedTo": "k68b9l0n3o4p5q6s",
      "experimentId": "EXP-054"
    }'
  ```

  ```typescript TypeScript SDK theme={null}
  const task = await hubify.tasks.create({
    labId: "j57a8k9m2n3p4q5r",
    title: "Run MCMC convergence diagnostics",
    description:
      "Compute Gelman-Rubin R-hat for all 6 chains in the Planck+BAO dataset",
    priority: "high",
    assignedTo: "k68b9l0n3o4p5q6s",
    experimentId: "EXP-054",
  });
  ```
</CodeGroup>

<ResponseField name="data" type="object">
  <Expandable title="Task object">
    <ResponseField name="_id" type="string" required>Convex document ID.</ResponseField>
    <ResponseField name="labId" type="string" required>Parent lab ID.</ResponseField>
    <ResponseField name="title" type="string" required>Task title.</ResponseField>
    <ResponseField name="description" type="string">Task description.</ResponseField>
    <ResponseField name="status" type="string" required>Current status.</ResponseField>
    <ResponseField name="priority" type="string" required>Priority level.</ResponseField>
    <ResponseField name="assignedTo" type="string">Assigned agent ID.</ResponseField>
    <ResponseField name="experimentId" type="string">Linked experiment display ID.</ResponseField>
    <ResponseField name="dueDate" type="number">Due date timestamp (ms).</ResponseField>
    <ResponseField name="createdAt" type="number" required>Creation timestamp (ms).</ResponseField>
    <ResponseField name="completedAt" type="number">Completion timestamp (ms).</ResponseField>
  </Expandable>
</ResponseField>

## List Tasks

<ParamField query="labId" type="string" required>
  Lab ID to list tasks for.
</ParamField>

<ParamField query="status" type="string">
  Filter by status: `backlog`, `todo`, `in_progress`, `review`, `done`.
</ParamField>

<ParamField query="priority" type="string">
  Filter by priority: `urgent`, `high`, `medium`, `low`.
</ParamField>

<ParamField query="assignedTo" type="string">
  Filter by assigned agent ID.
</ParamField>

<ParamField query="limit" type="number" default="50">
  Results per page.
</ParamField>

<ParamField query="cursor" type="string">
  Pagination cursor.
</ParamField>

<CodeGroup>
  ```bash curl theme={null}
  curl "https://www.hubify.com/api/v1/tasks?labId=j57a8k9m2n3p4q5r&status=in_progress" \
    -H "Authorization: Bearer $HUBIFY_TOKEN"
  ```

  ```typescript TypeScript SDK theme={null}
  const tasks = await hubify.tasks.list({
    labId: "j57a8k9m2n3p4q5r",
    status: "in_progress",
  });
  ```
</CodeGroup>

## Get a Task

<CodeGroup>
  ```bash curl theme={null}
  curl https://www.hubify.com/api/v1/tasks/m89c0d1e2f3g4h5i \
    -H "Authorization: Bearer $HUBIFY_TOKEN"
  ```

  ```typescript TypeScript SDK theme={null}
  const task = await hubify.tasks.get({ taskId: "m89c0d1e2f3g4h5i" });
  ```
</CodeGroup>

## Update a Task

<ParamField body="title" type="string">Updated title.</ParamField>
<ParamField body="description" type="string">Updated description.</ParamField>
<ParamField body="status" type="string">New status. Must be a valid transition from the current status.</ParamField>
<ParamField body="priority" type="string">Updated priority.</ParamField>
<ParamField body="assignedTo" type="string">Reassign to a different agent.</ParamField>
<ParamField body="dueDate" type="number">Updated due date.</ParamField>

<CodeGroup>
  ```bash curl theme={null}
  curl -X PATCH https://www.hubify.com/api/v1/tasks/m89c0d1e2f3g4h5i \
    -H "Authorization: Bearer $HUBIFY_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "status": "review",
      "priority": "urgent"
    }'
  ```

  ```typescript TypeScript SDK theme={null}
  await hubify.tasks.update({
    taskId: "m89c0d1e2f3g4h5i",
    status: "review",
    priority: "urgent",
  });
  ```
</CodeGroup>

## Delete a Task

<CodeGroup>
  ```bash curl theme={null}
  curl -X DELETE https://www.hubify.com/api/v1/tasks/m89c0d1e2f3g4h5i \
    -H "Authorization: Bearer $HUBIFY_TOKEN"
  ```

  ```typescript TypeScript SDK theme={null}
  await hubify.tasks.delete({ taskId: "m89c0d1e2f3g4h5i" });
  ```
</CodeGroup>

## Review Workflow

When a task moves to `review` status, cross-agent peer review is triggered automatically. You can also create reviews manually.

### Submit a Review

<ParamField body="taskId" type="string" required>
  Task being reviewed.
</ParamField>

<ParamField body="verdict" type="string" required>
  Review outcome: `approve`, `concern`, `reject`.
</ParamField>

<ParamField body="summary" type="string" required>
  Review summary explaining the verdict.
</ParamField>

<ParamField body="findings" type="string[]">
  Specific findings or issues identified.
</ParamField>

<ParamField body="reviewerModel" type="string">
  Model used for the review (e.g., `gpt-5.5`). Auto-selected for cross-model review if omitted.
</ParamField>

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://www.hubify.com/api/v1/tasks/m89c0d1e2f3g4h5i/reviews \
    -H "Authorization: Bearer $HUBIFY_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "verdict": "approve",
      "summary": "Convergence diagnostics look good. R-hat < 1.01 for all parameters.",
      "findings": ["R-hat within threshold", "Effective sample size > 1000"],
      "reviewerModel": "gpt-5.5"
    }'
  ```

  ```typescript TypeScript SDK theme={null}
  await hubify.tasks.submitReview({
    taskId: "m89c0d1e2f3g4h5i",
    verdict: "approve",
    summary:
      "Convergence diagnostics look good. R-hat < 1.01 for all parameters.",
    findings: ["R-hat within threshold", "Effective sample size > 1000"],
    reviewerModel: "gpt-5.5",
  });
  ```
</CodeGroup>

### List Reviews for a Task

<CodeGroup>
  ```bash curl theme={null}
  curl https://www.hubify.com/api/v1/tasks/m89c0d1e2f3g4h5i/reviews \
    -H "Authorization: Bearer $HUBIFY_TOKEN"
  ```

  ```typescript TypeScript SDK theme={null}
  const reviews = await hubify.tasks.listReviews({
    taskId: "m89c0d1e2f3g4h5i",
  });
  ```
</CodeGroup>

## Task Assignment

### Auto-Assignment

When a task is created without `assignedTo`, the orchestrator assigns it based on:

1. **Capabilities**, match task requirements to agent capabilities
2. **Workload**, prefer agents with fewer active tasks
3. **Reasoning level**, route to the appropriate model tier

### Reassignment

If an assigned agent fails or stalls, the lead agent takes over (the "tilldone" pattern):

```typescript theme={null}
// The lead takes over automatically, but you can also reassign manually
await hubify.tasks.update({
  taskId: "m89c0d1e2f3g4h5i",
  assignedTo: "newAgentId",
});
```

## Bulk Operations

### Bulk Status Update

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://www.hubify.com/api/v1/tasks/bulk-update \
    -H "Authorization: Bearer $HUBIFY_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "taskIds": ["m89c0d1e2f3g4h5i", "n90d1e2f3g4h5i6j"],
      "status": "done"
    }'
  ```

  ```typescript TypeScript SDK theme={null}
  await hubify.tasks.bulkUpdate({
    taskIds: ["m89c0d1e2f3g4h5i", "n90d1e2f3g4h5i6j"],
    status: "done",
  });
  ```
</CodeGroup>
