Set up a board
Shape a board around how a team actually works: add the columns they use, make them reachable, and give them the fields they fill in.
Before you start:
- The board exists. A team is created with its delivery board, so there is normally nothing to create — see Teams and boards.
- A delivery board needs a team. If you create a delivery board, select the
owning team. With the API, send
team_idtoPOST /api/boards. A request with no team returns 422VALIDATION. - A team has one delivery board. A second delivery board for the same team
returns 422
TEAM_HAS_DELIVERY_BOARD, and the response names the board that the team has. You cannot delete the only delivery board of a team, and you cannot change the team of a board. - A strategy or initiative board has a team. Send
team_idto use a team. With noteam_id, Kairos makes an empty team for the board, with the slug<level>-<board slug>and a charter. An administrator adds people to it. - An ADR board can have a team. A team ADR board holds the delivery ADRs of
the team. Send
team_id, and send the prefix of the team (the prefix of its delivery board) ascode_prefix. A different prefix returns 422VALIDATION. An ADR board with no team is an ADR board of the organization. - A team has one ADR board. A second ADR board for the same team returns 422
TEAM_HAS_ADR_BOARD. The response names the board that the team has. - A new board needs a short-code prefix, for example
PLAT. Send it ascode_prefix. It has 2 to 10 capital letters or digits, and the first character is a letter. Each item on the board gets a code with the prefix (PLAT-T-0001). The prefix does not change later. Two live boards of the same level cannot have the same prefix (409CONFLICT). - You hold
configure_boardson that board, or you are an org admin. Steps 1 to 3 return 403 without it. - Step 4 needs org admin specifically. Metadata definitions are tenant-wide, and creating or retiring one is org-admin only — a board capability does not reach them. If you are not one, get the fields created by someone who is and do steps 1 to 3 yourself.
- Board configuration is GUI and API only. The
kairosCLI reads boards (kairos boards list,kairos boards show) and does not configure them, so work from Admin → Boards → your board in the GUI, or call the endpoints directly.
1. Add the columns
Section titled “1. Add the columns”Admin → Boards → your board → Columns, or:
curl -X POST https://<host>/api/boards/<board-id>/columns \ -H "Authorization: Bearer <token>" -H 'Content-Type: application/json' \ -d '{"name":"Review","position":3}'Names and positions are both unique on a board: a clash comes back as 422
DUPLICATE_COLUMN_NAME or DUPLICATE_COLUMN_POSITION rather than being
silently resolved. PATCH on a column renames it or moves it, reordering the
others around the new position.
The lowest-position column is the entry column. Newly created work lands
there, tasks moved in from another board land there, and a request from a
different team goes there. Reordering columns therefore reorders that too — if you put
Review at position 0, new work starts in Review.
2. Make the new column reachable
Section titled “2. Make the new column reachable”A column with no transition edge into it cannot be reached. Adding Review
between Active and Completed means two edges, not one:
curl -X POST https://<host>/api/boards/<board-id>/transitions \ -H "Authorization: Bearer <token>" -H 'Content-Type: application/json' \ -d '{"from_column_id":"<active>","to_column_id":"<review>"}'…then Review → Completed. In the GUI the Transitions panel has From and
To selects and an Add transition button; do it twice.
Duplicate edges are refused with 422 DUPLICATE_TRANSITION, as are edges whose
endpoints are not both on this board.
3. Check it from the board
Section titled “3. Check it from the board”Move a real card through the new edge — drag it in the GUI, or:
curl https://<host>/api/boards/<board-id>/columns -H "Authorization: Bearer <token>"kairos tasks transition <CODE> --to <review-column-id>(--to takes the column’s UUID, not its name.)
A 422 INVALID_TRANSITION lists the allowed target columns by name and id from
where the card is, which is the fastest way to find the edge you forgot. If the
card will go in but not out, you added one edge and needed two.
4. Add the fields the team will fill in — as an org admin
Section titled “4. Add the fields the team will fill in — as an org admin”Board columns say where work is; metadata definitions say what the team records
about it. Admin → Metadata, or
POST /api/metadata-definitions
(org admin only, as is the DELETE below).
Once defined, a field is stamped on an item from the item page, over MCP with
set_metadata, or with
PATCH /api/{entity_type}/{short_code}/metadata
— not from the CLI, which stamps no metadata. It is searchable from anywhere:
kairos search --metadata risk=highRetiring a definition is where people get stuck. DELETE is refused with
409 DEFINITION_IN_USE while any item still carries a value, and neither
?include_deleted=true nor ?force=true overrides it. The trap: once a card is
archived its metadata row is unreachable — there is no route that clears it —
but it is still counted. Clear the stamp before you archive or delete the
card, or that definition can never be retired.
There is nothing to configure for the Planned and Support lanes: work class is
a property of the task, not of the board
(work_class in the CLI).
Group the cards by owner
Section titled “Group the cards by owner”On a delivery, initiative or strategy board, select Group by owner, or add
?by_owner=1 to the URL. The board shows one lane for each person:
- On a delivery board, the owner of a task is the person who has its claim in Active. All other cards are in the lane No owner.
- On an initiative or strategy board, the owner is the owner of the item.
Your lane is first, then the lanes of the other people by name, then
No owner. The board shows one grouping at a time. Group by owner turns
off Group by repository (?by_repo=1), and the reverse. You cannot change the owner when you move a card
to a different lane. You can move a card to a different column in its lane.
Collapse a lane
Section titled “Collapse a lane”To collapse a lane, click the arrow at the left of its name. The lane becomes one row: its name and the number of cards in each column. Click the arrow again to expand the lane. Collapse all and Expand all work on each lane on the board.
This browser keeps the collapsed lanes for each board and each grouping. Other people and other browsers do not see them. When the browser does not let a page keep data, the lanes collapse until you leave the page.
Read the done columns
Section titled “Read the done columns”A done column shows its last 20 cards. These are the cards that entered the column last. The board reads only these 20 cards from the server. The count in the column head is the count of the full column.
To see each card, click Show all N cards. The board then reads each done card. To show the last 20 cards again, click Show the last 20 cards.
Each card shows the days in its column, for example 3 days in column. A card with notes shows the number of its notes, for example 2 notes.
The REST route gives the same data. GET /api/boards/{id}/items?done_limit=20
gives the last 20 cards of each done column. Each card has entered_column_at
and notes_count.
Archive the old done tasks
Section titled “Archive the old done tasks”Click Archive completed on a delivery board. To keep the recent tasks, type a number of days in Older than (days). Kairos then archives only the tasks that entered their done column that many days ago or before. Leave the field empty to archive each done task. A restore brings back each archived task.
- The API:
POST /api/boards/{id}/archive-completed?older_than_days=30. - The MCP tool:
archive_completedwith"older_than_days": 30.
Set a WIP limit on a column
Section titled “Set a WIP limit on a column”A WIP limit is the most live items that a column should hold. For example, set 1 item in Active for each member of the team. Kairos does not refuse a move over the limit. It warns, and the board marks the column.
- On the board settings page (Admin → Boards, then the board), type the limit in the WIP limit field of the column, and click Set limit. To remove the limit, clear the field and click Set limit.
- Or the CLI:
kairos boards wip-limit <board> Active --limit 3, and--noneto remove it. - Or the API:
PATCH /api/boards/{id}/columns/{col_id}with{"wip_limit": 3}, and{"wip_limit": null}to remove it.
The column head on the board shows the live count against the limit, for
example WIP 2/3. When the column has more items than the limit, the chip
says over and the head has a red line. board_items (REST and MCP) gives
the same count. A move into a column over its limit succeeds. The answer has a
warning: the header Kairos-Warning on REST, a line on MCP. A create (into the
entry column), a cancel (into the done column) and a restore warn the same way.
Set a board policy
Section titled “Set a board policy”A board policy is a rule that you turn on or off for one board. A delivery
board has the policies parent_gate and blockers_gate. An initiative board
has the policy owner_gate. parent_gate and owner_gate are on by default.
blockers_gate is off by default.
With parent_gate on, a task moves to Active only while its parent initiative
is in Active or Monitoring. A bucket initiative is always active. A task with
no parent initiative moves freely. Kairos refuses a different move with
PARENT_NOT_ACTIVE.
With owner_gate on, an initiative moves to Active only with an owner. In
Active and in Monitoring, the owner cannot release it. A hand-off to a member
of the board changes the owner. Kairos refuses a different move or release
with OWNER_REQUIRED.
A task can have open blockers: the items that block it and are not done.
Kairos counts a cancelled blocker as open. With blockers_gate off, a move of such a task into
a claims column or a done column succeeds. The answer has a warning that names
each blocker. With blockers_gate on, Kairos refuses the move with BLOCKED.
- The CLI:
kairos boards policy <board>shows the policies.kairos boards policy <board> --parent-gate offturns the policy off.--owner-gate offdoes the same forowner_gate.--blockers-gate onturnsblockers_gateon. - MCP:
set_board_policywithboard, andparent_gate,owner_gateorblockers_gate.my_boardsshows the policies of each board. - The API:
PATCH /api/boards/{id}with{"parent_gate": false}.
You need configure_boards on the board.
Removing a column
Section titled “Removing a column”curl -X DELETE https://<host>/api/boards/<board-id>/columns/<col-id> \ -H "Authorization: Bearer <token>"Two outcomes worth knowing before you try:
- A live card in the column refuses the removal — 422
COLUMN_NOT_EMPTY, with the count indetails.item_count. Move the cards first. - A column holding only archived cards can be removed. It is a soft delete: live boards stop showing the column, its transition edges are kept but no longer apply, and archived cards keep reporting the column they were put away in. That is deliberate — see Archiving — and it has one consequence to plan for: an archived card whose column is gone can no longer be restored. See Find archived work.
Who may do this
Section titled “Who may do this”configure_boards is a board-scoped capability, granted per board through
POST /api/boards/{id}/members or the
GUI’s board members panel — not through the CLI, and not through a role. Org
admins bypass it. On a strategy, initiative or ADR board, the title of the
panel is Team of this board. The members of that board are its team. The full vocabulary is in
Capabilities; why it works this way is
Capabilities and access.
Related
Section titled “Related”- Boards and teams — every column and transition endpoint
- Errors — the
DUPLICATE_*,COLUMN_NOT_EMPTYandDEFINITION_IN_USEcodes with their statuses anddetails - Flight levels
- Move work between boards
- Wind down a team