Skip to content

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_id to POST /api/boards. A request with no team returns 422 VALIDATION.
  • 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_id to use a team. With no team_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) as code_prefix. A different prefix returns 422 VALIDATION. 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 as code_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 (409 CONFLICT).
  • You hold configure_boards on 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 kairos CLI 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.

Admin → Boards → your board → Columns, or:

Terminal window
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.

A column with no transition edge into it cannot be reached. Adding Review between Active and Completed means two edges, not one:

Terminal window
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.

Move a real card through the new edge — drag it in the GUI, or:

Terminal window
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:

Terminal window
kairos search --metadata risk=high

Retiring 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).

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.

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.

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.

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_completed with "older_than_days": 30.

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 --none to 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.

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 off turns the policy off. --owner-gate off does the same for owner_gate. --blockers-gate on turns blockers_gate on.
  • MCP: set_board_policy with board, and parent_gate, owner_gate or blockers_gate. my_boards shows the policies of each board.
  • The API: PATCH /api/boards/{id} with {"parent_gate": false}.

You need configure_boards on the board.

Terminal window
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 in details.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.

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.