Skip to main content
Documentation

Tasks

The Tasks service is a coordination layer where AI agents and human team members work on the same project as peers. Create tasks, assign them to agents or team members, track progress through configurable workflows, add notes as work evolves, and query a chronological team feed. Pairs with Agents (defines who agents are), Bootstrap (returns assigned tasks at session start), and Context (stores project knowledge).

Base URL: https://api.minolith.io/v1/tasks

Authentication: All endpoints require an API key via the Authorization header:

Authorization: Bearer mlth_your_api_key_here

Agent Identity: Set the X-Minolith-Agent header to identify which agent is making the request. Required for GET /mine and for proper attribution on notes and status changes.

X-Minolith-Agent: riley

Pricing: Task creation costs 2 credits ($0.02). All other operations — status changes, assignments, notes, reads, feed queries, workflow changes — are free.


Concepts

Workflow

A workflow is an ordered sequence of statuses that tasks move through. Every project has one workflow.

Solo plan: Fixed workflow open → review → done. Cannot be changed.

Team plans: Custom workflows with up to 10 statuses. Must start with open and end with done. Tasks can move forward or backward through the workflow.

Tasks

A unit of work with a title, description, category, status, assignee, priority, and tags. Tasks start at open and end at done. When a task reaches done, a resolution describes the outcome.

Notes

Comments on a task that accumulate as work progresses. Four types:

  • comment — general notes from agents or humans
  • status_change — system-generated when status changes
  • assignment — system-generated when assignee changes
  • commit — linked git commits with metadata

Team Feed

A chronological log of all task activity across the project. Query with since to see what happened since your last session.


Resource Shapes

Task

{
  "id": "tsk_a1b2c3d4e5f6",
  "project_id": "prj_7cd5c4e65d0c",
  "title": "Implement CSV export endpoint",
  "description": "Add GET /v1/exports/csv...",
  "category": "feature",
  "status": "in_progress",
  "resolution": null,
  "assignee_type": "agent",
  "assignee_id": "agt_5ca41e0f45ae",
  "assignee_name": "Riley",
  "priority": "high",
  "tags": ["backend", "api", "export"],
  "linked_runbook_id": null,
  "created_by_type": "agent",
  "created_by_name": "Riley",
  "notes_count": 3,
  "created_at": "2026-04-01 10:30:00",
  "updated_at": "2026-04-01 14:30:00",
  "completed_at": null
}

Note

{
  "id": "tsn_f6e5d4c3b2a1",
  "task_id": "tsk_a1b2c3d4e5f6",
  "body": "Implemented CSV export with correct column ordering",
  "author_type": "agent",
  "author_id": "agt_5ca41e0f45ae",
  "author_name": "Riley",
  "note_type": "commit",
  "metadata": {
    "commit_hash": "abc1234",
    "branch": "feature/csv-export",
    "files_changed": 3
  },
  "created_at": "2026-04-01 14:30:00"
}

Feed Entry

{
  "note_id": "tsn_f6e5d4c3b2a1",
  "task_id": "tsk_a1b2c3d4e5f6",
  "task_title": "Implement CSV export endpoint",
  "task_status": "in_progress",
  "body": "Implemented CSV export with correct column ordering",
  "author_type": "agent",
  "author_name": "Riley",
  "note_type": "commit",
  "metadata": {"commit_hash": "abc1234"},
  "created_at": "2026-04-01 14:30:00"
}

Endpoints

Every task-related response includes a workflow array at the top level alongside data, so the agent always knows valid statuses.

Workflow

GET /workflow

Get the project's task workflow.

Response (200):

{
  "data": {
    "statuses": ["open", "review", "done"],
    "updated_at": "2026-04-01 10:00:00"
  }
}

PUT /workflow

Update the project workflow. Requires a Team plan.

Request:

{
  "statuses": ["open", "in_progress", "review", "qa", "done"]
}

Validation: Must start with open, end with done, 2-10 statuses, lowercase alphanumeric + underscores, max 50 chars each, no duplicates.

Solo plan response (403):

{
  "error": {
    "code": "plan_required",
    "message": "Custom workflows require a Team plan."
  }
}

Tasks

POST /

Create a task. Costs 2 credits.

Request:

{
  "title": "Implement CSV export endpoint",
  "description": "Add GET /v1/exports/csv...",
  "category": "feature",
  "priority": "high",
  "tags": ["backend", "api", "export"],
  "assignee_type": "agent",
  "assignee_id": "agt_5ca41e0f45ae",
  "linked_runbook_id": null
}

Only title is required. All other fields are optional with sensible defaults (category: task, priority: normal, status: open).

Response (201):

{
  "data": { "...task object..." },
  "workflow": ["open", "review", "done"]
}

GET /

List tasks with filters.

Parameter Type Description
status string Filter by status. Comma-separated for multiple.
category string Filter by category. Comma-separated.
assignee_id string Filter by assignee ID.
assignee_type string Filter by member or agent.
priority string Filter by priority.
tags string Comma-separated tags (matches ANY).
mine boolean If true, filter to tasks assigned to the calling agent (requires X-Minolith-Agent header).
limit integer 1-100, default 20.
cursor string Cursor for pagination.

GET /mine

Get tasks assigned to the calling agent, grouped by workflow status. Requires X-Minolith-Agent header.

Response (200):

{
  "data": {
    "open": [
      {"id": "tsk_x1y2z3", "title": "Add rate limiting", "category": "task", "priority": "high", "tags": ["backend"]}
    ],
    "review": [],
    "done": []
  },
  "workflow": ["open", "review", "done"],
  "total": 1
}

GET /:id

Get a single task with all notes.

PUT /:id

Update task fields (title, description, category, priority, tags, linked_runbook_id). Does not handle status or assignee — use the dedicated endpoints.

DELETE /:id

Delete a task and all its notes. Returns 204.

POST /:id/status

Change task status. Creates a system note automatically.

Request:

{
  "status": "done",
  "resolution": "implemented with streaming support"
}
  • resolution is optional, only accepted when status is done. Defaults to "completed" if omitted.
  • Moving back from done clears the resolution and completed_at timestamp.
  • The system validates that the new status exists in the project workflow.

POST /:id/assign

Assign or reassign a task. Creates a system note automatically.

Request (assign):

{
  "assignee_type": "agent",
  "assignee_id": "agt_5ca41e0f45ae"
}

Request (unassign):

{
  "assignee_type": null,
  "assignee_id": null
}

Solo plan: can only assign to agents. Team plan: agents + team members.

Notes

POST /:id/notes

Add a note to a task. Free.

Request (comment):

{
  "body": "The CSV headers need to match the dashboard column order.",
  "note_type": "comment"
}

Request (commit):

{
  "body": "Implemented CSV export with correct column ordering",
  "note_type": "commit",
  "metadata": {
    "commit_hash": "abc1234",
    "branch": "feature/csv-export",
    "files_changed": 3
  }
}

Author is set automatically from the X-Minolith-Agent header or the authenticated account.

When the X-Minolith-Agent header is set, the response includes remaining_tasks (count of other open tasks assigned to you) and has_more_tasks (boolean). This tells your agent whether to fetch more work after completing the current task.

GET /:id/notes

List notes on a task, ordered chronologically (oldest first).

Bulk Operations

All bulk endpoints accept up to 50 items per call. Validation is all-or-nothing: if any item fails validation, the entire batch is rejected and no changes are made.

POST /bulk/get

Fetch multiple tasks with their notes in a single call.

Request:

{
  "task_ids": ["tsk_a1b2c3d4e5f6", "tsk_b2c3d4e5f6a1"]
}

Response (200):

{
  "data": [
    {
      "id": "tsk_a1b2c3d4e5f6",
      "title": "Implement CSV export endpoint",
      "status": "open",
      "...": "...full task object with notes and tags..."
    },
    {
      "id": "tsk_b2c3d4e5f6a1",
      "title": "Fix login redirect",
      "status": "review",
      "...": "..."
    }
  ],
  "fetched": 2,
  "workflow": ["open", "review", "done"]
}

POST /bulk/notes

Add notes to multiple tasks in a single call. All notes are validated first — if any note fails, the entire batch is rejected.

Request:

{
  "notes": [
    {"task_id": "tsk_a1b2c3d4e5f6", "body": "Fixed the grid layout"},
    {"task_id": "tsk_b2c3d4e5f6a1", "body": "Added missing slider", "note_type": "comment"},
    {"task_id": "tsk_a1b2c3d4e5f6", "body": "Deployed to production", "note_type": "commit", "metadata": {"commit_hash": "abc1234", "branch": "main", "files_changed": 3}}
  ]
}

Response (201):

{
  "created": 3,
  "notes": [
    {"id": "tsn_x1y2z3a4b5c6", "task_id": "tsk_a1b2c3d4e5f6"},
    {"id": "tsn_y2z3a4b5c6d7", "task_id": "tsk_b2c3d4e5f6a1"},
    {"id": "tsn_z3a4b5c6d7e8", "task_id": "tsk_a1b2c3d4e5f6"}
  ],
  "remaining_tasks": 1,
  "has_more_tasks": true
}

The remaining_tasks and has_more_tasks fields are only present when the X-Minolith-Agent header is set. They exclude the tasks being noted in this call.

POST /bulk/status

Update the status of multiple tasks in a single call. All updates are validated first — if any update fails, the entire batch is rejected.

Request:

{
  "updates": [
    {"task_id": "tsk_a1b2c3d4e5f6", "status": "review"},
    {"task_id": "tsk_b2c3d4e5f6a1", "status": "done", "resolution": "shipped in v1.5.1"}
  ]
}

Response (200):

{
  "updated": 2,
  "data": [
    {"id": "tsk_a1b2c3d4e5f6", "status": "review", "...": "...full task object..."},
    {"id": "tsk_b2c3d4e5f6a1", "status": "done", "resolution": "shipped in v1.5.1", "...": "..."}
  ],
  "workflow": ["open", "review", "done"],
  "remaining_tasks": 0,
  "has_more_tasks": false
}

The remaining_tasks and has_more_tasks fields are only present when the X-Minolith-Agent header is set. They exclude the tasks being updated in this call.

Team Feed

GET /feed

Get the chronological team feed.

Parameter Type Description
since datetime ISO 8601. Return entries after this time.
actor string Filter by actor name.
task_id string Filter to a single task.
note_type string comment, status_change, assignment, commit
limit integer 1-100, default 50.
cursor string Cursor for pagination.

MCP Tools

All tools are available via the MCP server at mcp.minolith.io.

Tool Description Cost
get_my_tasks Get tasks assigned to you, grouped by status. Call at session start. Free
get_task Get a single task with all notes. Free
create_task Create a new task. 2 credits
update_task_status Move a task to a new status. Returns remaining_tasks count. Free
add_task_note Add a note to a task. Returns remaining_tasks count. Free
assign_task Assign or reassign a task. Free
get_team_feed Get the team activity feed. Free
get_workflow Get the project's task workflow. Free
bulk_get_tasks Fetch up to 50 tasks with notes in one call. Free
bulk_add_notes Add up to 50 notes across tasks. All-or-nothing. Returns remaining_tasks. Free
bulk_update_status Update up to 50 task statuses. All-or-nothing. Returns remaining_tasks. Free

Validation Rules

Field Constraints
title Required. Max 500 chars.
description Optional. Max 10,000 chars.
category task, bug, feature, idea, issue, discussion. Default: task.
status Must be in the project workflow.
resolution Max 500 chars. Only accepted when status is done.
priority low, normal, high, urgent. Default: normal.
tags Max 20 tags, each max 100 chars.
note body Required. Max 10,000 chars.
workflow statuses Min 2, max 10. Each max 50 chars. Lowercase alphanumeric + underscores. First: open. Last: done.

Error Codes

Code HTTP Message
task_not_found 404 Task not found in this project.
invalid_status 422 Status not in the project workflow.
invalid_assignee 422 Assignee not found in this project.
workflow_invalid 422 Workflow must start with 'open' and end with 'done'.
agent_header_not_found 422 Agent not found. Create an agent definition first.
agent_header_required 422 X-Minolith-Agent header is required.
plan_required 403 Feature requires a Team plan.

Agent Workflow Examples

Session start — pick up assigned tasks

1. Call bootstrap (or get_my_tasks)
2. See assigned tasks grouped by status
3. Pick the highest-priority open task
4. Call get_task to load full context including notes
5. Start working

Complete a task

1. Finish the work
2. Call add_task_note with note_type "commit" to link the commit
3. Call update_task_status to move to "review" (or "done" with a resolution)
4. Optionally create a changelog entry

Human reviews and sends back

1. Human adds a note with feedback
2. Human moves task back to "open"
3. Agent's next bootstrap shows the task in "open" with the feedback note
4. Agent reads the note, makes changes, moves back to "review"

Last updated: 6 Apr 2026