Kanban
What it is for
The kanban service keeps boards of cards in columns for your organization. People work on a board in the browser and their agents work on the same board through these tools: a card created by one is moved, edited or commented on by another, and every board shows who did what. Use it to plan work, see what is waiting, in progress and done, and keep each task's working detail on its card.
It offers a trial, a number of days of free use, and it can also be enabled in full. Enabled in full, it is billed as a subscription rather than per call: a monthly fee that includes a number of active users, and a fee for each further person who used it within the active-user window, in the browser or through an agent acting for them.
Every tool works on this system's own boards only; none reaches outside it.
Working agreements
A board's description, and each column's description, are its working agreements: how the people on the board want the work done. They come with every snapshot of the board, ahead of its cards, so read them first and follow them: what a card needs before it moves to the next column, what "done" means, who picks up what. Changing them is a change to the board's setup.
Active, open and blocked
Every count and line uses these three words one way:
- An active card is one not archived or deleted, done ones included. A
board's
activeCardCountcounts them, andservices.kanban.max-open-cardslimits them. - An open card is an active card in a column that is not done; its
statusisopen. A card in a done column is done. - A card is blocked when it has a blocked reason (
blockedReason), or an open blocker: an open card on the same board linked as blocking it, by the card's ownblocked-bylink or the other card'sblockslink. Every card answered says whether it is blocked, either way, inisBlocked; a board open and the stand-up also list each card's open blockers inblockedBy.blockedReasonis null on a card held only by an open blocker.
Its tools
Every tool is covered by the subscription: no call is charged on its own, and no tool has a price per call.
Setting a board up (creating, copying, updating or archiving a board, and adding, changing, moving or removing its columns) is for the organization's owners and admins. Working on cards, labels, checklists, links and comments, including moving or archiving a column's cards in bulk, is for any member. An organization's API key holds the admin role.
Every tool but two answers one line of text saying what happened, and the
answer itself as structured content held to the output schema the tool
declares: ids, etags, sequences and cursors are read from that structure, not
from the line. kanban_card_body_read and kanban_card_search answer text,
which is their content: a body's lines, and search hits.
Answers name boards, columns, cards, checklists, items, links and comments by
their ids, and a card also by its number on the board (#12). Every board
and card answer carries its url, the address that opens it in the browser,
but for the cards of a board snapshot, whose address is the board's url
followed by /cards/<number>.
Tools that only read
kanban_board_listlists the organization's boards, most recently updated first, each with its id, link, column and active card counts andsequence;archived: truelists archived boards instead.kanban_board_openopens one board: its working agreements, labels, columns and each column's first page of cards as summaries, never card bodies; each card says whether it is blocked inisBlockedand lists its open blockers inblockedBy. A first-page card leaves out itsurl,columnIdandcolumnName, which the answer gives once: the page key infirstPagesis the card's column id,board.columnsnames that column, and a card's page is<board.url>/cards/<number>. Its line counts the board's active cards, open and done, and how many of the open cards answered are blocked and how many of those by open blockers. Afilternarrows the cards (by text, assignee, label, priority, due date, status, blocked, or mentioning you) and answers each column's match count;blocked: truekeeps the cards with a blocked reason or an open blocker,blocked: falsethe cards with neither; adueofoverdueorweekalso needs your own calendar date as itstoday.kanban_column_cardsreads one page of one column's cards, in board order: the first page, or the next one by following that column'scursorfrom the board snapshot, with the samefilter.kanban_board_activitylists what changed on a board, newest first: each write's sequence, who made it, and when.sinceSequencekeeps only the writes after a sequence you read and answers an empty page when nothing has changed, so it is the cheap check of whether a board needs reading again.actorkeeps only one member's writes andcardIdonly one card's. Every answer carries the board's currentsequence.kanban_board_standupis a board's stand-up digest: for each assignee, and for cards with none, what was completed sincesince, and what is in progress, due soon or overdue, and blocked. A card is listed in every section it qualifies for: an assigned card that is blocked or due is also in progress. Only open cards are listed as in progress, due or blocked, and blocked is decided by the same rule a board open's line uses: a blocked reason or an open blocker. Each card says whether it is blocked inisBlockedand lists its open blockers inblockedBy.kanban_card_getreads a card by itscardIdor by itsnumberon the board (#12), exactly one of the two: its summary, properties, checklists,cardLinks(its links to other cards),inboundLinks(other cards' links to it) andwebLinks(its web addresses), with itscardEtag; never its body. Each link carries thelinkIdthat removes it.kanban_card_body_readreads a card's markdown body, whole or fromfromLinetotoLine, with itsbodyEtag, size and line count.kanban_card_searchlooks for literal text in card bodies, on one board or on every live board, ignoring case, and answers matching lines (lines, with optionalcontextlines either side), matching cards (cards) or a count of matching lines per card (counts). Archived and deleted cards are not searched.kanban_comment_listlists a card's comments, oldest first, each with its author andcommentEtag.kanban_member_listlists the people and agents who can be assigned and mentioned, by display name and handle, and says which one is you.
Tools that add or change things
None of these drops anything a later call cannot set again.
kanban_board_createcreates boards, several in one call, each with its columns and labels, all or none. A board sent without columns starts with To do, In progress and Done. A column may carry a WIP limit, the most cards it may hold, within the board'swipMinandwipMax; one left out starts at the board'swipDefault, and a WIP limit of 0 means no limit. A done column (done: true) marks its cards done, withdoneStatusas their sub-status, such asshipped.kanban_board_copycreates a new board with another board's description, columns and labels under a newname. It copies no cards.kanban_board_updaterenames a board, replaces its description, or archives (archived: true) or restores (archived: false) it. Only the fields sent change.kanban_column_bulkacts on every card in a column in one write:archivearchives them all, andmovemoves them all to the end oftoColumnId, in order. A move is refused, with no card moved, when the target's WIP limit would be passed. It answers the board askanban_board_opendoes.kanban_card_createcreates whole cards in one column in one call, all or none: title, summary, markdown body, labels by name, assignees by handle, priority, dates, a blocked reason (blockedReason), checklists and web links (webLinks). Card links are added afterwards withkanban_card_links. It is refused when the column's WIP limit would be passed.kanban_card_moveplaces a card in a column after another card, first (afterCardId: null) or, with noafterCardId, last. It changes the card's position only, needs no etag, and is refused when the target column's WIP limit is full.kanban_card_updatechanges a card in one write, all or none: its title, summary, priority, dates, cover color or blocked reason (blockedReason, null clearing it), the labels (by name) and assignees (by handle) to add and remove, and whether it is archived. Only the fields sent change.archived: truearchives the card, the ordinary way to clear a finished card off the board;archived: falsebrings back an archived card at any time, or a deleted one within the undo window, at the end of its column, and is refused when that column's WIP limit is full. Until it is restored, an archived card's body can still be read withkanban_card_body_readand the card can be deleted, andkanban_card_updatetakes it (archived: falserestores it andarchived: truechanges nothing); every other card tool answers it as not found, and a body search skips it.kanban_card_copycreates a copy of a card right after it, on the same board only, with the next number: its properties, body, labels, assignees, checklists, card links and web links, never its comments.
More tools that add and change
These add or change and remove nothing; removals are kanban_remove's.
kanban_column_writemakes one change to one column per call; owners and admins only. With nocolumnIdit adds a column at the end of the board. With acolumnId, its name, description, color, WIP limit, done flag or done sub-status change (only the fields sent),afterColumnIdplaces it after another column, or first when null, andrestore: truebrings back a column removed within the undo window; two of these in one call are refused.kanban_label_writewrites one label, found by itsname. A name the board has no label for creates one withcolor, a palette color; a label's name is unique on the board ignoring case. For an existing label,newNamerenames it on every card that carries it andcolorrecolors it.kanban_card_body_appendaddstextto the end of a card's body, with nothing put between: start it with a line break to begin a new line. It needs no etag and adds to whatever the body holds when it runs, so calling it twice appends twice. It answers the body's newbodyEtag.kanban_checklist_editchanges a card's checklists by a list ofoperations, applied in order, all or none: add a checklist with its items (checklist_add), rename one (checklist_rename), add items to the end of one (item_add), or change an item's text, its own due date, its own assignee or whether it is done (item_update). To copy a checklist from another card, read that card and send its items.kanban_card_linksadds links to a card in one write, all or none. Each link is either a link to another card on the same board, by its number, asblocked-by,blocksorrelates-to, or a web link, an http or https address with an optional title. A card cannot link to itself. The card answers them incardLinksandwebLinks.kanban_comment_writecomments on a card as you, in markdown, or edits a comment you wrote, with itscommentEtag. An@handlein a comment records a mention of that member: the card then shows as mentioning them, and afilterwithmentionsMefinds it for them. Nothing is sent to them. An edit replaces the comment's whole text, keeping no earlier version; another member's comment is refused.
Tools that replace or remove content
These two can drop something a later call cannot set again. A removed card and a removed column can be restored within the undo window, and a removed card is purged for good once the retention period after it passes. Nothing else they replace or remove can be brought back.
kanban_removeremoves one kind of thing per call, named bykind, with the ids that kind takes and no others: a card (cardId), a comment you wrote (cardId,commentId), card links (card_link:cardId,linkIdsfrom the card'scardLinks), web links (web_link:cardId,linkIdsfrom itswebLinks), a checklist (cardId,checklistId), checklist items (cardId,checklistId,itemIds), a column (columnId) or a label (labelName). A list removes all its ids or none. Columns are owners' and admins' only. A column that holds cards cannot be removed: empty it first withkanban_column_bulk; a board's last column cannot be removed.kanban_card_updatewitharchived: falsebrings back a removed card, andkanban_column_writewithrestore: truea removed column, within the undo window. Archive a card instead to clear it off the board without losing it.kanban_card_body_writerewrites a card's body with itsbodyEtag: either the whole newbody, or a list ofedits, applied in order, each to the body the ones before it left, and all or none; exactly one of the two. An edit is afindcopied exactly from the body with thereplacethat takes its place (an emptyreplacedeletes the text). Eachfindmust occur exactly once, unless that edit'sreplaceAllis true. Matching is literal and case-sensitive, spacing and line breaks included. If anyfindis not found, or is found more than once, nothing changes and the refusal names that edit'sindexand how manymatchesit had.
Read before you write
A card's properties, its body and each comment carry an etag of their own,
named for what it guards: cardEtag, bodyEtag and commentEtag. Each
changes whenever that part changes. Rewriting a card's body needs the
bodyEtag from reading the body, from the create or copy that made the card,
or from the last body write, and
editing a comment needs the commentEtag from listing the comments or from
the add. Updating a card checks the cardEtag from reading the card when you
send it; left out, the fields sent are written over whatever the card holds. A
write given an etag the row has moved on from is refused, naming the etag
field and carrying currentEtag, the etag the row is at now, and changes
nothing, so a change another person or agent made meanwhile is never
overwritten unseen. What to do next depends on the write, and the refusal
says which:
- A body write sent as
editsmay be retried at once withcurrentEtagas itsbodyEtag: eachfindis matched against the body as it is then, so an edit whose text has changed is refused rather than applied blindly. - Every other write, a whole
body, a card update or a comment edit, would write over the change it was refused for: read again, look at what changed, then retry with the new etag.
Labels, assignees, archiving, moves and checklist changes leave the
cardEtag as it was, so they never stale a read you are about to write from.
Work on a body in a loop of read, edit, re-read: read the lines you mean to
change, edit them with the bodyEtag the read returned, and keep the new
bodyEtag the write answers for the next edit, because the text has moved. A
body read answers the text as stored, under a header naming the lines it
holds, and a body search shows each line with its card number and line number
in front: neither the header nor those prefixes are part of the body, so leave
them out of a find, or it will not match.
What a write answers
A write answers the ids it created and the values the server decided, never what you sent:
kanban_card_createanswers each card'scardId,number,cardEtagandbodyEtag, its checklists'checklistIdwith their items'itemIds, and its web links'linkIds, every list in the order you sent it, so you can tick an item, update the card or write its body with no read first.kanban_card_copyanswers the copy'scardId,number,cardEtagandbodyEtag, and each new checklist, item and link id paired with the source's (fromChecklistId,fromItemId,fromLinkId).kanban_card_update,kanban_checklist_edit,kanban_card_linksandkanban_removeof a card kind answer the card'scardIdandcardEtag, plus the ids they made (checklistswithitemIdsfor a checklist edit that added something,linkIdsfor links added) andisBlockedonly when the write could change it: ablockedReasonset or cleared, or ablocked-bylink added or removed.kanban_card_body_writeandkanban_card_body_appendanswer the body's newbodyEtag, and a find-and-replace itsreplacements; sendreturnBody: truefor the body itself.
Send returnCard: true on a card write when you want the whole card back, as
kanban_card_get reads it, with every checklist and link; a create or copy
then answers each whole card with its bodyEtag. Removing a column or a label answers
the board and takes no returnCard. The tools that take returnCard are
exactly kanban_card_update, kanban_checklist_edit, kanban_card_links,
kanban_card_create, kanban_card_copy and kanban_remove of a card kind.
Working together
Repeating a create safely. The creates of boards, cards and columns, the
board and card copies, and a card's checklist and link writes take an
idempotencyKey: any string unique to that call (on a batch of boards or
cards, only the first entry carries it). Repeat the call with the same key and
it answers what the first call made, as it stands now, instead of making it
again. A key whose first attempt failed, or is still running, is
refused as in flight: read the board to see what is there, then retry with a
new key if it is still needed. A label write and a comment take no key: a
repeated label write finds the label it made, and a repeated comment is posted
twice.
People and agents by handle. Members are named by opaque handles from the
member list, never by id or email: an assignee, a checklist item's assignee,
the actor of an activity read, and an @handle mention. me names you, for
a person and for an agent the member list shows; for a caller the members do
not list, the list's me is null and naming me is refused.
Changes that are safe to repeat. Adding a label a card already carries, assigning a member already assigned, removing what is not there and setting an item to the state it is already in are no change, so these calls are safe to repeat.
Who did what. Every write that changes the board raises its sequence and
answers the new one: by one for each change it records, so a card create raises it once
per card it creates. The board's activity names each write's actor by display name and
handle and marks a person's change made through an agent "via AI", so people
on the board can tell their own edits from their agents'. Before re-reading a
board, read its activity since the sequence you hold: an empty page means
nothing has changed.
Paging
The board list, a column's cards, a board's activity, a card's comments and a
body search answer a page at a time, each with a cursor: while there is a
next page, pass it back with every other argument unchanged to read it; a
null cursor marks the last page. A body search, which answers text, ends
with a "More" line naming the cursor while there is a next page, and has no
"More" line on its last page.
A board snapshot holds each column's first page only, with that column's own
cursor; read the rest of a column with kanban_column_cards.
A card body read whole is bounded by the read bound in the tool's description.
A line range stops at that bound and answers truncated: continue from the
line after the last one answered. A body search page likewise stops after a
bounded amount of reported text and answers truncated with a cursor.
The activity feed keeps a board's history for the retention period only. Its
answer's oldestRetained is the lowest sequence still kept; anything older has
been purged, so a gap below it cannot be read.
The stand-up digest is judged against your dates, not the server's: send
since (yesterday, for a daily stand-up) and today as your own calendar
dates, and the answer states both. Each of its lists shows a bounded number of
cards and counts the rest in more.
Its settings
Your organization's own limits, each capped by a platform ceiling of the same
key with -ceiling added (services.kanban.max-boards-ceiling); the smaller
of the two is the limit in force:
services.kanban.max-boards: the boards the organization may hold, archived boards included;services.kanban.max-open-cards: the active cards one board may hold, done ones included;services.kanban.max-cards: the cards one board may hold, archived cards included;services.kanban.max-columns: the columns one board may have;services.kanban.max-labels: the labels one board may define;services.kanban.max-checklists: the checklists the cards of one board may hold in all;services.kanban.max-checklists-per-card: the checklists one card may hold;services.kanban.max-items-per-checklist: the items one checklist may hold;services.kanban.max-attachments-per-card: the links one card may carry;services.kanban.max-assignees-per-card: the assignees one card may have;services.kanban.max-comments-per-card: the comments one card may hold;services.kanban.max-body-bytes: the largest card body, in UTF-8 bytes;services.kanban.max-comment-bytes: the largest comment, in UTF-8 bytes.
services.kanban.wip-default is the WIP limit a new column starts with, within
the platform's lowest and highest WIP limits, services.kanban.wip-min and
services.kanban.wip-max. A WIP limit of 0 means no limit.
The platform's own:
services.kanban.undo-window-ms: how long a deleted card or a removed column can still be restored;services.kanban.retention-deleted-days: how long a deleted card or removed column is kept before it is purged;services.kanban.retention-idempotency-hours: how long a create'sidempotencyKeyis kept, and so how long a repeat with it answers the first result;services.kanban.retention-activity-days: how long a board's activity is kept;services.kanban.trial-days: the days of free use a trial grants;services.kanban.active-user-period-days: the trailing window within which a person or agent who used the service counts as an active user;services.kanban.included-users: the active users the monthly fee covers.
Its limits
Each count and size refuses at its limit. A write that would take a board, a card or the organization past one of the limits above is refused, names the limit it would pass, and changes nothing; nothing already stored is lost. Lowering a limit deletes nothing either: it only refuses the next write past it. There is no warning level before a limit: a write either fits or is refused. The values are settings and can change, so they are not written here.
A WIP limit is a column's own. A card create, move, copy or restore, or a bulk move of a column's cards, that would put more cards in a column than its WIP limit is refused whole. The board in the browser shows each limited column's count against its limit.
One call is bounded. How many boards or cards one create makes, how many checklist operations or links one call applies, how many edits one body edit applies and how many replacements it makes, and how much one body read or search page returns are fixed bounds, each stated in its tool's description.
A body search is literal text, matched within one line and ignoring case, so it cannot contain a line break.
Bodies and comments are markdown, and a card or comment names another
member with an @handle mention, which is recorded on the card; nothing is
sent to that member.
Names, titles and other short text are one line. A board, column, label or checklist name, a card's title and summary, a checklist item's text, a done sub-status, a blocked reason and a web link's title cannot contain a line break. A description, a body and a comment can.