Appearance
Epic Tools
Six tools for managing epics: create, update, get (with progress data), delete, and tick or untick a Done when wish.
Permission Model
- Getting epics: requires Epics: Read permission
- Creating epics: requires Epics: Create permission
- Updating epics: requires Epics: Update permission (Own/All scope)
- Ticking and unticking wishes: requires Epics: Update permission (Own/All scope)
- Deleting epics: requires Epics: Delete permission (Own/All scope)
- Project owners and admins bypass all permission checks
Enums
Colors
| Value | Color |
|---|---|
0 | Grey |
1 | Green |
2 | Blue |
3 | Red |
4 | Purple |
5 | Yellow |
6 | Orange |
7 | Teal |
8 | Pink |
9 | Indigo |
Every tool and resource that returns an epic sends color and color_name beside it, e.g. "color": 9, "color_name": "Indigo".
Status
Epic status is derived — it isn't stored on the epic. When the epic has Done when wishes, they decide: the epic is Closed when every wish is ticked, even with issues still open, and Open while one wish is open, even when every issue is done. Without wishes, the issues decide: an epic with no issues, or any issue not in the project's last lane, is Open, and an epic with at least one issue and every issue in the last lane is Closed. The last lane is the highest order, tie-broken by highest id.
| Value | Status |
|---|---|
0 | Open |
1 | Closed |
Goal
An epic can carry a Goal: what the epic delivers, in one or two sentences of at most 500 characters. It is the first thing a reader of the epic sees. An epic created before the Goal existed has none, and returns goal: null.
create-epic and update-epic take it as goal; an empty or whitespace-only value is stored as null, and update-epic clears it with null. create-epic, update-epic and get-epics return the epic's goal, and prepare-issue-context returns it with the issue's epic. delete-epic returns only the deleted epic's id, title and project.
What done looks like
An epic can carry an ordered list of checks: plain-text lines an agent verifies its work against, labelled by habit (Proof: …, Browser look: …). A check is not ticked and has no links. An epic holds at most 100 checks of at most 500 characters each.
Every tool that returns checks sends them in order, each as { "id": 12, "text": "Proof: …" }.
create-epic and update-epic take the whole list as an array of { "id"?, "text" } objects, in the order you want it:
- A check with an
idkeeps its row and gets the text and position you send - A check without an
idis created - A stored check you leave out is deleted
- An
idthat is not a check of this epic, or anidsent twice, rejects the whole call and nothing is stored
Done when
An epic can carry an ordered list of wishes: the customer's wishes, each linking the issues of this epic that deliver it. A wish is ticked by hand, with tick-epic-wish and untick-epic-wish; saving the epic never changes a tick. An epic holds at most 100 wishes of at most 500 characters each, and a wish links at most 100 issues.
Every tool that returns wishes sends them in order, each as:
json
{ "id": 7, "text": "The customer can pay by card", "issues": [{ "id": 3462, "key": "KD-2108" }], "checked_at": null, "checked_by_id": null }checked_at (ISO 8601) and checked_by_id say when and by whom the wish was ticked; both are null while it is open.
create-epic and update-epic take the whole list as an array of { "id"?, "text", "issue_ids"? } objects, saved like the checks above:
- A wish with an
idkeeps its row and its tick, and gets the text, position and links you send: itsissue_idsreplace its links - A wish without an
idis created; a stored wish you leave out is deleted with its links - Every issue a wish links must be an issue of this epic, after the call's own
issue_idsare applied. Otherwise the whole call is rejected and nothing is stored - An issue that leaves the epic, by any tool or screen that changes its epic, loses its links; the wish keeps its text and its tick
create-epic
Create a new epic to group and order issues on the timeline.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
project_id | integer | Yes | The project to create the epic in |
title | string | Yes | Epic title (max 255 characters) |
color | integer | Yes | Color code (0–9, see table above) |
goal | string | No | What the epic delivers (max 500 characters). An empty or whitespace-only value is stored as null. |
description | string | No | Epic description in Markdown (max 65,535 characters). An empty or whitespace-only value is stored as null. |
start | date | No | Start date (ISO 8601). Required if end is provided. |
end | date | No | End date (ISO 8601). Must be after start. Required if start is provided. |
order | integer | No | Display order (default 0, minimum 0) |
assignee_id | integer | No | User ID of the project member to assign the epic to. Omit or send null for no assignee. |
issue_ids | array | No | Issue IDs to attach (must belong to the same project, at most 500). Omit or send null for an epic with no issues. |
checks | array | No | What done looks like, in order: { "text" } objects without an id (at most 100, each at most 500 characters). Omit for an epic with no checks. |
wishes | array | No | Done when, in order: { "text", "issue_ids"? } objects without an id (at most 100, each at most 500 characters and at most 100 issue IDs). A wish may link an issue this call attaches through issue_ids. Omit for an epic with no wishes. |
Behavior
- Status is derived (see Status above); a new epic with no issues and no ticked wishes is
Open(status0,status_nameOpen) - Start and end dates must be provided together — you can't set one without the other
- Every issue ID must be an issue of the specified project (at most 500); otherwise the create is rejected and nothing is stored
- The assignee must be a project member; otherwise the create is rejected with
Assignee not found or access deniedand nothing is stored - The assignee gets an in-app notification and, when their Assignment mail preference is on, a mail; both link to the epic. Assigning yourself notifies nobody
- The response includes
checks, the stored checks in order ([]when none were sent) - The response includes
wishes, the stored wishes in order with their linked issues ([]when none were sent) - Response includes
assignee_id,created_atandupdated_at(ISO 8601) - Requires the appropriate Epics permission for this action
Example Prompt
Create a red epic called "Q1 Auth Overhaul" in the kendo project for the month of April. Attach the three auth-related issues we created earlier.
update-epic
Update an existing epic's details, dates, or issue assignments.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
epic_id | integer | Yes | The epic to update |
title | string | No | New title (max 255 characters) |
goal | string | No | New Goal (max 500 characters), or null to clear. An empty or whitespace-only value clears it too. Omit to keep the current Goal. |
description | string | No | New description in Markdown (max 65,535 characters), or null to clear. An empty or whitespace-only value clears it too. |
color | integer | No | Color code (0–9) |
start | date | No | New start date, or null to clear. Send together with end — both dates, or both null to clear the window. |
end | date | No | New end date, or null to clear. Must be after start. Send together with start. |
order | integer | No | New display order (minimum 0) |
assignee_id | integer | No | User ID of the project member to assign the epic to, or null to unassign. Omit to keep the current assignee. |
issue_ids | array | No | Complete list of issue IDs to attach (at most 500). Omit or send null to keep current assignments. Pass [] to detach all. |
checks | array | No | Complete What done looks like list, in order: { "id"?, "text" } objects (at most 100, each at most 500 characters). Omit or send null to keep the current checks. Pass [] to clear them. |
wishes | array | No | Complete Done when list, in order: { "id"?, "text", "issue_ids"? } objects (at most 100, each at most 500 characters and at most 100 issue IDs). Omit or send null to keep the current wishes. Pass [] to clear them. |
Behavior
- Only provided fields are updated
- Omitting
issue_ids, or sendingnull, preserves current issue assignments; passing[]detaches all issues - Every issue ID must exist in the epic's project (at most 500); otherwise the update is rejected
- Omitting
checks, or sendingnull, keeps the stored checks; passing[]clears them. A list is saved as described under What done looks like above, and a rejected check leaves the epic as it was - The response includes
checks, the epic's checks in order - Omitting
wishes, or sendingnull, keeps the stored wishes; passing[]clears them. A list is saved as described under Done when above, against the issues the epic holds once this call'sissue_idsare applied, and a rejected wish leaves the epic as it was - An issue this call detaches, or takes from another epic, loses its links to the wishes of the epic it leaves
- The response includes
wishes, the epic's wishes in order with their linked issues and their tick - The assignee must be a project member; otherwise the update is rejected with
Assignee not found or access denied - Changing the assignee notifies the new assignee and the old one, as for an issue: an in-app notification, and a mail when their Assignment mail preference is on. Both link to the epic. Assigning yourself notifies nobody
- Status is not directly editable — it's derived from the epic's Done when wishes, or from the lanes of its issues when it has none
- The response includes the derived
status(0/1) andstatus_name(Open/Closed) - Response includes
assignee_id,created_atandupdated_at(ISO 8601) - Requires the appropriate Epics permission for this action
Example Prompt
Push the "Auth Overhaul" deadline to mid-May and attach the new MFA issue
get-epics
Get epics for a project with full issue details and progress data. Read-only and safe to call repeatedly.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
project_id | integer | Yes | The project to get epics for |
epic_id | integer | No | Get a single epic by ID |
status | integer | No | Filter by derived status (0 Open, 1 Closed). With Done when wishes, Closed means every wish is ticked; without, every issue is done |
Behavior
- Returns epics with full issue details (key, title, lane, assignee, and
priority/typewithpriority_name/type_name) - Each epic includes derived
status(0/1) andstatus_name(Open/Closed) — see Status above - Each epic includes its
goal, ornullwhen it has none - With
epic_id, the epic also includes itsdescription; the list withoutepic_idleaves it out, so read one epic for its description - Includes progress data: completed issues (those in the project's last lane) vs total. It counts issues even when the wishes decide the status
- Each epic includes
attachments_count— the number of files attached to the epic - Each epic includes
assignee_id— the project member it is assigned to, ornull. A member who leaves the project, or whose account is deleted, is unassigned from its epics - Each epic includes
checks_count— the number of What done looks like checks - Each epic includes
wishes_countandchecked_wishes_count— the number of Done when wishes, and how many of them are ticked - With
epic_id, the epic also includeschecksandwishes, both in order, each wish with its linked issues and its tick; the list withoutepic_idleaves them out - With
epic_id, the epic also includescomments, in the order they were posted, each with ID, content, author,parent_id(the comment it replies to, ornull),is_pinned,liker_ids, attachments andcreated_at/updated_at; the list withoutepic_idleaves them out. Add, edit and delete them with the comment tools - Each epic includes
created_atandupdated_at(ISO 8601) - Results ordered by display order
- Marked as
#[IsReadOnly]and#[IsIdempotent]
Example Prompt
Show me the open epics in the kendo project and their progress.
delete-epic
Permanently delete an epic.
Destructive
This action cannot be undone. The epic and its comments are permanently removed. Issues linked to the epic are NOT deleted — only the epic association is removed.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
epic_id | integer | Yes | The epic to delete |
Behavior
- Issues linked to the epic are preserved — only the epic grouping is removed
- The epic's comments are deleted with it, with their likes and attachments
- Requires Epics: Delete permission
Example Prompt
Delete the "Auth Overhaul" epic, we're restructuring the roadmap
tick-epic-wish
Tick one Done when wish of an epic, recording who ticked it and when.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
epic_id | integer | Yes | The epic |
wish_id | integer | Yes | A Done when wish of that epic. Find the IDs with get-epics and epic_id |
Behavior
- Records the user of the calling token as
checked_by_idand the current time aschecked_at - Ticking a wish that is already ticked changes nothing: it keeps its first ticker and time
- Returns
epic_idand the wish asget-epicssends it:id,text,issues,checked_at,checked_by_id - Also returns
epic: the epic'sstatus,status_name,wishes_countandchecked_wishes_count, read after the tick, so ticking the last open wish answersClosed - A
wish_idthat is not a Done when wish of this epic, a What done looks like check included, answersWish not found or access denied - Every open view of the epic receives the new tick, and every list its status and wish counts
- Requires Epics: Update permission
- Marked as
#[IsIdempotent]
Example Prompt
Tick the "The customer can pay by card" wish on the Payments epic, the card flow is live.
untick-epic-wish
Untick one Done when wish of an epic, clearing who ticked it and when.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
epic_id | integer | Yes | The epic |
wish_id | integer | Yes | A Done when wish of that epic. Find the IDs with get-epics and epic_id |
Behavior
- Sets
checked_atandchecked_by_idback tonull - Unticking a wish that is open changes nothing
- Returns
epic_idand the wish asget-epicssends it - Also returns
epic: the epic'sstatus,status_name,wishes_countandchecked_wishes_count, read after the untick - A
wish_idthat is not a Done when wish of this epic answersWish not found or access denied - Every open view of the epic receives the change, and every list its status and wish counts
- Requires Epics: Update permission
- Marked as
#[IsIdempotent]
Example Prompt
Untick the card payment wish on the Payments epic, the provider rolled it back.
See Also
- Resources — Read epic data via
kendo://projects/{id}/epics - Projects Guide — Understanding epics and timeline planning
- Epics API — REST endpoints for epic management