Browse the docs

API reference

Work

Tasks, stories and bugs across every product, with their comments.

List work

GET/v1/work

Open work, at most 60 rows, soonest due first by default. Epics are excluded, and counts describes the caller's own planned work and the triage queue regardless of the filters.

Requires work.read

Query parameters

  • whoenum

    Only work assigned to the caller, only work assigned to the agent, or everyone's.

    mineagentteam

  • assigneestring

    Legacy form of who=mine; who wins when both are given.

    me

  • unassignedboolean

    When true, only work with no assignee.

  • statusenum

    One status; without it the list holds TODO, IN_PROGRESS and IN_REVIEW.

    BACKLOGTODOIN_PROGRESSIN_REVIEWDONECANCELLED

  • sourceenum

    Only work the agent proposed.

    AGENT

  • lateboolean

    When true, only work whose due date has passed.

  • projectstring

    A product slug, or several separated by commas (up to 20).

  • qstring

    Case-insensitive search over title and description.

  • priorityenum

    Only work at this priority.

    LOWNORMALHIGHURGENT

  • sortenum

    Ordering; defaults to due.

    dueprioritynewest

Request
curl "https://atrix.dev/api/v1/work" \
  -H "Authorization: Bearer $ATRIX_TOKEN"
Response
{
  "truncated": false,
  "counts": {
    "overdue": 2,
    "today": 1,
    "week": 4,
    "later": 3,
    "none": 1,
    "triage": 5
  },
  "items": [
    {
      "id": "cm9x2k7f40001ab12cd34ef56",
      "title": "Retry failed Stripe webhooks",
      "status": "IN_PROGRESS",
      "priority": "HIGH",
      "type": "TASK",
      "source": "USER",
      "assigneeKind": "HUMAN",
      "epic": {
        "id": "cm9x2k7f40000ab12cd34ef56",
        "title": "Payments"
      },
      "comments": 3,
      "project": "Atrix Mail",
      "projectSlug": "atrix-mail",
      "daysLate": 2,
      "dueOn": "2026-10-25",
      "startOn": null,
      "assignee": {
        "id": "cm8q1z0a10003xy98wv76ut54",
        "name": "Sara Khan",
        "image": null
      }
    }
  ]
}

Create work

POST/v1/work

Opens a task, story or bug in a product, through the same core the board uses. Epics are refused; refusals come back as { error }.

Requires work.write

Body

  • projectIdstringrequired

    The product the work belongs to.

  • titlestringrequired

    What needs doing.

  • dueDateISO date | null

    When it is due.

  • priorityenum

    Defaults to the board's default.

    LOWNORMALHIGHURGENT

  • typeenum

    The kind of work; EPIC is refused.

    STORYTASKBUG

  • statusenum

    Starting status.

    BACKLOGTODOIN_PROGRESSIN_REVIEWDONECANCELLED

Request
curl -X POST "https://atrix.dev/api/v1/work" \
  -H "Authorization: Bearer $ATRIX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "projectId": "cm9x2k1a0000", "title": "…" }'
Response
{
  "ok": true,
  "id": "cm9x2k7f40001ab12cd34ef56"
}

Get work

GET/v1/work/{id}

One work item with its description, epic, children (up to 50) and the last 20 status changes as activity. Epics return 404.

Requires work.read

Path parameters

  • idstringrequired

    The work item id.

Request
curl "https://atrix.dev/api/v1/work/ID" \
  -H "Authorization: Bearer $ATRIX_TOKEN"
Response
{
  "id": "cm9x2k7f40001ab12cd34ef56",
  "title": "Retry failed Stripe webhooks",
  "description": "Back off exponentially, give up after 24h.",
  "status": "IN_PROGRESS",
  "priority": "HIGH",
  "type": "STORY",
  "source": "USER",
  "assigneeKind": "HUMAN",
  "startAt": null,
  "startOn": null,
  "completedAt": null,
  "completedBy": null,
  "requirement": {
    "id": "cm9r4t5y60002pq34rs56tu78",
    "key": "REQ-12",
    "title": "Reliable billing"
  },
  "epic": {
    "id": "cm9x2k7f40000ab12cd34ef56",
    "title": "Payments",
    "status": "IN_PROGRESS"
  },
  "children": [
    {
      "id": "cm9x2k7f40004ab12cd34ef56",
      "title": "Log each retry",
      "status": "TODO",
      "type": "TASK",
      "priority": "NORMAL"
    }
  ],
  "project": "Atrix Mail",
  "projectSlug": "atrix-mail",
  "dueAt": "2026-10-25T00:00:00.000Z",
  "daysLate": 2,
  "assignee": {
    "id": "cm8q1z0a10003xy98wv76ut54",
    "name": "Sara Khan",
    "image": null
  },
  "activity": [
    {
      "id": "cm9y0b1c20007de45fg67hi89",
      "what": "moved this to In progress",
      "at": "2026-10-24T09:12:00.000Z",
      "who": {
        "id": "cm8q1z0a10003xy98wv76ut54",
        "name": "Sara Khan",
        "image": null
      }
    }
  ]
}

Update work

PATCH/v1/work/{id}

Changes any combination of the fields below, each through the core that owns it, in a fixed order where the first refusal wins. null clears a date; an omitted field is left alone.

Requires work.write

Path parameters

  • idstringrequired

    The work item id.

Body

  • statusenum

    New status, recorded in the status history.

    BACKLOGTODOIN_PROGRESSIN_REVIEWDONECANCELLED

  • assigneeobject

    { kind, memberId? } where kind is UNASSIGNED, HUMAN or AGENT; HUMAN needs a memberId.

  • dueDateISO date | null

    Due date, or null to clear it.

  • startDateISO date | null

    Start date, or null to clear it.

  • priorityenum

    New priority.

    LOWNORMALHIGHURGENT

  • titlestring

    New title.

  • detailstring | null

    New description.

  • typeenum

    New type; promoting to EPIC clears the parent.

    EPICSTORYTASKBUG

  • parentIdstring | null

    The epic to file it under, or null to detach it.

  • requirementIdstring | null

    The requirement to link, or null to unlink.

Request
curl -X PATCH "https://atrix.dev/api/v1/work/ID" \
  -H "Authorization: Bearer $ATRIX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "status": "BACKLOG", "assignee": {} }'
Response
{
  "ok": true
}

Delete work

DELETE/v1/work/{id}

Removes a work item. Its children are detached, never deleted.

Requires work.write

Path parameters

  • idstringrequired

    The work item id.

Request
curl -X DELETE "https://atrix.dev/api/v1/work/ID" \
  -H "Authorization: Bearer $ATRIX_TOKEN"
Response
{
  "ok": true
}

Bulk update work

POST/v1/work/bulk

Applies one change to up to 50 work items. Ids from another workspace are silently dropped, and changed counts the items that were in this one.

Requires work.write

Body

  • idsstring[]required

    Between 1 and 50 work item ids.

  • statusenum

    New status for all of them.

    BACKLOGTODOIN_PROGRESSIN_REVIEWDONECANCELLED

  • assigneeobject

    { kind, memberId? } with kind one of UNASSIGNED, HUMAN, AGENT; HUMAN needs a memberId.

  • priorityenum

    New priority for all of them.

    LOWNORMALHIGHURGENT

  • dueDateISO date | null

    New due date (YYYY-MM-DD), or null to clear it.

Request
curl -X POST "https://atrix.dev/api/v1/work/bulk" \
  -H "Authorization: Bearer $ATRIX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "ids": [] }'
Response
{
  "ok": true,
  "changed": 3
}

List comments

GET/v1/work/{id}/comments

Up to 200 comments, oldest first. Deleted comments come back as tombstones with an empty body, and blocks is the body already parsed into formatted blocks with mentions resolved.

Requires work.read

Path parameters

  • idstringrequired

    The work item id.

Request
curl "https://atrix.dev/api/v1/work/ID/comments" \
  -H "Authorization: Bearer $ATRIX_TOKEN"
Response
{
  "items": [
    {
      "id": "cm9z3d4e50009jk01lm23no45",
      "body": "@Sara can you check the retry window?",
      "blocks": [
        {
          "type": "paragraph",
          "children": [
            {
              "type": "mention",
              "text": "@Sara"
            },
            {
              "type": "text",
              "text": " can you check the retry window?"
            }
          ]
        }
      ],
      "at": "2026-10-26T14:03:00.000Z",
      "editedAt": null,
      "deleted": false,
      "mine": true,
      "author": {
        "id": "cm8q1z0a10001xy98wv76ut54",
        "name": "Moeid Saleem",
        "image": null
      }
    }
  ]
}

Add a comment

POST/v1/work/{id}/comments

Comments on a work item. Mentioned people and whoever carries the work are notified.

Requires work.write

Path parameters

  • idstringrequired

    The work item id.

Body

  • bodystringrequired

    The comment text; @mentions are resolved against the workspace.

Request
curl -X POST "https://atrix.dev/api/v1/work/ID/comments" \
  -H "Authorization: Bearer $ATRIX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "body": "…" }'
Response
{
  "ok": true,
  "id": "cm9z3d4e50009jk01lm23no45"
}

Edit a comment

PATCH/v1/work/{id}/comments

Rewrites a comment. Only its author may edit it.

Requires work.write

Path parameters

  • idstringrequired

    The work item id.

Body

  • commentIdstringrequired

    The comment to edit.

  • bodystringrequired

    The new text.

Request
curl -X PATCH "https://atrix.dev/api/v1/work/ID/comments" \
  -H "Authorization: Bearer $ATRIX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "commentId": "cm9x2k1a0000", "body": "…" }'
Response
{
  "ok": true
}

Delete a comment

DELETE/v1/work/{id}/comments

Removes a comment, leaving a tombstone in the list. The comment id travels in the body, not the path.

Requires work.write

Path parameters

  • idstringrequired

    The work item id.

Body

  • idstringrequired

    The comment to remove.

Request
curl -X DELETE "https://atrix.dev/api/v1/work/ID/comments" \
  -H "Authorization: Bearer $ATRIX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "id": "cm9x2k1a0000" }'
Response
{
  "ok": true
}