Working with workspaces

Concepts

Quick recap of concepts in Kantree:

  • A user is a member of one or more teams
  • Each team contains projects
  • Projects contain cards.
  • Cards can contain other cards.
  • There is a top level card from which the hierarchy of cards start. This card is considered the “project” card.
  • We use the term children for cards directly under another and descendants for all the cards in the hierarchy starting from one card.
  • Cards have a title, some field values and can be associated to a model
  • There is a set of fields defined at the project level and shared by all cards
  • Models can define their own fields. When a card is associated to a model, it can use fields from the project and from the model.
  • Cards can be organized in groups
  • Groups belong to a group type
  • The grouping system is exposed through “contexts” and through the field type “group_type” (Labels or Multiple Choice in the interface).

IMPORTANT:

  • “workspaces” are still named “projects” in the API
  • “fields” are still named “attributes” in the API

The next api version will use the new names

Pagination

Some calls may return paginated results (notably listing cards on projects). Paginated results will contain the following headers:

  • X-Kantree-Page: current page number
  • X-Kantree-NextPage: next page number
  • X-Kantree-Total: total number of items
  • X-Kantree-TotalPages: total number of pages

Pass the page parameter to get the desired page. You can control how many items per page using per_page.

Example:

GET /projects/123/cards?page=2

Listing projects

Get your Champs:

GET /organizations

Get the list of projects in the org.:

GET /organizations/{org_id}/projects

List cards in your project

List all the cards in your project (across all the hierarchy):

 GET /projects/{project_id}/cards

The results are paginated. See the pagination section at the beginning.

This call can take a few parameters:

  • filter: a KQL filter to search for cards
  • with_archived: bool indicating whether archives should be included
  • only_ids: bool indicating to only return card ids

Getting a card details

Get a card details:

 GET /cards/{card_id}

Get the stream of a card (comments, activities, logs):

 GET /cards/{card_id}/stream

Get the children of a card:

 GET /cards/{card_id}/children

Creating cards

First you will need to determine the parent of the future card. It can be the top level card (you will find the top_level_card_id property on the project object) or any card in the project.

POST /cards/{parent_id}/children
{
    "title": "my new card title",
    "attributes": {"Due Date": "2018-01-01"},
    "group_id": 111
}

About fields

Some fields can have values only from a list of available choices. To list the choices:

GET /cards/{card_id}/attributes/{attr_id}/choices

Which returns a list of tuples in the form of (value, label). Use the value to set the field.

Updating a card

To update the card title:

PUT /cards/{card_id}
{
    "title": "new card title"
}

To change the state of the card:

PUT /cards/{card_id}
{
    "state": "completed"
}

Available states: undecided, dropped, accepted, in_progress, waiting, completed, closed.

To update fields:

POST /cards/{card_id}/attributes
{
    "attributes": {
        "field_name_or_id": "value",
        "field_name_or_id": "value"
    }
}

You can also edit fields individually:

POST /cards/{card_id}/attributes/{field_name_or_id}
{
    "value": "my field value"
}

When dealing with fields with multiple values, you can use append or pop:

POST /cards/{card_id}/attributes/{field_name_or_id}/append
{
    "value": "my field value"
}

Warning: fields of type “group_type” cannot be modified through this operation. You will need to use the grouping system as explained below. When a field is of type “group_type”, it includes a group_type_id property.

The format of the value depends on the type of field.

  • text / content: a string
  • number: int or float
  • bool: either a JSON boolean or a string where the value “false”, “no” and “0” are considered false
  • date:

    • dates use the ISO format YYYY-MM-DD. If the time option is enabled, time can be added after the date with the format HH:MM:SS.
    • In case of periods, you can specify the start and end date:

      • using JSON: {"start": "YYYY-MM-DD", "end": "YYYY-MM-DD"}
      • using a string: YYYY-MM-DD -> YYYY-MM-DD
  • time:: time in the format HH:MM:SS
  • members: either a user id or its username starting with @
  • likes: -1, 0, 1 depending on your vote
  • relationships: the id of the target card

For files fields, there are multiple ways to set the value:

  • Pass the file as the value field, example: curl https://kantree.io/api/1.0/cards/{card_id}/attributes/{field_name_or_id}/append -F value=@myfile.ext
  • Pass a URL as the value: {"value": "http://example.com/myimage.jpg"}
  • Pass a dict with the name and data keys:

    • Data as tring: {"value": {"name": "myfile.txt", "data": "..."}}
    • Data as base64 encoded value with mimetype: {"value": {"name": "myimage.png", "data": "data:image/png;base64,..."}}

Moving cards between groups

Listing available groups

List all available group types:

GET /projects/{project_id}/group-types

To list available groups for a card, you must use its parent’s id:

GET /cards/{parent_id}/groups

Possible parameter:

  • type_id: only show groups of this type

Moving the card

POST /cards/{card_id}/relocate
{
    "parent_id": 111,
    "group_id": 222,
    "position": 1
}

Parameters:

  • parent_id: the id of the parent. in most cases it should be the same as the current one so you can use the parent_id property on the card object. A different one will change the parent of the card.
  • group_id: the id of the group
  • position: optional, position at which to place the card

Adding cards to multiple groups of the same type

If the group type allows it, you can add a card to multiple groups of the same group type.

POST /cards/{card_id}/add-to-group
{
    "group_id": 111
    "position": 1
}

Remove from a group:

POST /cards/{card_id}/remove-from-group
{
    "group_id": 111
}

Remove from all groups of a type:

POST /cards/{card_id}/remove-from-group-type
{
    "type_id": 111
}

Associating a card to a model

To associate:

POST /cards/{card_id}/model
{
    "model_id": 111
}

To deassociate:

POST /cards/{card_id}/model
{
    "model_id": null
}

Removing a card

Archive and restore

Archive:

POST /cards/{card_id}/archive

Restore:

DELETE /cards/{card_id}/archive

Delete a card

DELETE /cards/{card_id}