Krokanti Tasks API
Automate your task management workflow with personal API tokens and a simple REST API.
https://tasks.krokanti.com/api100 req/min per tokenPro or Team plan required
API access is available on Pro and Team plans. Generate tokens in Settings → API Tokens.
Upgrade your plan →Authentication
All API requests must include an Authorization header with a personal API token. Generate tokens in Settings → API Tokens. Tokens start with kt_ and are shown once on creation.
curl https://tasks.krokanti.com/api/spaces
-H "Authorization: Bearer kt_your_token_here"
-H "Content-Type: application/json"Spaces
/api/spacesList all spaces the authenticated user belongs to.
- →Returns an array of space objects.
/api/spacesCreate a new team space.
| Parameter | Type | Description |
|---|---|---|
namerequired | string | Space display name. |
slugrequired | string | Unique URL-friendly identifier (3-50 chars, a-z 0-9 -). |
description | string | Optional description. |
color | string | Hex color for the space icon. |
- →The authenticated user becomes the space owner.
- →A default General project is created automatically.
Projects
/api/projectsList all projects in a space.
| Parameter | Type | Description |
|---|---|---|
spaceIdrequired | string (UUID) | The space ID. |
/api/projectsCreate a new project.
| Parameter | Type | Description |
|---|---|---|
spaceIdrequired | string (UUID) | The space to create the project in. |
namerequired | string | Project display name. |
slugrequired | string | URL-friendly identifier, unique within the space. |
description | string | Optional description. |
defaultView | kanban | list | calendar | gantt | Default view mode. |
color | string | Hex color. |
- →Requires Owner, Admin, or Member role.
- →Default statuses are created automatically.
/api/projects/:idUpdate project settings.
| Parameter | Type | Description |
|---|---|---|
idrequired | string (UUID) | Project ID. |
name | string | New display name. |
slug | string | New slug (must be unique within space). |
description | string | null | Project description. |
defaultView | kanban | list | calendar | gantt | Default view. |
- →Requires Owner or Admin role.
/api/projects/:idArchive a project. Requires Owner or Admin role.
| Parameter | Type | Description |
|---|---|---|
idrequired | string (UUID) | Project ID. |
Tasks
/api/tasksList tasks in a project.
| Parameter | Type | Description |
|---|---|---|
projectIdrequired | string (UUID) | The project ID. |
archived | boolean | true to list archived tasks. |
updatedSince | string (ISO 8601) | Only tasks changed at or after this timestamp, ordered by updatedAt. Use this for incremental syncs instead of re-reading the board. |
includeArchived | boolean | With updatedSince: include archived tasks (so you can see what left the board). |
includeSubtasks | boolean | With updatedSince: include subtasks. |
/api/tasksCreate a new task.
| Parameter | Type | Description |
|---|---|---|
projectIdrequired | string (UUID) | Project to create the task in. |
titlerequired | string | Task title. |
statusId | string (UUID) | null | Status column for the task. |
priority | none | low | medium | high | urgent | Task priority. |
dueDate | string (ISO 8601) | Due date. |
parentTaskId | string (UUID) | null | Parent task for subtasks. |
- →Requires at least Member role.
- →Position is assigned automatically.
/api/tasks/:idUpdate a task.
| Parameter | Type | Description |
|---|---|---|
idrequired | string (UUID) | Task ID. |
title | string | New title. |
statusId | string (UUID) | null | Move to a different status column. |
priority | none | low | medium | high | urgent | Priority. |
dueDate | string (ISO 8601) | null | Due date. |
completedAt | string (ISO 8601) | null | Mark done (ISO date) or reopen (null). |
isArchived | boolean | Archive or restore the task. |
estimatedHours | number | null | Time estimate in hours. |
- →Requires at least Member role.
- →Setting completedAt marks the task done.
/api/tasks/:idPermanently delete a task.
| Parameter | Type | Description |
|---|---|---|
idrequired | string (UUID) | Task ID. |
/api/tasks/:id/assigneesAssign a space member to the task. The assignee is notified (in-app + email) exactly as if a human had assigned them.
| Parameter | Type | Description |
|---|---|---|
userIdrequired | string (UUID) | Member to assign. Get it from GET /api/spaces/:id/members. |
/api/tasks/:id/assignees/:userIdRemove an assignee. Idempotent — removing someone who isn't assigned succeeds.
| Parameter | Type | Description |
|---|---|---|
userIdrequired | string (UUID) | Assignee to remove. |
/api/tasks/:id/labelsAttach a label to the task. Labels are project-scoped.
| Parameter | Type | Description |
|---|---|---|
labelIdrequired | string (UUID) | Label from GET /api/projects/:id/labels. |
/api/tasks/:id/labels/:labelIdDetach a label from the task.
/api/tasks/:id/commentsList the task's comments, newest last. Supports limit and offset.
/api/tasks/:id/commentsPost a comment. Assignees and @-mentioned members are notified.
| Parameter | Type | Description |
|---|---|---|
contentrequired | string | Comment body (HTML; plain text is wrapped). |
/api/tasks/:id/activityTask history — status changes, assignments, edits. Retention depends on the space plan (7 days Free, 90 days Pro, unlimited Team+).
/api/spaces/:id/membersList space members with userId, name, email and role — the userId the assignee endpoints expect.
Webhooks
Suscribe un endpoint HTTPS a los eventos de tareas y Krokanti Tasks te envía los cambios en el momento en que ocurren. Es la forma soportada de mantener sincronizado un sistema externo (GitHub Issues, Linear, un bot de Slack, tu propia base de datos).
Eventos
| Evento | Se dispara cuando |
|---|---|
task.created | Se crea una tarea. |
task.updated | Cambia cualquier campo. Reordenar dentro de una columna no dispara evento. |
task.moved | La tarea cambia de columna de estado, o se mueve a otro proyecto. |
task.assigned | Se asigna a alguien. data.assignee contiene el usuario. |
task.unassigned | Se retira un asignado. data.assignee contiene el usuario. |
task.completed | La tarea se marca como hecha. |
task.reopened | Se reabre una tarea completada. |
task.archived | Se archiva la tarea (se oculta del tablero, sigue siendo recuperable). |
task.unarchived | Se restaura una tarea archivada. |
task.deleted | La tarea se borra permanentemente. El payload lleva la instantánea previa al borrado. |
task.commented | Se publica un comentario. data.comment lo contiene. |
Un envío por cambio: cada webhook recibe el evento más específico al que se ha suscrito. Un webhook que solo conoce task.updated sigue recibiendo un envío cuando una tarea se mueve, se asigna o se archiva — las integraciones antiguas siguen funcionando igual.
Payload
Los envíos son POST con cuerpo JSON. El objeto task viene siempre completo (estado, asignados, etiquetas, fechas), así que rara vez necesitarás una lectura adicional.
{
"id": "b1e1c0de-...", // delivery id — de-duplicate on this
"event": "task.moved",
"timestamp": "2026-07-27T09:14:22.104Z",
"data": {
"task": {
"id": "6f0c...", "title": "Ship the webhook docs",
"description": "<p>...</p>",
"priority": "high",
"statusId": "2a91...",
"status": { "id": "2a91...", "name": "In progress", "type": "in_progress" },
"dueDate": "2026-07-30T00:00:00.000Z",
"startDate": null,
"completedAt": null,
"isArchived": false,
"parentTaskId": null,
"createdAt": "2026-07-20T08:00:00.000Z",
"updatedAt": "2026-07-27T09:14:22.041Z",
"assignees": [{ "id": "9c2f...", "name": "Edgar" }],
"labels": [{ "id": "77aa...", "name": "docs", "color": "#c07f3a" }],
"url": "https://tasks.krokanti.com/en/app/my-space/my-project?taskId=6f0c..."
},
"project": { "id": "4d5e...", "name": "My project", "slug": "my-project" },
"space": { "id": "1a2b...", "slug": "my-space" },
"actor": { "id": "9c2f...", "name": "Edgar" },
"comment": null,
"assignee": null,
"changes": { "statusId": { "from": "1f00...", "to": "2a91..." } }
}
}Cabeceras
Todo envío de plataforma personalizada incluye estas cabeceras. Usa X-Krokanti-Delivery para deduplicar reintentos.
X-Krokanti-Event: task.moved
X-Krokanti-Delivery: b1e1c0de-... # unique per delivery
X-Krokanti-Timestamp: 2026-07-27T09:14:22.104Z
X-Krokanti-Signature: 3f8a... # HMAC-SHA256 hex of the raw body
X-Krokanti-Signature-256: sha256=3f8a... # same value, GitHub-style prefix
User-Agent: Krokanti-Tasks-Webhook/1Verificar la firma
La firma es un HMAC-SHA256 del cuerpo crudo exacto de la petición, con el secreto del webhook como clave. Compárala en tiempo constante y sobre el cuerpo crudo — si parseas y vuelves a serializar no coincidirá.
import crypto from "crypto";
export async function POST(req: Request) {
const raw = await req.text(); // raw body, before JSON.parse
const sent = req.headers.get("x-krokanti-signature") ?? "";
const expected = crypto
.createHmac("sha256", process.env.KROKANTI_WEBHOOK_SECRET!)
.update(raw)
.digest("hex");
const a = Buffer.from(sent), b = Buffer.from(expected);
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
return new Response("invalid signature", { status: 401 });
}
const payload = JSON.parse(raw);
// ... handle payload.event, de-duplicate on payload.id
return new Response("ok"); // respond 2xx fast; queue slow work
}Semántica de entrega
Cada envío caduca a los 4 s y se reintenta una vez ante timeout, error de red, 5xx o 429. Un 4xx se considera rechazo permanente y no se reintenta. Tras 10 fallos consecutivos el webhook se desactiva automáticamente — reactívalo desde los ajustes del espacio cuando tu endpoint esté sano.
Gestionar webhooks
/api/spaces/:id/webhooksLista los webhooks de un espacio, con su secreto, eventos suscritos y estado del último envío. Solo owner/admin.
/api/spaces/:id/webhooksCrea un webhook. Devuelve el secreto de firma. Requiere plan Pro o Team (5 webhooks en Pro, 10 en Team+).
| Parameter | Type | Description |
|---|---|---|
namerequired | string | Label for this integration. |
urlrequired | string (HTTPS) | Endpoint that receives the POSTs. |
eventsrequired | string[] | Events to subscribe to (see the table above). |
platform | custom | slack | discord | custom (default) sends the JSON payload; slack/discord send formatted messages and require Team+. |
/api/spaces/:id/webhooks/:webhookIdActualiza nombre, URL o eventos de un webhook, o actívalo/desactívalo.
| Parameter | Type | Description |
|---|---|---|
name | string | New label. |
url | string (HTTPS) | New endpoint. |
events | string[] | Replace the subscribed events. |
isActive | boolean | Enable or disable. Enabling resets the failure counter. |
/api/spaces/:id/webhooks/:webhookIdElimina una suscripción de webhook.
/api/spaces/:id/webhooks/:webhookId/testEnvía un payload de prueba al endpoint — mismas cabeceras y firma que uno real. Úsalo para validar tu código de verificación.
Error codes
Error responses include an error field and optionally a code field.
| Status | Meaning | Common cause |
|---|---|---|
400 | Bad Request | Missing or invalid fields. |
401 | Unauthorized | Missing or invalid API token. |
402 | Payment Required | API access requires Pro or Team. |
403 | Forbidden | Insufficient role. |
404 | Not Found | Resource does not exist. |
409 | Conflict | Slug already taken. |
429 | Too Many Requests | Exceeded 100 req/min per token. |
// Error response body
{ "error": "Unauthorized" }
// With machine-readable subcode
{ "error": "API access requires a Pro or Team plan", "code": "pro_required" }Rate limits
API token requests are limited to 100 requests per minute per token.
When you exceed the limit you receive 429 Too Many Requests. The response includes a Retry-After header with seconds to wait.
HTTP/1.1 429 Too Many Requests
Retry-After: 42
Content-Type: application/json
{ "error": "Rate limit exceeded" }Code examples
Replace kt_your_token_here with your actual token.
cURL
# List your spaces
curl "https://tasks.krokanti.com/api/spaces"
-H "Authorization: Bearer kt_your_token_here"
# List projects in a space
curl "https://tasks.krokanti.com/api/projects?spaceId=SPACE_ID"
-H "Authorization: Bearer kt_your_token_here"
# List tasks in a project
curl "https://tasks.krokanti.com/api/tasks?projectId=PROJECT_ID"
-H "Authorization: Bearer kt_your_token_here"
# Create a task
curl -X POST "https://tasks.krokanti.com/api/tasks"
-H "Authorization: Bearer kt_your_token_here"
-H "Content-Type: application/json"
-d '{ "projectId": "PROJECT_ID", "title": "My new task", "priority": "high" }'
# Complete a task
curl -X PATCH "https://tasks.krokanti.com/api/tasks/TASK_ID"
-H "Authorization: Bearer kt_your_token_here"
-H "Content-Type: application/json"
-d '{ "completedAt": "2026-02-22T10:00:00.000Z" }'JavaScript / Node
const BASE = "https://tasks.krokanti.com/api";
const TOKEN = "kt_your_token_here";
const headers = {
Authorization: `Bearer ${TOKEN}`,
"Content-Type": "application/json",
};
// List spaces
const spaces = await fetch(`${BASE}/spaces`, { headers }).then(r => r.json());
// List projects in first space
const projects = await fetch(
`${BASE}/projects?spaceId=${spaces[0].id}`,
{ headers }
).then(r => r.json());
// Create a task
const { task } = await fetch(`${BASE}/tasks`, {
method: "POST",
headers,
body: JSON.stringify({
projectId: projects[0].id,
title: "Review pull request",
priority: "high",
dueDate: new Date(Date.now() + 86400000).toISOString(),
}),
}).then(r => r.json());
// Mark it done
await fetch(`${BASE}/tasks/${task.id}`, {
method: "PATCH",
headers,
body: JSON.stringify({ completedAt: new Date().toISOString() }),
});Python
import requests
from datetime import datetime, timedelta, timezone
BASE = "https://tasks.krokanti.com/api"
TOKEN = "kt_your_token_here"
HEADERS = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}
# List spaces
spaces = requests.get(f"{BASE}/spaces", headers=HEADERS).json()
# List projects
projects = requests.get(
f"{BASE}/projects", headers=HEADERS,
params={"spaceId": spaces[0]["id"]}
).json()
# Create a task
tomorrow = (datetime.now(timezone.utc) + timedelta(days=1)).isoformat()
resp = requests.post(f"{BASE}/tasks", headers=HEADERS, json={
"projectId": projects[0]["id"],
"title": "Deploy new release",
"priority": "urgent",
"dueDate": tomorrow,
})
task = resp.json()["task"]
print(f"Created task: {task['id']}")
# Complete the task
requests.patch(f"{BASE}/tasks/{task['id']}", headers=HEADERS, json={
"completedAt": datetime.now(timezone.utc).isoformat()
})MCP — AI Integration
Krokanti Tasks ships with a built-in MCP (Model Context Protocol) server. Connect Claude Code, Claude Desktop, or Cursor to your tasks and let AI create, update, and query tasks on your behalf — using the same API token.
Claude Code
Create a .mcp.json file in the root of your project (or add to an existing one):
// .mcp.json (project root)
{
"mcpServers": {
"krokanti-tasks": {
"type": "http",
"url": "https://tasks.krokanti.com/api/mcp",
"headers": {
"Authorization": "Bearer kt_your_token_here"
}
}
}
}Claude Code also needs the server enabled. Create .claude/settings.local.json in the same directory:
// .claude/settings.local.json
{
"enableAllProjectMcpServers": true,
"enabledMcpjsonServers": ["krokanti-tasks"]
}Claude Desktop
Add to your Claude Desktop configuration file. On macOS the file is at ~/Library/Application Support/Claude/claude_desktop_config.json. On Windows: %APPDATA%Claudeclaude_desktop_config.json.
// claude_desktop_config.json
{
"mcpServers": {
"krokanti-tasks": {
"command": "npx",
"args": [
"mcp-remote@latest",
"https://tasks.krokanti.com/api/mcp",
"--header",
"Authorization: Bearer kt_your_token_here"
]
}
}
}Cursor
Add to .cursor/mcp.json in your project root (project-level) or ~/.cursor/mcp.json for global access:
// .cursor/mcp.json (or ~/.cursor/mcp.json for global)
{
"mcpServers": {
"krokanti-tasks": {
"type": "http",
"url": "https://tasks.krokanti.com/api/mcp",
"headers": {
"Authorization": "Bearer kt_your_token_here"
}
}
}
}Available tools
| Tool | Description | Key inputs |
|---|---|---|
list_spaces | List all spaces the user belongs to | — |
list_projects | List projects in a space | spaceId |
list_statuses | List status columns in a project | projectId |
list_tasks | List tasks; updatedSince for incremental syncs | projectId, updatedSince?, includeArchived?, includeSubtasks?, limit? |
get_task | Full detail: assignees, labels, subtasks, comments | taskId |
create_task | Create a new task | projectId, title, description?, statusId?, priority?, dueDate?, parentTaskId? |
update_task | Update title, description, status, priority, due date, hours | taskId + fields to change |
complete_task | Mark done or reopen a task | taskId, reopen? |
archive_task | Archive a task or restore it (reversible) | taskId, archived? |
delete_task | Delete a task permanently (irreversible) | taskId |
add_comment | Add a comment to a task | taskId, content |
list_members | Space members with their userId and role | spaceId |
assign_task | Assign a space member to a task | taskId, userId |
unassign_task | Remove an assignee from a task | taskId, userId |
list_labels | List a project's labels | projectId |
set_task_labels | Attach and/or detach labels on a task | taskId, add?, remove? |
list_webhooks | List a space's webhook subscriptions | spaceId |
create_webhook | Subscribe an endpoint to task events | spaceId, name, url, events |
delete_webhook | Remove a webhook subscription | spaceId, webhookId |
All write operations (create, update, complete, add_comment, assign) require at least Member role in the space. Viewer role is read-only.
Built-in prompts
| Prompt | Description | Inputs |
|---|---|---|
plan_sprint | Review a project and suggest a prioritized sprint plan | projectId, goal? |
daily_standup | Generate a done/in-progress/next/blockers report | projectId, userName? |
Prompts guide the AI to use multiple tools together for common workflows.