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.