Projects and workflows
Every Iskue project owns at least one workflow: an ordered set of statuses plus the transitions that connect them. A workflow is seeded from a template when the project is created, and project admins can then reshape it — add or remove statuses, restrict transitions, and attach rules that gate, validate or automate each move. This page covers project creation, the four templates, the workflow editor (table and diagram views), transition rules, and per-type workflow schemes.
Create a project
In the web UI, open Projects and press New project. The form asks for a key, a name and a template. The creator automatically becomes a project member with the ADMIN project role, so they can administer the workflow immediately. Every configuration change described on this page is recorded in the project's configuration audit log.
- Key — 2–10 alphanumeric characters, starting with a letter (pattern
[A-Za-z][A-Za-z0-9]{1,9}). The server upper-cases it on creation; keys are unique case-insensitively, and a duplicate returns409 Conflict. - Name — required, at most 120 characters.
- Description — optional, at most 4000 characters (API only; the quick-create form omits it).
- Template — optional; when omitted the project uses
SCRUM.
ISKUE_URL="https://iskue.example.com" # your Iskue base URL
TOKEN="<paste a bearer token from POST /api/v1/auth/login>"
curl -sS -X POST "$ISKUE_URL/api/v1/projects" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"key":"OPS","name":"Operations","template":"KANBAN"}'The New project dialog offers Scrum, Kanban and Bug tracking. The fourth template, PORTFOLIO, is accepted by the API at project creation and is offered in the UI when creating additional workflows under Workflow settings (labelled *Portfolio funnel*).
The four workflow templates
A template seeds the project's first workflow: its statuses in order, with the first status marked initial (new tickets start there), and one *global* transition per status. Every status belongs to a category — TODO, IN_PROGRESS or DONE — which drives board grouping and the diagram layout.
| Template | Statuses (category) | Initial status |
|---|---|---|
SCRUM | To Do (TODO) → In Progress (IN_PROGRESS) → In Review (IN_PROGRESS) → Done (DONE) | To Do |
KANBAN | To Do (TODO) → In Progress (IN_PROGRESS) → Done (DONE) | To Do |
BUG_TRACKING | Open (TODO) → Triaged (TODO) → In Progress (IN_PROGRESS) → Resolved (DONE) → Closed (DONE) | Open |
PORTFOLIO | Funnel (TODO) → Analyzing (TODO) → Portfolio Backlog (TODO) → Implementing (IN_PROGRESS) → Done (DONE) | Funnel |
Default template behaviour: permissive global transitions
Each seeded transition is named Move to <Status> and has no source status (shown as *Any status* in the editor). A move is allowed when either an explicit from→to transition exists or a from-any transition points at the target — so a freshly templated workflow permits moving any ticket from any status to any other status. When a move matches both, rules are read from the explicit from→to row first, falling back to the global row.
To lock a workflow down, delete the seeded Move to <Status> transitions and add explicit from→to transitions for the paths you want. Tickets can then only follow the edges you define.
Edit statuses and transitions (Settings → Workflow)
Open the project and follow the Workflow link (route /projects/<KEY>/workflow, also linked from project settings). Any project member can view the workflow; changing it requires the project ADMIN role, and changes apply immediately. The page offers two views — Table (default) and Diagram — via a toggle that is remembered per project in your browser.
Statuses
Add a status by entering a name (at most 60 characters) and picking a category, then pressing Add status. Names must be unique within the workflow, case-insensitively. Use make initial to change where new tickets start — exactly one status is initial at a time. The UI covers add, make-initial and delete; renaming or re-categorising an existing status is done through the API's PATCH endpoint, which accepts name, category and sortOrder.
# Add a status to project OPS
curl -sS -X POST "$ISKUE_URL/api/v1/projects/OPS/workflow/statuses" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"name":"Blocked","category":"IN_PROGRESS"}'
# Rename it (statusId comes from the response above, or from GET .../workflow)
curl -sS -X PATCH "$ISKUE_URL/api/v1/projects/OPS/workflow/statuses/$STATUS_ID" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"name":"On Hold"}'Deleting a status is guarded: you cannot delete the initial status (set another status initial first), and you cannot delete a status that tickets currently occupy. Deleting a status also removes every transition that starts or ends at it.
Transitions
Add a transition by naming it (at most 60 characters), choosing a source — a specific status or From: any status — and a target, then pressing Add transition. A transition may not point to its own source status; the server rejects it with *"A transition cannot point to its own source status"*. Delete removes the transition and any rules attached to it.
Transition rules
Press Rules next to a transition (or select its arrow in the diagram) to open the rule editor. Three kinds of rule can be attached, evaluated in this order when a ticket is moved: conditions gate whether the transition is offered at all, validators must pass before it commits, and post-functions run after it succeeds. A transition with no rules behaves as a plain status change. Save rules replaces the transition's entire rule set with what is shown in the editor, in the listed order.
Conditions (kind CONDITION)
A failing condition removes the target status from the user's transition menu, and a direct API attempt returns 403 Forbidden with the reason for the first failing condition. Independently of any rules, every move also requires the TRANSITION_TICKET permission.
| Type | Spec (JSON) | Passes when |
|---|---|---|
PERMISSION | {"type":"PERMISSION","key":"TRANSITION_TICKET"} | The user holds the named permission key in this project. Any key from the permission catalogue is accepted; the rule builder offers TRANSITION_TICKET, ADMINISTER_PROJECT and EDIT_TICKET. |
ROLE | {"type":"ROLE","role":"ADMIN"} | The user's project role equals the named role (ADMIN, MEMBER or VIEWER, matched case-insensitively). Instance administrators always pass. |
PREDICATE | {"type":"PREDICATE","predicate":{…}} | The field predicate matches the ticket's current field values (shape below). |
APPROVAL | {"type":"APPROVAL"} | At least one approval has been requested on the ticket, and every requested approval is granted. |
Validators (kind VALIDATOR)
Validators run in saved order once the move is otherwise allowed; the first failure aborts the transition with 422 Unprocessable Entity and the validator's message (or a built-in default when the message is blank).
| Type | Spec (JSON) | Fails when |
|---|---|---|
REQUIRED_FIELD | {"type":"REQUIRED_FIELD","fieldRef":"assignee","message":"…"} | The referenced field is null, blank or an empty list. |
PREDICATE | {"type":"PREDICATE","predicate":{…},"message":"…"} | The predicate does not match the ticket's field values. |
Post-functions (kind POSTFUNCTION)
Post-functions are automation actions applied after the status change, within the same transaction. A malformed or failing post-function is logged and skipped — it never blocks the committed transition. The TRANSITION and ADD_CANNED_COMMENT automation actions are intentionally not applied as post-functions.
| Action | Spec (JSON) | Effect |
|---|---|---|
ASSIGN | {"type":"ASSIGN","value":"<user UUID>"} | Assigns the ticket to the given user. |
ASSIGN_TO_CURRENT_USER | {"type":"ASSIGN_TO_CURRENT_USER"} | Assigns the ticket to whoever performed the transition. |
SET_PRIORITY | {"type":"SET_PRIORITY","value":"HIGH"} | Sets the ticket priority (value is a priority name, case-insensitive). |
ADD_LABEL | {"type":"ADD_LABEL","value":"<label UUID>"} | Adds an existing project label to the ticket. |
ADD_COMMENT | {"type":"ADD_COMMENT","value":"…"} | Adds a comment authored by the transitioning user. |
Predicates and REQUIRED_FIELD see this field state: priority (priority name), assignee, reporter, type and status (UUID strings), summary (the title text), estimate, plus each custom field as custom:<fieldId> (the custom field's UUID — the same key used in the customValues map). The predicate shape is {"any":[{"all":[{"fieldRef":…,"op":…,"value":…}]}]} — it matches when any group matches, a group matches when all its conditions match, and an empty predicate always matches. The engine supports the operators EQUALS, NOT_EQUALS, IN, NOT_IN, IS_EMPTY, IS_NOT_EMPTY, GREATER_THAN, LESS_THAN and CONTAINS; the rule builder offers EQUALS, NOT_EQUALS, IS_EMPTY, IS_NOT_EMPTY, GREATER_THAN and LESS_THAN over the fields assignee, priority, summary and estimate.
# Transition ids are listed by GET $ISKUE_URL/api/v1/projects/OPS/workflow
curl -sS -X PUT "$ISKUE_URL/api/v1/projects/OPS/workflow/transitions/$TRANSITION_ID/rules" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"rules":[
{"kind":"CONDITION","spec":{"type":"ROLE","role":"ADMIN"}},
{"kind":"VALIDATOR","spec":{"type":"REQUIRED_FIELD","fieldRef":"assignee",
"message":"Assign the ticket before closing it"}},
{"kind":"POSTFUNCTION","spec":{"type":"ADD_COMMENT","value":"Closed via workflow"}}
]}'PUT …/rules is a full replacement — send the complete set every time. An empty rules array clears all rules from the transition.
The diagram view
Switch the editor to Diagram to see statuses as nodes arranged in columns by category (TODO left, IN_PROGRESS centre, DONE right) and transitions as labelled arrows. Drag a node to reposition it; positions are saved per workflow in your browser's local storage, so the layout is personal to you and survives reloads. A dashed ANY node appears whenever a from-any transition exists, and the initial status is drawn with a dashed border and a ▸ marker. Click a node to get a panel with make initial and Delete; click an arrow for Rules and Delete; click empty canvas to clear the selection. New statuses and transitions are still added through the forms beneath the diagram — the diagram is for layout, selection and the actions above, not free-hand edge drawing.
Per-type workflows (the workflow scheme)
Each ticket type follows the project's default workflow unless it is mapped to another one. New projects seed the ticket types EPIC, STORY, TASK, BUG and SUBTASK, all initially on the default workflow. In the Per-type workflows section of the workflow page, create an additional workflow by naming it and choosing a template (Kanban, Scrum, Bug tracking or Portfolio funnel — Kanban when unspecified), then pick a workflow per ticket type from the drop-downs. Selecting the entry marked (default) clears the mapping so the type falls back to the default workflow. A ticket's type decides which workflow governs its initial status, its allowed transitions and the rules that apply.
# 1. Create a workflow from the bug-tracking template
curl -sS -X POST "$ISKUE_URL/api/v1/projects/OPS/workflow/workflows" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"name":"Bug workflow","template":"BUG_TRACKING"}'
# 2. Find the BUG ticket type id
curl -sS "$ISKUE_URL/api/v1/projects/OPS/ticket-types" -H "Authorization: Bearer $TOKEN"
# 3. Map the type to the new workflow (workflowId null clears back to the default)
curl -sS -X PUT "$ISKUE_URL/api/v1/projects/OPS/workflow/scheme/mappings" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"ticketTypeId":"'"$TYPE_ID"'","workflowId":"'"$WORKFLOW_ID"'"}'
# Inspect the scheme: workflows, mappings and the default workflow id
curl -sS "$ISKUE_URL/api/v1/projects/OPS/workflow/scheme" -H "Authorization: Bearer $TOKEN"The workflow admin screen and the board columns show the default workflow's statuses; tickets whose type is mapped elsewhere are still transitioned, validated and reported against their own workflow. Status lookups by id (reports, automation, ticket views) resolve across every workflow the project owns.