Cards
A card is a page. Not a page-like object, not a ticket with a description field — the same kind of document the rest of the platform is made of, appearing on a board.
Everything that follows from that comes for free, because none of it is reimplemented for cards:
- a body you write in, with the full editor;
- comments and mentions;
- version history, and the trash;
- full-text search;
- workspace fields — the same field defined once for the whole company, not a custom field invented per board;
- events and webhooks.
A card's title is its page's title. A card's body is its page's body. Reading a card as Markdown is reading the page as Markdown:
curl "$BASE/api/v1/workspaces/$WS/pages/$CARD?format=markdown" \
-H "Authorization: Bearer $TOKEN"
There is no card-shaped endpoint for that, and there does not need to be.
One card, several boards
A card can be on more than one board, and it is the same card — not a copy, not a link, not a mirror that syncs. Edit its text on one board and the other board's card already says the same thing, because there is only one of it.
What is not shared is where it sits. Each board holds its own column, lane and position for that card. The same piece of work can be "In review" on the team board and "This quarter" on the roadmap board, and neither placement disturbs the other.
That is the mechanism behind the promise: a card belongs to the work, and boards are views onto the work.
Placing a card
A card gets onto a board in one of two ways:
Create a new one. Give it a title, a column, optionally a lane:
curl -X POST "$BASE/api/v1/workspaces/$WS/boards/$BOARD/cards" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "title": "Rewrite the onboarding mail", "columnId": "…", "laneId": "…" }'
Attach a page that already exists. Send pageId instead of title. This is
how a card reaches a second board, and how an ordinary page becomes a card.
Attaching needs edit on the board and edit on the page — you are changing
the page's memberships, which is a change to the page.
Position is given by a neighbour: beforeId or afterId. Leave both out and
the card goes to the end of the column, which is also what makes placing the
first card in an empty column work without a special case.
Moving a card
POST /api/v1/workspaces/{workspaceId}/boards/{boardId}/cards/{pageId}/move
One transactional call, taking the target column, the lane and a neighbour. It changes only this board's placement.
Colliding positions are healed rather than stacked: two clients dropping a card at the same spot at the same moment end up with two distinct positions, not two cards claiming one.
Moving needs edit on the board. See
Permissions — this is deliberate, and it is what lets
a project lead run a board containing work they are not cleared to read.
Taking a card off a board
DELETE /api/v1/workspaces/{workspaceId}/boards/{boardId}/cards/{pageId}
The card leaves the board. The page stays — it is still in the workspace, still searchable, still on any other board it is on.
One refusal is worth knowing: if this board is the page's last home, the
call fails with 409 and the code needs-new-home. Removing the final
membership would leave a page nothing points at — reachable only by search, and
in practice lost. Put it on another board first, or trash the page itself if
that is what you meant.
Say where it goes and there is no refusal to work around:
DELETE …/boards/{boardId}/cards/{pageId}?newHomeBoardId={otherBoardId}
The other board has to be one the card is already on, in the same collection. The card is re-homed there and taken off this board in one step — which is what the "move to another board" button does. Prefer it over parking the page somewhere in between: a card that is briefly homed outside any board is a card that is briefly not a card, and things that read the workspace do notice.
Cards without a column
A card can exist on a board with no column. That happens when a row is added to the board's backing database through the generic row API, which knows nothing about columns.
Those cards come back in their own group in the grouped read. They are not an error state; they are the state of "this exists here and nobody has said where". Move them like any other card.
Columns are not fields
A column is not a select option, and a lane is not one either. They live on the board, in its own configuration, and a card's placement is stored per board rather than as a value on the page.
That distinction is why the same card can be in different columns on two boards
at once — a field value is a property of the page and could only ever have one
value. It also means a board's stages never appear as a column in a database
view, and never collide with a Status field somebody defined for the
workspace.
Naming the project a card is part of
A card body takes a project block: type /project, then either paste the
link or id of a project that exists, or type a name and one is made.
The block draws the project's name and links to it. What is stored on the card is only the link — the name is fetched when the block is drawn — so a card whose project you have no access to (or whose product is not active on this workspace) shows a link without a name. Nothing is broken about that; a colleague may well see it.
Two things this deliberately is not:
- not a search. There is no way to browse the projects that exist from here; you paste the address of one you have open, or you make one. The block is a link between two places, not a window into the other.
- not a copy. The project's tasks are not shown on the card and are not editable from it. That may come; today the block names the work and gets you there.
Both halves have to be active on this workspace for the block to work — making one says so plainly if they are not.
What is missing
- Card covers — no image on the front of a card.
- Filtering and sorting — a board shows every card you may read, in board order.
- Public share links for a board. A card's own page can be shared the ordinary way; the board cannot.
- Comments on the board's body. Comments on cards work.
- Cross-product embedding — no wiki page inside a board, no card inside a wiki page, no search across products. A card can NAME a project kept elsewhere (above), which is a link and not an embed: nothing of the other side's content is shown here.