Tasks
The core resource — tasks, subtasks, dependencies, followers, activity, plus the labels, milestones and sprints that organise them.
Tasks are Krrim's unit of work. A task belongs to exactly one project, carries a type, priority, status and assignee, and can hold subtasks, comments, attachments, custom field values, time entries and dependency links.
Scopes: tasks:read, tasks:write
Addressing a task
A task is identified by its key — krrim-0042 — not a numeric id. The key
is what appears in the UI, in notifications and in links people paste to each
other, and it is stable for the life of the task.
Creating and listing go through the project, since a task cannot exist without one:
GET /api/v1/projects/APOLLO/tasks/
POST /api/v1/projects/APOLLO/tasks/
GET /api/v1/tasks/krrim-0042/Creating a task
curl -X POST https://acme.krrim.com/api/v1/projects/APOLLO/tasks/ \
-H "Authorization: Bearer krm_live_..." \
-H "Idempotency-Key: intake-4417" \
-H "Content-Type: application/json" \
-d '{
"title": "Investigate checkout timeout",
"description": "p95 crossed 3s after the 08-24 deploy.",
"task_type": "bug",
"priority": "high",
"assignee": 14
}'Only title is required. Everything else falls back to the project's defaults —
which is why a project's task types, priorities and statuses are readable
endpoints of their own: an integration should look up what a project actually
offers rather than assuming "bug" exists everywhere.
Attach an Idempotency-Key to every create. A
retried POST without one makes a second task, and there is no way for the
client to tell that from a request that never arrived.
Status changes are workflow moves
Setting status is not a free-form write. Projects define which transitions are
allowed, and a move that is not permitted is refused with INVALID_TRANSITION
and the from/to pair in details.
Read the legal moves from /api/v1/transitions/ before offering a status change
in your own UI, rather than discovering the rules by trial.
Dependencies
POST /api/v1/tasks/krrim-0042/link/
GET /api/v1/tasks/krrim-0042/links/
DELETE /api/v1/tasks/krrim-0042/links/{id}/A link that would close a loop is refused with DEPENDENCY_CYCLE, and
details.path names every task in the cycle so you can report which one
rather than saying "invalid".
Each edge is stored once, in one canonical direction. Asking either task about
its links returns the same relationship described from that task's side — so do
not create the mirror yourself, or you will get DUPLICATE_LINK.
Bulk operations
POST /api/v1/projects/APOLLO/tasks/bulk/
POST /api/v1/projects/APOLLO/tasks/bulk-update/Prefer these over a loop. One bulk call costs one request against your rate limit where a hundred single writes cost a hundred — and the loop will hit the per-token burst limit long before it finishes.
Search
GET /api/v1/search/?q=timeoutFull-text over titles and descriptions, scoped to what the caller can see. Capped at 60 requests/minute independently of your token's own limits.
Syncing
To keep a copy of the backlog up to date, use the changes feed rather than re-listing tasks. It is the only endpoint that reports deletions.
Endpoints
| Method | Path | Scope |
|---|---|---|
GET | /api/v1/changes/tasks/ | tasks:read |
GET | /api/v1/milestones/{id}/ | tasks:read |
PUT | /api/v1/milestones/{id}/ | tasks:write |
DELETE | /api/v1/milestones/{id}/ | tasks:write |
GET | /api/v1/projects/{project_key}/labels/ | tasks:read |
POST | /api/v1/projects/{project_key}/labels/ | tasks:write |
GET | /api/v1/projects/{project_key}/milestones/ | tasks:read |
POST | /api/v1/projects/{project_key}/milestones/ | tasks:write |
GET | /api/v1/projects/{project_key}/priorities/ | tasks:read |
GET | /api/v1/projects/{project_key}/sprints/ | tasks:read |
POST | /api/v1/projects/{project_key}/sprints/ | tasks:write |
GET | /api/v1/projects/{project_key}/task-types/ | tasks:read |
GET | /api/v1/projects/{project_key}/tasks/ | tasks:read |
POST | /api/v1/projects/{project_key}/tasks/ | tasks:write |
POST | /api/v1/projects/{project_key}/tasks/bulk-update/ | tasks:write |
POST | /api/v1/projects/{project_key}/tasks/bulk/ | tasks:write |
GET | /api/v1/search/ | tasks:read |
GET | /api/v1/sprints/{id}/ | tasks:read |
PUT | /api/v1/sprints/{id}/ | tasks:write |
DELETE | /api/v1/sprints/{id}/ | tasks:write |
GET | /api/v1/tasks/{task_key}/ | tasks:read |
PUT | /api/v1/tasks/{task_key}/ | tasks:write |
DELETE | /api/v1/tasks/{task_key}/ | tasks:write |
GET | /api/v1/tasks/{task_key}/activities/ | tasks:read |
POST | /api/v1/tasks/{task_key}/assign/ | tasks:write |
POST | /api/v1/tasks/{task_key}/follow/ | tasks:write |
DELETE | /api/v1/tasks/{task_key}/follow/ | tasks:write |
GET | /api/v1/tasks/{task_key}/followers/ | tasks:read |
POST | /api/v1/tasks/{task_key}/link/ | tasks:write |
GET | /api/v1/tasks/{task_key}/links/ | tasks:read |
DELETE | /api/v1/tasks/{task_key}/links/{id}/ | tasks:write |
GET | /api/v1/tasks/{task_key}/subtasks/ | tasks:read |
POST | /api/v1/tasks/{task_key}/subtasks/ | tasks:write |