Full endpoint coverage, auth flows, plan limits, and agent workflow recipes. Drop this into any agent context and get to work.
https://api.ikanban.org/apiapplication/jsonAuthorization: Bearer <accessToken>Authorization: Bearer ik_<key> — preferred for agentswss://api.ikanban.org/ws?boardId=<id>&token=<accessToken>All IDs are UUIDs. All timestamps are ISO 8601 (UTC). Paginated endpoints accept ?page=1&pageSize=10.
{ "email": "agent@example.com", "password": "Str0ng!Pass", "displayName": "My Agent" }
Password requirements: min 8 chars, uppercase, lowercase, digit, special character.
Response 201: { "user": {...}, "accessToken": "<jwt>", "refreshToken": "<jwt>" }
{ "email": "agent@example.com", "password": "Str0ng!Pass" }
Response 200: { "user": {...}, "accessToken": "<jwt>", "refreshToken": "<jwt>" }
Store both tokens. Call refresh on 401.
{ "refreshToken": "<jwt>" }
Response 200: { "accessToken": "<jwt>", "refreshToken": "<jwt>" }
{ "name": "CI Pipeline", "expiresAt": "2027-01-01T00:00:00Z" }
Response 201 includes "key": "ik_<raw>" — shown once only. Store immediately.
{ "title": "Sprint 14", "description": "Optional", "orgId": "<uuid>" }
Free plan: max 3 active org boards, 3 personal boards.
{ "title": "In Progress", "wipLimit": 5, "color": "#3b82f6" }
// reorder
{ "columnIds": ["<uuid>", "<uuid>", "<uuid>"] }
// create
{ "title": "Deploy pipeline", "description": "...", "assigneeId": "<uuid>",
"dueDate": "2026-04-01T00:00:00Z", "priority": "high", "labelIds": ["<uuid>"] }
// move
{ "columnId": "<target_column_uuid>", "position": 0 }
Priority values: "low" | "medium" | "high". labelIds replaces all labels — omit to leave unchanged.
{ "content": "Deployed to staging ✓" }
// create item
{ "title": "Write unit tests", "position": 0 }
// update item
{ "title": "Write unit tests", "isCompleted": true }
{ "name": "Bug", "color": "#ef4444" }
{ "title": "Frontend", "color": "#6366f1", "position": 0 }
Trigger types: card_moved | due_date_passed | card_assigned | checklist_completed
Action types: move_card | assign_member | add_label | post_comment
{ "triggerType": "card_moved", "targetValue": "<column_id>",
"actionType": "add_label", "targetColumnId": "<column_id>" }
Invite by email — user must already have an account. Plan limits: free=5 members, pro=25, team=unlimited.
{ "emailOnDueDate": true, "emailOnComplete": false }
Live JSON events for a board:
{ "type": "card-moved", "payload": { "cardId": "...", "columnId": "...", "position": 0 } }
{ "type": "card-created", "payload": { "card": { ... } } }
{ "type": "card-updated", "payload": { "card": { ... } } }
{ "type": "card-deleted", "payload": { "cardId": "..." } }
{ "type": "column-created","payload": { "column": { ... } } }
{ "type": "comment-added", "payload": { "comment": { ... } } }
| Feature | Starter (Free) | Pro ($9/mo) | Team ($29/mo) |
|---|---|---|---|
| Boards per org | 3 | Unlimited | Unlimited |
| Personal boards | 3 | 3 | 3 |
| Org members | 5 | 25 | Unlimited |
| Automation rules | ✗ | ✓ | ✓ |
| Swimlanes | ✗ | ✓ | ✓ |
| API key management | ✗ | ✓ | ✓ |
Limit exceeded returns 402 Payment Required: { "error": "...", "limit": N, "plan": "free" }
| Status | Meaning |
|---|---|
400 | Validation error / bad request |
401 | Token invalid or expired — call /auth/refresh |
402 | Plan limit exceeded — upgrade required |
403 | Forbidden — insufficient role/permissions |
404 | Resource not found |
409 | Conflict (e.g. duplicate member) |
429 | Rate limited — back off and retry |
500 | Internal server error |
All errors: { "error": "descriptive message" }
POST /auth/login → save accessToken
POST /boards → { "title": "Project X" }
POST /columns/board/<id> → { "title": "Backlog" }
POST /columns/board/<id> → { "title": "In Progress" }
POST /columns/board/<id> → { "title": "Review" }
POST /columns/board/<id> → { "title": "Done" }
POST /cards/column/<backlog_id> → { "title": "Task 1", "priority": "high" }
WSS /ws?boardId=<id>&token=<t> → listen for events
// On card-moved event to Done column:
PUT /cards/<id> → update metadata
POST /cards/<id>/comments → { "content": "Verified by agent ✓" }
GET /boards/<id> → full board state // Parse columns → group cards // Filter: dueDate < now+24h AND not in Done column // Report overdue / at-risk cards
// Any request → 401
POST /auth/refresh { "refreshToken": "<rt>" }
// Save new tokens, retry original request
POST /apikeys { "name": "My Agent" } → save raw key ik_... (shown once)
// All future requests:
Authorization: Bearer ik_<raw-key> → never expires until revoked