---
title: "Set board mode (draw / todo)"
method: POST
path: "/api/boards/{boardId}/mode"
tags: ["Kanban"]
---

# Set board mode (draw / todo)

`POST /api/boards/{boardId}/mode`

## Request

- Base URL: `https://cnvs.app`
- URL: `https://cnvs.app/api/boards/{boardId}/mode`
- Auth: none declared

Mirrors the MCP `set_board_mode` tool. A board is either `draw` (the default infinite-canvas whiteboard) or `todo` (a kanban task board with columns and cards). **The mode is switchable WHENEVER the board is empty of real content** — drawings (text/strokes/images) and tasks. Empty or seeded columns DON'T count (switching to `draw` clears them), so a board that once held content but is now cleared becomes switchable again, and you can flip `draw` ↔ `todo` freely until the first stroke/text/image or task lands. Calling this on a board that still holds real content returns `400 { code: "board_not_empty" }`. Switching an empty board to `todo` seeds the starter columns; pass an optional `template` (`kanban` — the default — / `sprint` / `bugs`) to choose the column set, returned in the `columns` array.

## Request body

- object
  - `mode` 'draw' | 'todo', required: `draw` = infinite-canvas whiteboard (default). `todo` = kanban task board.
  - `template` 'kanban' | 'sprint' | 'bugs': Starter column set when switching to `todo`. Defaults to `kanban`. Ignored for `draw`.

## Response `200`

Mode set.

- object
  - `ok` boolean, required
  - `mode` 'draw' | 'todo', required
  - `columns` Column[]
    - `id` string, required
    - `title` string, required
    - `sort` number: Left-to-right order of the column.
    - `lane` integer: Row index for multi-lane layout. Defaults to 0 (top row).
    - `color` 'red' | 'blue' | 'green' | 'null', nullable: Column title color — one of `red` / `blue` / `green`, or null for the default.
    - `author` string, nullable
    - `last_updated` string: UTC timestamp.

## Other responses

- `400`: Invalid mode, or the board still holds real content (`code: board_not_empty`) so the mode can't change until it's cleared.
- `401`: Board is access-locked and the request did not carry a valid key. `lockMode` tells the client whether to prompt for a code or just disable write UI.
- `404`: Board does not exist or was deleted within the 30-day tombstone window.
- `429`: Rate limit exceeded. Standard REST/MCP: 60 requests/10s/board; valid X-Import-Token infrastructure tier: 600/10s/board; browser WebSocket always 60/10s/board. REST/MCP enforcement is soft per-isolate; WebSocket enforcement is strong per Durable Object.

---

[API](https://skmtc.dev/cnvs/apis/cnvs-app-http-api.md) · [All operations](https://skmtc.dev/cnvs/apis/cnvs-app-http-api/llms.txt) · [OpenAPI document](https://skmtc.dev/cnvs/apis/cnvs-app-http-api/revisions/c8f2c3b7ff90?raw)
