Skip to content

PI Objectives — Endpoints

Base URL: https://rest.kendis.io/api/<companyPrefix>/… · Auth: HTTP Basic (email : API key).


1. List collections

GET /api/<companyPrefix>/collections

Returns all board collections visible to the authenticated user. Run this first to discover collection IDs for filtering boards.

curl -H "Authorization: Basic <base64-token>" \
     "https://rest.kendis.io/api/<companyPrefix>/collections"

Response — 200 OK

{
  "data": [
    { "id": "<collection-id-1>", "title": "Program Collection" },
    { "id": "<collection-id-2>", "title": "Operations Collection" }
  ]
}

2. List boards

GET /api/<companyPrefix>/boards

Returns boards visible to the authenticated user. Use the id returned here as the boardId on the next endpoint — there is no other reliable way to get a board ID.

Query parameters

Parameter Type Required Description
collectionIds string No Comma-separated collection IDs from List Collections. Plural form onlycollectionId (singular) is silently ignored.
# all boards
curl -H "Authorization: Basic <base64-token>" \
     "https://rest.kendis.io/api/<companyPrefix>/boards"

# boards in specific collections
curl -H "Authorization: Basic <base64-token>" \
     "https://rest.kendis.io/api/<companyPrefix>/boards?collectionIds=<collection-id-1>,<collection-id-2>"

Response — 200 OK

{
  "data": [
    {
      "id": "<board-id>",
      "title": "ADO PI#9",
      "state": { "id": "<state-id>", "title": "Tracking" }
    }
  ]
}

3. List objective groups

GET /api/<companyPrefix>/objective-groups

Returns objective groups for a single board, each with its objectives and (optionally) their linked board items and sub-items.

Query parameters

Parameter Type Required Default Description
boardId string Yes The PI Board ID, from List Boards
completionType string No 2 (or 6 when OKRs are enabled on the board) Which completion calculation to project onto objective.completion. See reference.
additionalColumns string No Set to 1 to add a denormalised teamsAndSprints array on each linked item / sub-item. See reference.
curl -H "Authorization: Basic <base64-token>" \
     "https://rest.kendis.io/api/<companyPrefix>/objective-groups?boardId=<board-id>&completionType=2&additionalColumns=1"

Response — 200 OK (ADO-connected board, truncated; IDs replaced with placeholders)

{
  "data": [
    {
      "id": "<group-id>",
      "title": "Team Sky",
      "type": "TeamGroup",
      "completion": 25.0,
      "bvPlan": 7.0,
      "bvActual": 8.0,
      "achievement": 114.29,
      "status": { "id": "<status-id>", "title": "Planned", "category": "ToDo" },
      "objectives": [
        {
          "id": "OBJ-23",
          "title": "Objective for 5",
          "type": "Objective-Committed",
          "completion": 25.0,
          "bvPlan": 7.0,
          "bvActual": 5.0,
          "sequence": 17371185352.0,
          "status": { "id": "<status-id>", "title": "Planned", "category": "ToDo" },
          "linkedItems": [
            {
              "id": "<kendis-item-id>",
              "tfsId": "415",
              "tfsURL": "https://dev.azure.com/<org>/<project-guid>/_workitems/edit/415",
              "tfsItemTypeIcon": "https://tfsprodweu5.visualstudio.com/_apis/wit/workItemIcons/icon_trophy?color=773B93&v=2",
              "title": "Feature 1",
              "type": "Feature",
              "issueType": "Feature",
              "storyPoints": 0.0,
              "completion": 0.0,
              "status": { "id": "<status-id>", "title": "New", "category": "ToDo" },
              "teamsAndSprints": [
                {
                  "sequence": 23121024284.0,
                  "team":   { "id": "<team-id>", "title": "Team Earth", "label": "EART", "color": "#f39c12" },
                  "sprint": { "id": "<sprint-id>", "title": "Iteration 3", "label": "S3", "startDate": 1777852800000, "endDate": 1778803200000, "isIPSprint": false }
                }
              ],
              "subItems": [
                {
                  "id": "<sub-item-kendis-id>",
                  "tfsId": "1178",
                  "tfsURL": "https://dev.azure.com/<org>/<project-guid>/_workitems/edit/1178",
                  "tfsItemTypeIcon": "https://tfsprodweu5.visualstudio.com/_apis/wit/workItemIcons/icon_book?color=0098C7&v=2",
                  "title": "Story 2",
                  "type": "UserStory",
                  "issueType": "Story",
                  "storyPoints": 0.0,
                  "status": { "id": "<status-id>", "title": "New", "category": "ToDo" }
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

Jira-connected boards

On Jira boards, replace tfsIdjiraId, drop tfsURL (the Jira URL is built from jiraKey), and add jiraKey (e.g. FEA-123) and jiraIssueTypeId. tfsItemTypeIcon is absent. Everything else is identical. See Compatibility notes.


completionType reference

completionType selects which completion calculation the server projects onto each objective.completion. The valid values mirror the dropdown in the in-app Objectives screen.

Value Calculation Notes
1 Linked-item status Counts only the direct linked items' statuses
2 Children linked-item status (default when OKR mode is off) Counts direct items + their sub-items by status
3 Children linked-item estimate Uses estimates (story points / effort) of children, not status counts
4 Team-story status Filters to stories under each Team's iterations and counts by status
5 Team-story estimate Same as 4 but uses estimates
6 OKR / KR-weighted formula (default when OKR mode is on) Uses the Key Result weighting formula — only meaningful when OKRs are enabled on the board

Defaulting behaviour

  • OKR mode off and completionType omitted → server falls back to 2.
  • OKR mode on and completionType=6 → server uses the OKR formula path.
  • OKR mode on and completionType is 15 → respected as-is.
  • Any unrecognised value silently falls back to the OKR / status default for that board.

Tip

When the chosen completionType produces no data (e.g. 4/5 on a board with no Team mappings), objective.completion may be 0 or null — both are valid; treat null as "not computable".


additionalColumns

additionalColumns=1 adds a denormalised teamsAndSprints array to every linkedItems and subItems entry. Omit it (or set 0) for a leaner payload without that array.

Because team / sprint titles and labels are denormalised onto the entry, a single call to /objective-groups?additionalColumns=1 is enough — no separate /teams or /sprints calls are needed for this endpoint.

See the teamsAndSprints entry for the shape.