Errors and rate limits

The errors the REST API and the kanman MCP server return, the request limits, and how to retry, including webhook delivery retries.

This page covers what kanman’s programmatic interfaces return when something goes wrong: the REST API and the kanman MCP server. Tool errors of the MCP server are listed in MCP tools. How kanman retries webhook deliveries is described under Delivery rules.

REST API errors

Every error has the same shape:

{ "error": { "code": "not_found", "message": "Run run-7f3k does not exist in this workspace." } }

code is stable and meant for your code; message is meant for people and may change.

Status code When
400 invalid_request A parameter or the body is invalid, for example an unknown filter value, a bad cursor or an option that is not part of the decision.
401 unauthorized The token is missing, unknown, revoked or expired, its workspace was deleted, or its owner left the workspace. The answer carries WWW-Authenticate: Bearer.
403 forbidden The token lacks the permission of the endpoint, or the audit log was requested by a token of a person who is not an owner or admin.
404 not_found The endpoint or the object does not exist in the token’s workspace.
405 method_not_allowed The path exists, but not with this method.
409 conflict The decision was already answered.
410 gone An endpoint of the first API version that was removed (projects and tasks).
429 rate_limited Too many requests. See Rate limits.
500 internal_error Something went wrong on kanman’s side. Try again.

MCP server errors

The MCP server answers in JSON-RPC 2.0. A request it cannot accept gets an error object:

{ "jsonrpc": "2.0", "id": null, "error": { "code": -32600, "message": "Unauthorized" } }

A tool that fails does not return a protocol error. It returns a normal tool result marked isError: true with a readable message, so the coding agent can react to it.

HTTP status codes

Status When
200 The request was handled. Tool errors also come back with 200.
202 A notification was accepted.
400 The body is not valid JSON.
401 The token is missing, unknown, revoked or expired, or the story in the address is not in the token’s workspace. The response carries WWW-Authenticate: Bearer.
405 The method is not POST. The server is stateless and offers no event stream.
413 The request body is larger than 256 KB.
500 Something went wrong on kanman’s side. Try again.

Error codes

Code Message Meaning
-32700 Parse error The body is not valid JSON.
-32600 Unauthorized, Request too large, Invalid JSON-RPC message The request was refused before it was handled. Send one JSON-RPC message per request; batches are not accepted.
-32601 Method not found The JSON-RPC method is not one the server knows.
-32602 Unknown tool tools/call named a tool the server does not have.
-32603 Internal error Something went wrong on kanman’s side.

Rate limits

The REST API allows 120 requests per minute per token. The window starts at the full minute. Every answer carries:

Header Meaning
X-RateLimit-Limit Requests allowed per minute.
X-RateLimit-Remaining Requests left in the current minute.
X-RateLimit-Reset Unix time in seconds when the next minute starts.

Over the limit, the API answers 429 with Retry-After in seconds. kanman does not publish request limits for the MCP server; coding agents call it a few times per story, far below any limit you would notice.

Retrying

  • Retry 500 responses and network errors after a short pause, with growing intervals.
  • After a 429, wait the number of seconds in Retry-After.
  • Do not retry 400, 401, 403, 404, 409 or 410: change the request or the token first.
  • Tool results with isError: true are answers, not failures. Read the message: it tells the agent what to do next, for example “No run is active for this story yet. Call start_work first.”
  • Webhook deliveries are retried by kanman up to four times. See Delivery rules.

Use fewer requests

  • Subscribe to webhooks instead of polling the API for new runs or decisions.
  • Page with a limit of 100 when you read a long history, and stop when nextCursor is null.
  • Call get_story once at the start instead of before every step.
  • Send report_progress when the stage changes, not for every file.

Last updated: January 1, 0001

Open kanman