API and MCP
Connect Kanbanana to your automations or AI assistants.
Authentication
API base URL: https://kanbanana.app (all REST endpoints use the prefix https://kanbanana.app/api/public/v1).
The REST API requires an API key in the Authorization: Bearer <key> header. Create keys in account settings (Pro or Team plan required).
curl -H "Authorization: Bearer fb_xxxxxxxxxxxxxxxxxxxx" \
https://kanbanana.app/api/public/v1/boardsMachine-readable specifications
The REST specification comes from the same operation definitions used by this page. MCP tool schemas come from the live server manifest, so names, types and null handling match the /mcp endpoint. Import them into Postman, Swagger UI, a client generator or an AI assistant.
- REST (OpenAPI 3.1): /api/public/v1/openapiJSONYAML
- MCP tools (JSON Schema): /api/public/v1/mcp-toolsJSONYAML
curl https://kanbanana.app/api/public/v1/openapi | jq .pathsREST API endpoints
/api/public/v1/boardsscope: readReturns non-archived boards accessible to the API key owner.
No parameters.
Example response
{
"boards": [
{
"id": "uuid",
"name": "Roadmap",
"description": null,
"accent": "cyan",
"icon": "rocket",
"template": "kanban",
"created_at": "2026-08-01T09:00:00Z",
"updated_at": "2026-08-20T12:30:00Z"
}
]
}/api/public/v1/boards/{boardId}scope: readReturns a board with its columns, cards, labels and card-label associations.
| Parameter | Location | Type | Required | Description |
|---|---|---|---|---|
| boardId | path | uuid | yes | Board identifier. |
Example response
{
"board": { "id": "uuid", "name": "Roadmap" },
"columns": [{ "id": "uuid", "name": "To do", "position": 1000, "wip_limit": null, "is_done_column": false }],
"cards": [{ "id": "uuid", "column_id": "uuid", "title": "Task", "priority": "medium", "due_at": null }],
"labels": [{ "id": "uuid", "name": "Bug", "color": "red" }],
"cardLabels": [{ "card_id": "uuid", "label_id": "uuid" }]
}/api/public/v1/boards/{boardId}/cardsscope: writeAdds a card to the end of the specified column on this board.
| Parameter | Location | Type | Required | Description |
|---|---|---|---|---|
| boardId | path | uuid | yes | Board identifier. |
| title | body | string | yes | Card title (1–200 characters). |
| columnId | body | uuid | yes | Target column; it must belong to this board. |
| description | body | string | no | Card description (maximum 5,000 characters). |
| priority | body | none | low | medium | high | urgent | no | Card priority. |
| dueAt | body | date-time | null | no | Due date in ISO 8601 format (UTC). |
| estimatePomodoros | body | integer | no | Estimated number of Pomodoro sessions (>= 0). |
Example response
{ "card": { "id": "uuid", "title": "New card", "column_id": "uuid", "position": 3000 } }/api/public/v1/cards/{cardId}scope: writeUpdates selected card fields. Provide at least one field in the request body.
| Parameter | Location | Type | Required | Description |
|---|---|---|---|---|
| cardId | path | uuid | yes | Card identifier. |
| title | body | string | no | New title (1–200 characters). |
| columnId | body | uuid | no | Move the card to another column. |
| description | body | string | null | no | Card description; null clears the field. |
| priority | body | none | low | medium | high | urgent | no | Card priority. |
| dueAt | body | date-time | null | no | Due date in ISO 8601 format; null removes it. |
| estimatePomodoros | body | integer | null | no | Estimated number of Pomodoro sessions. |
| completedAt | body | date-time | null | no | Completion date in ISO 8601 format; null marks the card as incomplete. |
Example response
{ "card": { "id": "uuid", "title": "Updated title", "priority": "high" } }/api/public/v1/cards/{cardId}scope: writePermanently deletes a card.
| Parameter | Location | Type | Required | Description |
|---|---|---|---|---|
| cardId | path | uuid | yes | Card identifier. |
Example response
{ "deleted": true }MCP server
Kanbanana provides an MCP server that lets AI assistants (such as Claude, ChatGPT and Cursor) read boards and manage cards through OAuth. MCP endpoint: https://kanbanana.app/mcp (server kanbanana, version 0.2.1).
How to connect: in a web app (Claude or ChatGPT), add a custom connector using the URL above. Authentication uses OAuth 2.1 with dynamic client registration, so you do not need a client ID or API key. After signing in, grant consent. Tools then act on your behalf with the same permissions as your account in Kanbanana.
In clients with a configuration file (Cursor or Claude Desktop), use the same URL:
{
"mcpServers": {
"kanbanana": {
"url": "https://kanbanana.app/mcp"
}
}
}The tool descriptions and schemas below come directly from the live MCP server definitions. Pass parameters in the arguments field of a tools/call request; MCP does not use an HTTP request body.
list_boardsread-onlyList all Kanban boards the user has access to.
No arguments.
get_boardread-onlyGet a single Kanban board with its columns, cards, and labels.
| Argument | Type | Required | Constraints | Description |
|---|---|---|---|---|
| boardId | string (uuid) | yes | — | The board ID (UUID). |
create_cardwriteCreate a new card on a Kanban board column.
| Argument | Type | Required | Constraints | Description |
|---|---|---|---|---|
| boardId | string (uuid) | yes | — | The board ID (UUID). |
| columnId | string (uuid) | yes | — | The column ID (UUID) to place the card in. |
| title | string | yes | 1–200 znaków | Card title. |
| description | string | null | no | 0–5000 znaków | Optional card description (null clears it). |
| priority | none | low | medium | high | urgent | no | — | Optional priority. |
| dueAt | string (date-time) | null | no | — | Optional ISO 8601 due date/time (null for none). |
| estimatePomodoros | integer | null | no | zakres 0–100 | Estimated number of Pomodoro sessions. |
update_cardwriteUpdate a card's title, description, priority, due date, or column.
| Argument | Type | Required | Constraints | Description |
|---|---|---|---|---|
| cardId | string (uuid) | yes | — | The card ID (UUID). |
| title | string | no | 1–200 znaków | New card title. |
| columnId | string (uuid) | no | — | New column ID. |
| description | string | null | no | 0–5000 znaków | New description; null clears it. |
| priority | none | low | medium | high | urgent | no | — | New priority. |
| dueAt | string (date-time) | null | no | — | New ISO 8601 due date/time; null removes the due date. |
| estimatePomodoros | integer | null | no | zakres 0–100 | Estimated number of Pomodoro sessions; null clears it. |
| completedAt | string (date-time) | null | no | — | Completion timestamp (ISO 8601); null marks the card as not completed. |
delete_cardwritedestructiveDelete a card by ID.
| Argument | Type | Required | Constraints | Description |
|---|---|---|---|---|
| cardId | string (uuid) | yes | — | The card ID (UUID) to delete. |
Fields in MCP responses
Results are returned in structuredContent.result. list_boards returns boards[] with fields id, name, description, accent, icon, template, created_at, updated_at. get_board returns board (without created_at), columns (id, name, color, position, wip_limit, is_done_column), cards, labels and cardLabels.
| Card field | Meaning |
|---|---|
| id / column_id | IDs of the card and the column containing it. |
| title / description | Card title and description (description may be null). |
| priority | none | low | medium | high | urgent. |
| due_at | Due date in ISO 8601 (UTC), or null. |
| all_day | true means an all-day deadline; the time in due_at is ignored. |
| assignee_id | User assigned to the card (UUID), or null. Set in the application. |
| estimate_pomodoros | Estimated Pomodoro sessions (read and write with create_card/update_card). |
| completed_at | Completion date, or null for an incomplete card. |
| position | Order within the column (ascending). |
| created_by | Card creator (UUID). |
| created_at / updated_at | Creation and update timestamps. |
Rate limits
- REST API: 1,000 requests per hour per API key.
- Write operations (POST/PATCH/DELETE): an additional 60 requests per minute per key.
- Requests without a valid key: 60 per hour per IP address.
- MCP endpoint
/mcp: 600 requests per hour per token (or per IP when no token is provided).
Every REST response includes X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers. When the limit is exceeded, the API returns 429 with Retry-After in seconds.
Error codes and retries
REST API errors use a consistent JSON format. The retryable field tells you whether to retry the request with exponential backoff.
{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded. Try again later.",
"retryable": true,
"retryAfter": 42
}
}| Status | code | Retry? |
|---|---|---|
| 400 | invalid_request / invalid_json | No — fix the request |
| 401 | unauthorized | No — check the API key |
| 402 | usage_limit_reached | No — check your plan and limits |
| 403 | forbidden | No — insufficient permissions or scope |
| 404 | not_found | No |
| 429 | rate_limited | Yes — after Retry-After |
| 500 | internal_error | Yes — backoff, e.g. 5s, 10s, 20s |
The MCP endpoint returns transport errors in JSON-RPC format: -32029 for rate limits and -32603 for server errors. Both include retryable and retryAfter in data. Domain errors (such as an unknown ID) return as tool results with isError: true and a structured code:
{
"isError": true,
"structuredContent": {
"result": {
"error": { "code": "not_found", "message": "No board found for the given boardId.", "retryable": false }
}
}
}not_found— unknown or inaccessibleboardId,cardIdorcolumnId(equivalent to REST404). Do not retry.unauthenticated— missing or invalid OAuth token. Reconnect the connector.forbidden— insufficient board or card permissions. Do not retry.invalid_request— invalid input. Do not retry.internal_error— server error;retryable: true. Retry with backoff.
Example: create a card
curl -X POST \
-H "Authorization: Bearer fb_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"columnId":"column-uuid","title":"New card","priority":"high"}' \
https://kanbanana.app/api/public/v1/boards/board-uuid/cards