{"openapi":"3.1.0","info":{"title":"Kanbanana REST API","version":"1.0.0","description":"Kanbanana REST API for reading Kanban boards and creating, updating and deleting cards. Authenticate with an API key (Pro or Team plan)."},"servers":[{"url":"https://kanbanana.app","description":"Production (kanbanana.app)"}],"tags":[{"name":"boards","description":"Kanban boards"},{"name":"cards","description":"Task cards"}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"API key from account settings: Authorization: Bearer fb_..."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}},"security":[{"apiKey":[]}],"paths":{"/api/public/v1/boards":{"get":{"operationId":"listBoards","summary":"List boards","description":"Returns non-archived boards accessible to the API key owner. Required API key scope: read.","tags":["boards"],"security":[{"apiKey":[]}],"parameters":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Request limit for the current window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Window reset time in Unix milliseconds."}},"content":{"application/json":{"example":{"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"}]}}}},"400":{"description":"Invalid request (invalid_request / invalid_json).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid API key (unauthorized).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"402":{"description":"An active Pro or Team plan is required (usage_limit_reached).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"403":{"description":"Insufficient permissions or key scope (forbidden).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"404":{"description":"Resource not found (not_found).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded (rate_limited); see the Retry-After header.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"500":{"description":"Server error (internal_error); retry with backoff.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}}}}},"/api/public/v1/boards/{boardId}":{"get":{"operationId":"getBoard","summary":"Get board details","description":"Returns a board with its columns, cards, labels and card-label associations. Required API key scope: read.","tags":["boards"],"security":[{"apiKey":[]}],"parameters":[{"name":"boardId","in":"path","required":true,"description":"Board identifier.","schema":{"type":"string","format":"uuid","description":"Board identifier."}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Request limit for the current window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Window reset time in Unix milliseconds."}},"content":{"application/json":{"example":{"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"}]}}}},"400":{"description":"Invalid request (invalid_request / invalid_json).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid API key (unauthorized).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"402":{"description":"An active Pro or Team plan is required (usage_limit_reached).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"403":{"description":"Insufficient permissions or key scope (forbidden).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"404":{"description":"Resource not found (not_found).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded (rate_limited); see the Retry-After header.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"500":{"description":"Server error (internal_error); retry with backoff.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}}}}},"/api/public/v1/boards/{boardId}/cards":{"post":{"operationId":"createCard","summary":"Create card","description":"Adds a card to the end of the specified column on this board. Required API key scope: write.","tags":["boards","cards"],"security":[{"apiKey":[]}],"parameters":[{"name":"boardId","in":"path","required":true,"description":"Board identifier.","schema":{"type":"string","format":"uuid","description":"Board identifier."}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Request limit for the current window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Window reset time in Unix milliseconds."}},"content":{"application/json":{"example":{"card":{"id":"uuid","title":"New card","column_id":"uuid","position":3000}}}}},"400":{"description":"Invalid request (invalid_request / invalid_json).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid API key (unauthorized).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"402":{"description":"An active Pro or Team plan is required (usage_limit_reached).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"403":{"description":"Insufficient permissions or key scope (forbidden).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"404":{"description":"Resource not found (not_found).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded (rate_limited); see the Retry-After header.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"500":{"description":"Server error (internal_error); retry with backoff.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","description":"Card title (1–200 characters)."},"columnId":{"type":"string","format":"uuid","description":"Target column; it must belong to this board."},"description":{"type":"string","description":"Card description (maximum 5,000 characters)."},"priority":{"type":"string","enum":["none","low","medium","high","urgent"],"description":"Card priority."},"dueAt":{"type":["string","null"],"format":"date-time","description":"Due date in ISO 8601 format (UTC)."},"estimatePomodoros":{"type":"integer","description":"Estimated number of Pomodoro sessions (>= 0)."}},"required":["title","columnId"],"additionalProperties":false}}}}}},"/api/public/v1/cards/{cardId}":{"patch":{"operationId":"updateCard","summary":"Update card","description":"Updates selected card fields. Provide at least one field in the request body. Required API key scope: write.","tags":["cards"],"security":[{"apiKey":[]}],"parameters":[{"name":"cardId","in":"path","required":true,"description":"Card identifier.","schema":{"type":"string","format":"uuid","description":"Card identifier."}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Request limit for the current window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Window reset time in Unix milliseconds."}},"content":{"application/json":{"example":{"card":{"id":"uuid","title":"Updated title","priority":"high"}}}}},"400":{"description":"Invalid request (invalid_request / invalid_json).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid API key (unauthorized).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"402":{"description":"An active Pro or Team plan is required (usage_limit_reached).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"403":{"description":"Insufficient permissions or key scope (forbidden).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"404":{"description":"Resource not found (not_found).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded (rate_limited); see the Retry-After header.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"500":{"description":"Server error (internal_error); retry with backoff.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","description":"New title (1–200 characters)."},"columnId":{"type":"string","format":"uuid","description":"Move the card to another column."},"description":{"type":["string","null"],"description":"Card description; null clears the field."},"priority":{"type":"string","enum":["none","low","medium","high","urgent"],"description":"Card priority."},"dueAt":{"type":["string","null"],"format":"date-time","description":"Due date in ISO 8601 format; null removes it."},"estimatePomodoros":{"type":["integer","null"],"description":"Estimated number of Pomodoro sessions."},"completedAt":{"type":["string","null"],"format":"date-time","description":"Completion date in ISO 8601 format; null marks the card as incomplete."}},"additionalProperties":false}}}}},"delete":{"operationId":"deleteCard","summary":"Delete card","description":"Permanently deletes a card. Required API key scope: write.","tags":["cards"],"security":[{"apiKey":[]}],"parameters":[{"name":"cardId","in":"path","required":true,"description":"Card identifier.","schema":{"type":"string","format":"uuid","description":"Card identifier."}}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Request limit for the current window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Window reset time in Unix milliseconds."}},"content":{"application/json":{"example":{"deleted":true}}}},"400":{"description":"Invalid request (invalid_request / invalid_json).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid API key (unauthorized).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"402":{"description":"An active Pro or Team plan is required (usage_limit_reached).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"403":{"description":"Insufficient permissions or key scope (forbidden).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"404":{"description":"Resource not found (not_found).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded (rate_limited); see the Retry-After header.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}},"500":{"description":"Server error (internal_error); retry with backoff.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code, such as rate_limited or usage_limit_reached."},"message":{"type":"string"},"retryable":{"type":"boolean","description":"Whether retrying the request may help."},"retryAfter":{"type":"integer","description":"Seconds until retry, when applicable."}},"required":["code","message","retryable"]}},"required":["error"]}}}}}}}}}