Boards and sprints

Reading boards, moving cards between columns, planning the backlog and running sprints.

All paths are under https://your-workspace.albaticket.com/api/v1. A board is named by its number, the one in its address (/boards/3). Every action works on the tickets of the board's projects that the member can see.

Boards

GET /boards

The boards the member can see: those drawing from at least one project they can see.

{
  "boards": [
    {
      "number": 3,
      "name": "Web team",
      "kind": "scrum",
      "projects": ["WEB"],
      "owner": {"id": "5f0c2a1e-…", "name": "Ada Lovelace"},
      "url": "https://your-workspace.albaticket.com/boards/3"
    }
  ]
}

kind is scrum (with sprints and a backlog) or kanban. projects are the keys of the board's projects the member can see; a board that draws from every project lists them all.

GET /boards/{number}

The board's columns, left to right, each with its cards in board order, as the board page shows them.

Argument
sprint On a scrum board: which sprint to show, by name or id, or none for every ticket. Left out, the active sprint (or every ticket when none is active).
{
  "number": 3,
  "name": "Web team",
  "kind": "scrum",
  "projects": ["WEB"],
  "owner": {"id": "5f0c2a1e-…", "name": "Ada Lovelace"},
  "url": "https://your-workspace.albaticket.com/boards/3",
  "sprint": {
    "id": "8c3a…",
    "name": "Sprint 14",
    "goal": "Ship the new checkout",
    "state": "active",
    "start_at": "2026-09-15T00:00:00.000000Z",
    "end_at": "2026-09-29T00:00:00.000000Z",
    "completed_at": null
  },
  "columns": [
    {"index": 0, "name": "To do", "statuses": ["Open"], "min": null, "max": null, "tickets": […]},
    {"index": 1, "name": "Doing", "statuses": ["In Progress", "In Review"], "min": null, "max": 3, "tickets": […]},
    {"index": 2, "name": "Done", "statuses": ["Resolved", "Closed"], "min": null, "max": null, "tickets": […]}
  ],
  "unmapped": 0,
  "hidden_done": 3,
  "done_retention_days": 14
}
Field
columns[].statuses The statuses a column shows. A ticket is in the column holding its status.
columns[].min, max The column's work-in-progress limits, or null. They are shown, not enforced.
columns[].tickets Ticket summaries, at most 500 on the board
unmapped How many tickets are in a status no column shows, and so on no column
hidden_done How many done tickets are left off for being done longer than the board keeps them
done_retention_days How many days done tickets stay on the board, from their resolution, or else from their last status change; null keeps them always

Moving cards

POST /boards/{number}/moves

Moves a ticket into a column and places it among the column's cards, exactly as dragging it does. Answers with the ticket, shaped as GET /tickets/{key}.

Field
key Required. The ticket.
column Required. The column's name, or its index from 0.
before / after A ticket key in that column to land before or after. Left out, the end of the column.
resolution, comment, assignee, fields For a move whose transition asks for them (see below); fields are custom fields by key
comment_internal true makes the comment an internal note the customer does not see
POST /boards/3/moves
Content-Type: application/json

{"key": "WEB-142", "column": "Doing", "before": "WEB-139"}

Into another column is a move through the workflow: the ticket takes the first transition the member may take to one of the column's statuses. It needs ticket:transition. If there is no such transition, the answer is 422 (no_transition).

Within its column it is a change of order and needs ticket:edit.

Some transitions ask for something, usually a resolution when a ticket is done. The browser shows a form; the API needs the answer given with the move:

POST /boards/3/moves
Content-Type: application/json

{"key": "WEB-142", "column": "Done", "resolution": "Done", "comment": "Released in 2.5."}

Without it, nothing changes and the answer is 422, naming the transition and what it asks for. Nothing is ever half-moved.

The backlog

GET /boards/{number}/backlog

A scrum board's open sprints (active first, then those not yet started, in order), each with its tickets, then the backlog: open tickets in the board's projects that are in no open sprint, in rank order.

{
  "board": 3,
  "sprints": [
    {
      "id": "8c3a…",
      "name": "Sprint 14",
      "goal": "Ship the new checkout",
      "state": "active",
      "start_at": "2026-09-15T00:00:00.000000Z",
      "end_at": "2026-09-29T00:00:00.000000Z",
      "completed_at": null,
      "tickets": […]
    },
    {"id": "e7b0…", "name": "Sprint 15", "state": "future", "tickets": […], …}
  ],
  "backlog": […]
}

Tickets are summaries. The backlog holds at most 500.

POST /boards/{number}/backlog/moves

Puts a ticket into an open sprint, or back into the backlog, and places it in that list. Needs ticket:edit. Answers with the ticket.

Field
key Required
sprint Required. An open sprint's name or id, or backlog.
before / after A ticket key in that list. Left out, the end.
POST /boards/3/backlog/moves
Content-Type: application/json

{"key": "WEB-150", "sprint": "Sprint 15", "after": "WEB-148"}

A ticket is in one open sprint of a board at a time: moving it into another takes it out of the first. The ticket's history records the change of sprint.

Sprints

GET /boards/{number}/sprints

Every sprint of the board, closed ones included, and whether the member may manage them:

{
  "board": 3,
  "can_manage": true,
  "sprints": [
    {"id": "8c3a…", "name": "Sprint 14", "goal": "Ship the new checkout", "state": "active", "start_at": "…", "end_at": "…", "completed_at": null},
    {"id": "e7b0…", "name": "Sprint 15", "goal": null, "state": "future", "start_at": null, "end_at": null, "completed_at": null},
    {"id": "11f2…", "name": "Sprint 13", "goal": null, "state": "closed", "start_at": "…", "end_at": "…", "completed_at": "…"}
  ]
}

A sprint is future until it starts, active while it runs (a board runs one at a time) and closed once completed.

Managing sprints (everything below) needs what the backlog page needs: being an installation administrator, or holding project:admin in every project the board draws from, and a token with write access. can_manage says whether the member does. Anyone else is answered 403. Planning tickets into sprints only needs ticket:edit.

In the paths below, {sprint} is the sprint's name or id. Encode spaces in a name (Sprint%2015), or use the id.

POST /boards/{number}/sprints

Adds a future sprint at the end of the board's sprints. Answers 201 with the sprint.

Field
name Required
goal
start_date, end_date YYYY-MM-DD (midnight UTC) or an ISO 8601 time

PATCH /boards/{number}/sprints/{sprint}

Changes a sprint's name, goal, start_date or end_date. Send only what changes.

POST /boards/{number}/sprints/{sprint}/start

Starts a future sprint. end_date is required unless the sprint has one; start_date defaults to now.

POST /boards/3/sprints/Sprint%2015/start
Content-Type: application/json

{"end_date": "2026-10-13"}

While another sprint is active the answer is 409 (sprint_active). A sprint that is not future answers 409 (wrong_state).

POST /boards/{number}/sprints/{sprint}/complete

Completes the active sprint. Its done tickets stay in it, for its reports; the rest move on.

Field
move_open_to Another open sprint's name or id, or backlog. Default backlog.
{
  "id": "8c3a…",
  "name": "Sprint 14",
  "state": "closed",
  "completed_at": "2026-09-29T16:40:12.000000Z",
  "moved": ["WEB-148", "WEB-151"],
  …
}

moved lists the unfinished tickets that went to move_open_to. Each has a history entry.

DELETE /boards/{number}/sprints/{sprint}

Deletes a sprint that has not started. Its tickets go back to the backlog, each with a history entry. An active or closed sprint cannot be deleted (409, wrong_state).

{"deleted": {"id": "e7b0…", "name": "Sprint 15", "state": "future", …}}

What is not here

Creating, changing and deleting boards, and their columns, filters and swimlanes, are done in the browser by the board's owner or an administrator. Sprint reports (burndown, velocity) are on the board's reports page.