Docs · Using Iskue

Scaled agile: teams, ARTs, PIs and portfolio

Beyond single-team Scrum and Kanban, Iskue models the structures of the Scaled Agile Framework: teams grouped into agile release trains (ARTs), ARTs grouped into solution trains, program increments (PIs) with a generated iteration cadence, PI objectives, ROAM risks, milestones, a drag-and-drop program board, burn-up and predictability reporting, an Inspect & Adapt summary, and a portfolio layer of strategic themes and value streams with lean-budget guardrails. All of it is a view over ordinary tickets — a ticket simply gains team, pi, iteration, theme and WSJF fields — so nothing is duplicated into a parallel data model.

Edition: the SAFe module is an Enterprise feature. /api/v1/arts/**, /api/v1/pis/**, /api/v1/portfolio, /api/v1/admin/teams/** and /api/v1/value-streams/** answer 403 This feature requires the ENTERPRISE edition on lower editions, and the matching navigation entries are hidden. The read-only pickers (GET /api/v1/teams, GET /api/v1/themes), the SAFe fields on tickets, the team/pi/theme TQL fields and per-sprint team capacity are deliberately not gated, so data entered under an Enterprise licence stays visible and queryable afterwards. With no licence installed nothing is gated.

Where it lives

PageRouteWhoWhat
Teams & ARTs/admin/teamsInstance adminSolution trains, ARTs, teams and members; program increments (state, cadence, burn-up, objectives, risks); strategic themes; value streams and lean budgets
Program board/program-boardAny userPI planning: drag work items across (team × iteration) cells, see milestones and blocking dependencies
ART dashboard/art-dashboardAny userInspect & Adapt: predictability across PIs, the current PI at a glance, the I&A summary export
Portfolio/portfolioAny userCross-project overview of accessible projects, value-stream guardrails, filtered by strategic theme
Rooms/roomsAny userRole-based home pages — RTE room (ART report and trains), Team room (team catalogue and my open work), Portfolio room (guardrails, goal alignment, progress). Rooms are composed from the APIs below; the last room chosen is remembered per browser.
Ticket detail/tickets/:keyMembersTeam, Program Increment, Iteration, Theme pickers and the WSJF editor

Teams, ARTs and solution trains

A team owns work items: the team field on tickets, team = "Payments" in TQL, a per-sprint capacity, and a row on the program board. An ART groups teams into a release train and is what a PI belongs to; a solution train groups ARTs for SAFe Large Solution. Names are unique at each level (duplicates return 409 A team named '…' already exists, likewise for ARTs and trains); deleting a solution train detaches its ARTs rather than deleting them. Membership uses a dedicated team-member table, independent of user groups.

Team and ART management
# Admin: an ART, a team in it, and a member
curl -s -X POST $ISKUE_URL/api/v1/admin/teams/arts -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"name":"Commerce ART"}'
curl -s -X POST $ISKUE_URL/api/v1/admin/teams -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"name":"Payments","artId":"<art-uuid>"}'
curl -s -X POST $ISKUE_URL/api/v1/admin/teams/<team-uuid>/members -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"userId":"<user-uuid>"}'

# Anyone: the pickers
curl -s $ISKUE_URL/api/v1/teams -H "Authorization: Bearer $TOKEN"
curl -s $ISKUE_URL/api/v1/arts  -H "Authorization: Bearer $TOKEN"
EndpointAccessPurpose
GET /api/v1/teamsAny userTeam catalogue for pickers and TQL suggestions: id, name, ART, member count, members
GET/POST /api/v1/admin/teams, GET/PATCH/DELETE …/{id}AdminTeams: name (≤ 120), optional artId (clearArt to detach)
POST …/{id}/members, DELETE …/{id}/members/{userId}AdminTeam membership
GET/POST /api/v1/admin/teams/arts, PATCH/DELETE …/arts/{id}AdminARTs: name; PATCH sets solutionTrainId or clearTrain
GET/POST /api/v1/admin/teams/solution-trains, DELETE …/{id}AdminSolution trains
GET /api/v1/arts, GET /api/v1/arts/solution-trainsAny userRead-only catalogues (so Rooms work for non-admins)
GET /api/v1/arts/{id}/reportAny userART report: current PI, predictability per PI, burn-up, per-team completeness (planned/done tickets and points), open cross-team dependencies
GET /api/v1/arts/solution-trains/{id}/reportAny userOne row per ART: team count, current PI, latest predictability, open cross-team dependencies

Program increments

A PI is an ART's planning timebox. Create it with a name (unique per ART) and a start date — the end date defaults to start + 10 weeks — then generate the cadence: devIterations (1–8) iterations of iterationDays (7–28) days, named It 1 … It N with kind DEV, followed by one IP (innovation and planning) iteration; the PI's end date snaps to the end of the IP iteration, and regenerating replaces the existing iterations. A PI moves through the states FUTURE → ACTIVE → DONE; the ART report and Rooms treat the active PI (or, failing that, the most recently started one) as *current*. Tickets are planned into a PI and an iteration through the ordinary ticket PATCH (piId, iterationId, or the clearPi/clearIteration flags) — which is exactly what dragging on the program board does. Deleting a PI deletes its iterations and milestones and clears pi on every ticket planned into it.

Create a PI, lay out 4×2-week dev iterations plus IP, activate it
curl -s -X POST $ISKUE_URL/api/v1/pis -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"artId":"<art-uuid>","name":"PI 2026.4","startDate":"2026-10-05"}'
curl -s -X POST $ISKUE_URL/api/v1/pis/<pi-uuid>/generate -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"devIterations":4,"iterationDays":14}'
curl -s -X PATCH $ISKUE_URL/api/v1/pis/<pi-uuid>/state -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"state":"ACTIVE"}'

Objectives and predictability

Each PI carries objectives per team (or at ART level when teamId is null): a description (≤ 500 characters), a committed flag (uncommitted objectives are *stretch* goals), a planned business value from 1 to 10 agreed at PI planning, and an actual business value from 0 to 10 scored at Inspect & Adapt. The predictability measure is sum(actual) / sum(planned) over committed objectives only — an unscored committed objective counts as 0 — reported per team and for the whole ART, as a rounded percentage (null while nothing is planned). The ART report plots it across PIs.

Risks (ROAM), milestones and the I&A summary

  • Risks — GET/POST /api/v1/pis/{id}/risks, PATCH …/risks/{riskId} ({"roam":…}), DELETE. A risk has a description (≤ 500), an optional owner and an optional ticket key (KEY-123 form, upper-cased), and a ROAM state RESOLVED, OWNED (default), ACCEPTED or MITIGATED.
  • Milestones — POST /api/v1/pis/{id}/milestones with name and date; DELETE …/milestones/{milestoneId}. The program board places each milestone in the iteration whose dates contain it.
  • Burn-up — GET /api/v1/pis/{id}/burnup: one row per iteration with scope (estimate sum of everything planned into the PI) and accepted (points of tickets whose last entry into a DONE status, from the changelog, happened by that iteration's end — reopening removes them).
  • I&A summary — GET /api/v1/pis/{id}/ia-summary returns a Markdown document: objectives table with commitment and planned/actual BV, the predictability line, risks by ROAM state, and metrics (scope, accepted, items planned, open cross-team dependencies). The ART dashboard offers it as an export.

The program board

/program-board is PI planning on one screen: rows are the ART's teams, columns are the PI's generated iterations, cards are the tickets planned into the PI (key, title, estimate, status category). Drag a card to another cell to change its team and iteration; arrows show BLOCKS dependencies, and a red dashed arrow flags a blocker scheduled *after* the item it blocks. Milestones sit in their iteration column. The board (GET /api/v1/pis/{id}/board) applies the normal visibility rules — cards from projects you are not a member of and restricted tickets are omitted, and a dependency edge is dropped when either end is hidden — so two users can see different boards of the same PI. A PI without a cadence shows a prompt to generate one under Teams & ARTs.

Portfolio: themes, value streams and WSJF

  • Strategic themes (/api/v1/themes, admin writes) are organisation-level investment themes tagged onto portfolio epics (and any ticket) via themeId; the Portfolio board filters by them and the goals page groups goals by theme (GET /api/v1/goals/alignment). Deleting a theme clears it from tickets and goals first.
  • Value streams (/api/v1/value-streams) carry a story-point budgetPoints and a warnPct threshold (1–100); themes are assigned to a stream with PATCH /api/v1/value-streams/themes/{themeId}. GET /api/v1/value-streams/guardrails rolls up committed and done points from tickets tagged with each stream's themes and reports OK, WARN (utilisation ≥ warnPct) or OVER (committed ≥ budget).
  • WSJF — every ticket accepts wsjfUbv, wsjfTc, wsjfRr and wsjfSize (1–20 each); the score is (user-business value + time criticality + risk reduction) / job size, kept to one decimal, exposed as wsjfScore, and sortable with ORDER BY wsjf DESC.
  • Portfolio board — GET /api/v1/portfolio is a cross-project overview limited to the projects you can access.

Hierarchy tiers

SAFe tiers are catalogue configuration, not code. Three non-system ticket types ship for them — PORTFOLIO_EPIC (level 3), CAPABILITY (level 2, spanning ARTs) and FEATURE (level 1, a shippable slice planned into PIs) — and a project adopts them from Settings → Ticket types → Add existing, typically bumping its own Epic to level 2 so the chain reads Portfolio Epic > Epic > Feature > Story. Parent links follow the usual rule (the parent's level must be higher), and progress rolls up through the existing Children section. See the screens-and-fields page for the catalogue mechanics.

TQL and capacity

FieldOperatorsValues
team= != IN NOT INTeam name (case-insensitive) or empty for unowned
pi= != IN NOT INPI name or empty for unplanned; PI names are unique per ART, so one name can match PIs on several ARTs
theme= != IN NOT INStrategic theme name or empty for untagged
ORDER BY wsjf—Sort by WSJF score

All three appear in the TQL autocomplete metadata with instance-wide name suggestions (newest PIs first, up to 50 each). There is no iteration or art field. Capacity is set per team per sprint, not per PI iteration: PUT /api/v1/projects/{key}/sprints/{sprintId}/capacity with {"teamId","points"} (0–10 000, 0 removes the row; needs MANAGE_SPRINTS), and GET …/team-load returns tickets, points and capacity per team — the load-versus-capacity bars on the backlog page and the capacity bands on plan timelines read from it.