You are not logged in. Click here to log in.

codeBeamer ALM

Search In Project

Search inClear

Tags:  not added yet

REST API

Starting with codeBeamer 7.1, you can also access codeBeamer resources via a REST API.

The REST API is the replacement for the old Hessian-based Remote API and offers the following advantages:

  • Completely platform independent
  • Completely stateless. No need to worry about closing sessions or expiring session timeouts.
  • Completely self-describing.
  • Locale aware: data is returned and can be submitted in the client/user's preferred language (as long as language is supported by the server).
  • Based on open Web standards:
    • HTTP for the communication protocol.
    • JSON for the data interchange.
    • JSON Schema for the data description.
  • Clients do not need any codeBeamer client libraries nor any specific 3rd party libraries.
    • In fact, you can use any web browser to execute/test queries (GET), by simply entering the URL of the query into the browser's address bar.



The URL of the REST API typically is: https://{hostname}/cb/rest

In the following sections, we will use the placeholder {RestURL} to refer to the URL of the REST API.

Table of Contents

For a better readability, we will ommit the {RestURL} part when describing REST API methods and only show the relative URIs.

Accessing resources

In the REST API, each codeBeamer resource is identified, accessed and referenced via an URI, that is relative to the REST API URL.


Important note: By default Rest API Access is disabled for users. Every user has permission to Access Rest API if they have Rest / Remote API - Access Group Permission is granted.


For example: The URI of the default system administrator "bond" is: /user/1 or /user/bond

Using relative resource URIs simply allows to append the relative {ResourceURI} to the {RestURL} in order to create a request to that resource.

E.g. to get the account information for the user "bond" via the REST API, you would do a: GET {RestURL}{UserURI}:

GET https://hostname/cb/rest/user/bond

The following HTTP methods are supported by the REST API:

Method Used for Return status Response
POST Create a new resource and return it's URI 201 (Created) A reference to the newly created resource in the response body
The new resource's URI is also returned in the 'Location' response header
PUT Update existing resources 200 (OK) No response body
DELETE Delete resources 200 (OK) No response body
GET Retrieve resources 200 (OK) The requested resource data


Any other response status than 200 (OK) and 201 (Created) means failure.
In that case the response body contains additional failure information:

{ "exception" : "Type of failure", "message" : "Explanation of failure" }



Requests to the REST API must use UTF-8 encoding for the request URL and any optional query parameters (GET only).

The following headers must be present in all requests to the REST API:

Header Required Value
Authorization Yes Basic authentication credentials of an active codeBeamer user for request authentication and authorization
Basic authorization method should be UTF-8 encoded:
https://tools.ietf.org/id/draft-reschke-basicauth-enc-00.html#examples
Accept Yes Client must accept response with content type "application/json"
Accept-Language Yes Comma-separated list of the preferred client languages/locales.
If none of these languages is supported, the response will be in English ("en_US")



The optional request body (POST/PUT only), can be either

  • singlepart, with "Content-type: application/json; charset=utf-8"
  • multipart, with "Content-type: multipart/mixed" or "Content-type: multipart/form-data"
    • where the first/root part must contain the resource specification and be marked as
      • Content-Disposition: form-data; name="body"
      • Content-type: application/json; charset=utf-8
    • all other parts represent attachments (file uploads) to the resource and may contain content of arbitrary type.


Responses from the REST API will always have "Content-type: application/json; charset=utf-8".

Data description

In the REST API, resources are represented as JSON objects and described by a JSON Schema.

E.g. English /user/schema

{
  "title" : "User",
  "plural" : "Accounts",
  "type" : "object",
  "properties" : {
    "uri" : {
      "title" : "URI",
      "type" : "string",
      "format" : "uri"
    },
    "name" : {
      "title" : "User Name",
      "type" : "string",
      "maxLength" : 40
    },
    "title" : {
      "title" : "Title",
      "type" : "string",
      "maxLength" : 10
    },
    "firstName" : {
      "title" : "First Name",
      "type" : "string",
      "maxLength" : 100
    },
    "lastName" : {
      "title" : "Last Name",
      "type" : "string",
      "maxLength" : 150
    },
    "company" : {
      "title" : "Company",
      "type" : "string",
      "maxLength" : 255
    },
    "address" : {
      "title" : "Address",
      "type" : "string",
      "maxLength" : 255
    },
    "zip" : {
      "title" : "Zip/Postal Code",
      "type" : "string",
      "maxLength" : 15
    },
    "city" : {
      "title" : "City",
      "type" : "string",
      "maxLength" : 255
    },
    "state" : {
      "title" : "State/Province",
      "type" : "string",
      "maxLength" : 50
    },
    "country" : {
      "title" : "Country",
      "type" : "string",
      "format" : "ISO 3166",
      "maxLength" : 2
    },
    "dateFormat" : {
      "title" : "Date Format",
      "type" : "string",
      "maxLength" : 255
    },
    "timeZone" : {
      "title" : "Time zone",
      "type" : "string",
      "maxLength" : 255
    },
    "language" : {
      "title" : "Language",
      "type" : "string",
      "format" : "ISO 639",
      "maxLength" : 2
    },
    "email" : {
      "title" : "Email",
      "type" : "string",
      "format" : "email",
      "maxLength" : 255
    },
    "phone" : {
      "title" : "Phone",
      "type" : "string",
      "maxLength" : 255
    },
    "mobile" : {
      "title" : "Mobile/IP Voice",
      "type" : "string",
      "maxLength" : 255
    },
    "skills" : {
      "title" : "Skills",
      "type" : "string",
      "maxLength" : 4000
    },
    "registryDate" : {
      "title" : "Registered",
      "type" : "string",
      "format" : "date-time"
    },
    "status" : {
      "title" : "Status",
      "enum" : [ "In activation", "Activated", "Disabled" ]
    }
  },
  "required" : [ "name", "firstName", "lastName", "email" ]
}


It is important to understand, that schemas and data are not the raw codeBeamer schema/data objects, but user and language specific views on the underlying codeBeamer schema/data objects. You can therefore apply a schema only on data that you retrieved for the same user and language.

The codeBeamer data model is also customizable and extensible, therefore you must not rely on (example) schemas shown here or elsewhere, but always get the schema applicable to your client from the REST API of your target server !

For the same reason, the caching of schemas in the client is not recommendable, except you can be sure, that the underlying model won't change, or you will be notified about such changes in some way outside the scope of this document.

The codeBeamer REST API uses some non-standard extensions to JSON Schema:

  • Date and Timestamp properties are declared as
     { "type" : "string", "format" : "date-time" } 
    , where the string value is an ISO 8601 encoded timestamp.
  • Language properties are declared as
     { "type" : "string", "format" : "ISO 639", "maxLength" : 2 } 
    , where the value is an ISO 639 2-letter language code.
  • Country properties are declared as
     { "type" : "string", "format" : "ISO 3166", "maxLength" : 2 } 
    , where the value is an ISO 3166 2-letter country code.
  • Wiki Text properties are declared as
     { "type" : "string", "format" : "Wiki" } 
    , where the value is a String, that may contain codeBeamer Wiki markup.

In addition to the standard "title" and "description", a schema can also have an optional "plural"property, that defines the plural form of the "title".

The schemas of Tracker/CMDB item reference or member fields, that represent choices from a dynamic set of options, that themselves are other resources, cannot declare the field to be an "enum", because the possible choice option set is dynamic and typically huge.

Therefore, reference fields are declared to contain a resource reference (see next section "Data interchange" for an explanation) or an array of resource references (if multiple selection is allowed), and contain an extra "optionsURI" property, which allows a client to retrieve the possible property values when needed.

E.g. The "possibleReleases" of a Test Set:

{
   "type" : "array",
   "items" : {
       "title" : "Item",
       "plural" : "Items",
       "type" : "object",
       "properties" : {
            "uri" : {
                "title" : "URI",
                "type" : "string",
                "format" : "uri"
            },
            "name" : {
                "title" : "Name",
                "type" : "string"
            }
       }
   },
   "uniqueItems" : true,
   "optionsURI" : "/tracker/1028/field/1000/options"
}


A client can then get the possible property values (optionally only options containing a filter string) via:

GET {RestURL}{optionsURI}[?filter=string] 

Tracker/CMDB item fields, whose value depends on the value of other fields (see Dynamic pick-list fields), also have an additional "dependsOn" property, that lists the names of the fields, this field's value depends upon.

e.g. the Country/Language example from Dynamic pick-list fields:

    ...
    "country" : {
      "title" : "Country",
      "type" : "string",
      "format" : "ISO 3166",
      "maxLength" : 2
    },
    "language" : {
      "title" : "Language",
      "type" : "array",
      "items" : {
        "type" : "string",
        "format" : "ISO 639",
        "maxLength" : 2
      },
      "dependsOn" : [ "country" ],
      "optionsURI" : "/tracker/11164/field/10005/options"
    },
    ...

To get the possible/allowed values for a field, whose value depends on the values of other fields, you must POST to the specified optionsURI

POST {RestURL}{optionsURI} 

and provide the values of all fields listed in "dependsOn" in the request body.

E.g. to find the possible languages for country Switzerland:

{
   "country" : "CH"
}

would return:

[ "de", "en", "it", "fr" ]

Again, caching the result of an options query is not recommendable!

Data interchange

Data is passed to and returned from the REST API in form of JSON objects or arrays of objects.

Please note, that an object is a sparse set of properties (name/value pairs), meaning that properties that don't have an actual value need not exist in the object, in order to keep the size of objects minimal.

When creating new objects, you must pass values for required properties (according to schema) and should otherwise only pass properties whose value is not null.

E.g. Create a new user:

{
  "name"     : "TestUser",
  "password" : "TestPassword",
  "firstName": "Test",
  "lastName" : "User",
  "company"  : "Intland",
  "address"  : "Gropiusplatz 10",
  "zip"      : "70563",
  "city"     : "Stuttgart",
  "country"  : "DE",
  "language" : "de",
  "email"    : "TestUser@intland.com",
  "status"   : "Activated"
}


When updating objects, you should only pass the object's URI and those properties you intend to update.
In order to clear properties upon update, you must pass the properties with value null.

E.g. To deactivate a user (change it's status), you only need to pass:

{
  "uri"    : "/user/TestUser",
  "status" : "Disabled"
}


You can use any valid form of a resource URI to refer to an resource in data you send to the REST API, but in data returned from the REST API, resources will always be identified with the primary resource URI, which is based on the immutable unique resource ID, e.g. "/user/1".

Because these numeric URIs are not very self-descriptive, the URI is packed into a resource reference object, together with the human readable (and localized) resource name:

{
  "uri"  : "/user/2",
  "name" : "TestUser"
}


Wherever you have to pass resource references, that are formally declared to be objects with an "uri" and "name", you can always simply pass the URI value instead.

E.g. property "assignedTo", declared to be an array of User or Role references, can be passed as

{
  "assignedTo" : [{
      "uri" : "/user/1",
      "name" : "bond"
   }, {
      "uri" : "/role/1",
      "name" : "Project Admin"
   }]
}

or simply

{
  "assignedTo" : ["/user/1", "/role/1"]
}

you can also use any valid form of resource URI:

{
  "assignedTo" : ["/user/bond", "/role/Project Admin"]
}


When passing a single value for a property, that is formally declared to be an array, e.g.

{
  "assignedTo" : ["/user/bond"]
}

you can also simply pass the single value without enclosing it into an array:

{
  "assignedTo" : "/user/bond"
}



System

Get server version

GET /version

The response body contains the version String, e.g. "7.7.0".


Get server time

GET /time

The response contains the server time as a formatted String and as milliseconds since "1970-01-01T00:00:00+00:00".

{
  "date" : "2015-04-23T13:28:50+02:00",
  "millis" : 1429788530398
}

Users and User Groups

Users have URIs of the form: "/user/{id}" or "/user/{name}", where {id} is the internal unique user id/number and {name} is the unique user name.

There is also the special URI "/user/self", that allows to refer to the user passed in the "Authorization" request header.

User Groups have URIs of the form: "/user/group/{id}" or "/user/group/{name}", where {id} is the internal unique group id/number and {name} is the unique group name.

Please note: The user or group name can be changed, so URIs based on the name are not guaranteed to always identify the same/identical resource, whereas URIs based on the immutable id do.

Get user schema

GET /user/schema

Create a new user

POST /user

The request body must contain a valid user object with all required properties.


Update an existing user

PUT /user

The request body must contain a user object with the "uri" and the properties to update.


Get information about an existing user

GET {userURI} 

Get list of users

GET /users/page/{page}[?query]

Returns the specified page of all users (matching the specified filter).


Parameter Type Required Meaning
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.
filter String No If present: Only return users whose data contains this String


Example:

GET https://hostname/cb/rest/users/page/1?pagesize=50&filter=Intland 

Get the user license schema

GET /user/license/schema

Get the available user licenses

GET /user/licenses

These are the licenses installed on the system. You cannot install a codeBeamer license via the REST API, only associated users with licenses.


Get the licenses assigned to a specific user

GET {userURI}/licenses

Set the licenses assigned to a specific user

PUT {userURI}/licenses

E.g.:

{
  "ALM" : "USER_WITH_FLOATING_LICENSE",
  "RM"  : "USER_WITH_NAMED_LICENSE
}

Get the user permission schema

GET /user/permission/schema

Get all available user permissions

GET /user/permissions

You cannot create, update or delete user permissions, only assign permissions to user groups.


Get the permissions of a specific user

GET {userURI}/permissions

You cannot directly assign permissions to users. You can only assign permissions to user groups and then make users group members.


Get the user group schema

GET /user/group/schema

Get the defined user groups

GET /user/groups

Create a new user group

POST /user/group

The request body must contain a valid user group object with all required properties, e.g.:

{
  "name"        : "REST API Users",
  "description" : "All users that are allowed to use the REST API",
  "permissions" : ["Own Account - Admin", "Account - View Address"]
}

You can pass permissions as full permission objects, per permission name (see above) or even simpler per permission id, e.g

"permissions" : [2, 8]

Update an existing user group

PUT /user/group

The request body must contain a user group object with the "uri" and the properties to update, e.g.:

{
  "uri" : "/user/group/REST API Users",
  "permissions" : [1, 2, 4, 8, 16]
}

Delete a user group

DELETE {groupURI} 

Get information about a user group

GET {groupURI} 

Get the group change history

GET {groupURI}/history 

Get all current members of a user group

GET {groupURI}/members 

Set the members of a user group

PUT {groupURI}/members 

The request body must contain an array of user objects who should be the exclusive members of this group (User URIs are sufficient). E.g.:

[ "/user/bond", "/user/TestUser" ]

Get the group members history schema

GET /user/group/members/history/schema 

Get the members history of a user group

GET {groupURI}/members/history 

Get the groups where a specific user currently is a member

GET {userURI}/groups

Get the group membership history of a specific user

GET {userURI}/groups/history

Set the groups where a specific user is a member

PUT {userURI}/groups

The request body must contain an array of user groups (group URI only is sufficient), e.g.:

[ "/user/group/1001", "/user/group/External" ]

Make a user a member of a group

PUT {userURI}{groupURI} 
PUT {groupURI}{userURI} 

The request body is optional and can contain a single comment string. E.g.:

 "Why it was necessary to add this user to this group" 

Remove a user from a group

DELETE {userURI}{groupURI} 
DELETE {groupURI}{userURI} 

The request body is optional and can contain a single comment string. E.g.:

 "It was necessary to remove this user from this group, because ..." 

Get the membership history of a specific user for a specific group

GET {userURI}{groupURI}/history
GET {groupURI}{userURI}/history

Get the photo of a specific user

GET {userURI}/photo

Caution!

This request will not return a JSON body, but the JPEG user image data "Content-type: image/jpeg".

Set the photo of a specific user

PUT {userURI}/photo

Caution!

The request body must not contain JSON, but image data "Content-type: image/*".

Remove the photo of a specific user

DELETE {userURI}/photo

Roles

Roles are stereotypes for project roles. You must first define the role stereotype, before you can instantiate a role in project.
Roles have URIs of the form: "/role/{id}" or "/role/{name}", where {id} is the internal unique role id/number and {name} is the unique role name.

Get the role schema

GET /role/schema

Get all defined role stereotypes

GET /roles


Define a new role stereotype

POST /role

The request body must contain a valid role object with a unique name and an optional description, e.g.:

{
  "name"        : "Tester",
  "description" : "Testers of the REST API"
}

Update the description of a role stereotype

PUT /role

The request body must contain the role URI and the new role description, e.g.:

{
  "uri"         : "/role/Tester",
  "description" : "Testers of the REST API"
}

Please note: The name of role stereotypes cannot be changed.


Delete an unused role stereotype

DELETE {roleURI} 

Please note: You can only delete role stereotypes, as long as no project roles with this stereotyp exist.


Get a role stereotype definition

GET {roleURI} 

Projects

Projects have URIs of the form: "/project/{id}" or "/project/{name}", where {id} is the internal unique project id/number and {name} is the unique project name.

Please note: The project name can be changed, so URIs based on the name are not guaranteed to always identify the same/identical project, whereas URIs based on the immutable id do.

Project roles are instantiations of role stereotypes. The URI of project roles is the combination of the project URI and the role (stereotype) URI: {projectURI}{roleURI}

Get the project schema

GET /project/schema

Create a new project

POST /project

The request body must contain a valid project object with all required properties, e.g.:

{
  "name"        : "REST API Test",
  "description" : "A sample project to test and demonstrate the __REST API__",
  "descFormat"  : "Wiki",
  "category"    : "Education"
}

Create a new project as a clone of another project

POST {projectURI}/clone

The request body must contain a valid project, same as above, but the new project will use the specified project as template and inherit the roles, members, trackers and CMDB categories.


Update a project definition

PUT /project

The request body must contain the project URI and the properties to update, e.g.:

{
  "uri"                 : "/project/1",
  "propagation"         : "Public with join approval",
  "defaultMemberRoleId" : 2
}

The "defaultMemberRoleId" must be the role stereotype id of a defined project role, therefore you cannot set this property initially upon project creation !


Close/Re-Open a project

PUT /project

The request body must contain the project URI and the properties to update, e.g.:

{
  "uri"    : "/project/1",
  "closed" : true
}

To re-open a previously closed project, set "closed" to false.


Remove/Restore a project

PUT /project

The request body must contain the project URI and the properties to update, e.g.:

{
  "uri"     : "/project/1",
  "deleted" : true
}

To restore a previously removed project, set "deleted" to false.


Delete a project

DELETE {projectURI} 

Please note: Deleting a project is irreversible.


Get a project definition

GET {projectURI} 

Get the project definition change history

GET {projectURI}/history 

Get list of projects

GET /projects/page/{page}[?query]

Returns the specified page of all projects (visible to the current user and matching the specified filter).


Parameter Type Required Meaning
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of projects, valid range is [1 .. 500]. Default is 100.
category String No If present: Only return projects with this category
filter String No If present: Only return projects whose data contains this String


Example:

GET https://hostname/cb/rest/projects/page/1?pagesize=50&category=Education 

Get all available project permissions

GET /project/permissions

You cannot create, update or delete project permissions, only assign permissions to project roles.


Get a project permission definition

GET /project/permission/{permissionIdOrName} 

Get the project role schema

GET /project/role/schema

Define a new project role (instantiate a role stereotype on a project)

POST {projectURI}{roleURI} 

The request body must contain a non empty array of project permissions to grant to the new project role (passing the permission id or name is sufficient), e.g.:

  [ "Wiki Space - View", "Document - View", "Tracker - View", "CMDB - View" ]

Caution: The new role will not have any permissions on existing project artifacts (documents, trackers, etc.), therefore you should use the clone method (below) !


Create a new project role based on an existing (template) role

POST {projectURI}{roleURI}/clone/{roleIdOrName} 

The request body must contain a non empty array of project permissions to grant to the new project role (passing the permission id or name is sufficient), e.g.:

  [ "Wiki Space - View", "Document - View", "Tracker - View", "CMDB - View" ]

The new role will have the same permissions on existing project artifacts (documents, trackers, etc.) as the template role.


E.g. Create the project role "Tester" based on the predefined "Developer" role:

POST https://hostname/cb/rest/project/1/role/Developer/clone/Tester

Change the permissions granted to a roject role

PUT {projectURI}{roleURI} 

The request body must contain a non empty array of the project permissions assigned to the role, e.g.:

  [ "Wiki Space - View", "Document - View", "Tracker - View", "CMDB - View", "SCM - View", "Members - View" ] 

Delete a project role

DELETE {projectURI}{roleURI} 

Get a project role definition

GET {projectURI}{roleURI} 

Get the change history of a project role

GET {projectURI}{roleURI}/history 

Get a list of all roles defined in a project

GET {projectURI}/roles 

Get a list of all roles defined in a project plus all current role members

GET {projectURI}/roles/members[?query]
Parameter Type Required Meaning
status String No One of {"Any", "Submitted", "Rejected", "Active", "Resigned", } to only show project role members with this status. Default is currently "Active" members.

Get a list of all roles defined in a project plus all current/former role members

GET {projectURI}/roles/members/history

Get a list of all members currently assigned to a specific project role

GET {projectURI}{roleURI}/members[?query]
Parameter Type Required Meaning
status String No One of {"Any", "Submitted", "Rejected", "Active", "Resigned", } to only show project role members with this status. Default is currently "Active" members.

Get the members history of a project role

GET {projectURI}{roleURI}/members/history 

Set all (current) members of a project role

PUT {projectURI}{roleURI}/members 

The request body must contain an array of role members. Members can be users and/or user groups, e.g.:

  [ "/user/TestUser", "/user/group/REST API Users" ] 

Get a page of all users assigned to a project role

GET {projectURI}{roleURI}/users/page/{page} 
Parameter Type Required Meaning
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of projects, valid range is [1 .. 500]. Default is 100.


Returns the requested page of all users, that are either directly or indirectly members of the specified project role.
Indirectly means, the user is member of a user group and that user group is member of the project role.

Grant a project role to a user

PUT {projectURI}{roleURI}{userURI} 
PUT {projectURI}{userURI}{roleURI} 
PUT {userURI}{projectURI}{roleURI} 

The request body is optional and can contain a single comment string. E.g.:

 "Why it was necessary to grant this role to this user" 

Revoke a project role from a user

DELETE {projectURI}{roleURI}{userURI} 
DELETE {projectURI}{userURI}{roleURI} 
DELETE {userURI}{projectURI}{roleURI} 

The request body is optional and can contain a single comment string. E.g.:

 "Why it was necessary to revoke this role from this user" 

Get the membership history of a specific user in a specific project role

GET {projectURI}{roleURI}{userURI}/history 
GET {projectURI}{userURI}{roleURI}/history 
GET {userURI}{projectURI}{roleURI}/history 

The result schema is /project/role/history/schema.


Get all roles of a specific project where a user is currently a (direct) member

GET {projectURI}{userURI}/roles[?direct=true] 
GET {userURI}{projectURI}/roles[?direct=true] 

Get the history of all direct project roles a user has or had in a specific project

GET {projectURI}{userURI}/roles/history 
GET {userURI}{projectURI}/roles/history 

Get all projects and roles where a user is currently a (direct) member

GET {userURI}/projects/roles[?direct=true] 

Get the history of all projects and roles where a user is or was a direct member

GET {userURI}/projects/roles/history 

Get all projects visible to a user and the effective project permissions per project

GET {userURI}/projects/permissions 

Get the effecitve project permissions of a user for a specific project

GET {userURI}{projectURI}/permissions 
GET {projectURI}{userURI}/permissions 

Get a page of all projects accessible to a user

GET {userURI}/projects/page/{page}[?query]
Parameter Type Required Meaning
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of projects, valid range is [1 .. 500]. Default is 100.
deleted boolean No If true, also show removed projects. Default is false.

Returns the requested page of projects accessible to a user.

Get a page of all projects where a user has a specific permission

GET {userURI}/projects/permission/{permissionIdOrName}/page/{page}[?query]
Parameter Type Required Meaning
permissionIdOrName String Yes Id or name of a project permission
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of projects, valid range is [1 .. 500]. Default is 100.
deleted boolean No If true, also show removed projects. Default is false.

Returns the requested page of projects, where the user has the requested permission.

E.g. Find first page of projects, where the /user/bond is project administrator:

GET https://hostname/cb/rest/user/bond/projects/permission/Project - Admin/page/1 

Grant a project role to a user group

PUT {projectURI}{roleURI}/group/{groupIdOrName} 
PUT {projectURI}/group/{groupIdOrName}/{roleURI} 
PUT {groupURI}{projectURI}{roleURI} 

The request body is optional and can contain a single comment string. E.g.:

 "Why it was necessary to grant this role to this user group" 

Revoke a project role from a user group

DELETE {projectURI}{roleURI}/group/{groupIdOrName} 
DELETE {projectURI}/group/{groupIdOrName}/{roleURI} 
DELETE {groupURI}{projectURI}{roleURI} 

The request body is optional and can contain a single comment string. E.g.:

 "Why it was necessary to revoke this role from this user group" 

Get the membership history of a specific user group in a specific project role

GET {projectURI}{roleURI}/group/{groupIdOrName}/history 
GET {projectURI}/group/{groupIdOrName}{roleURI}/history 
GET {groupURI}{projectURI}{roleURI}/history 

The result schema is /project/role/history/schema.


Get all roles of a specific project where a user group is currently a member

GET {projectURI}/group/{groupIdOrName}/roles 
GET {groupURI}{projectURI}/roles 

Get the history of all project roles a user group has or had in a specific project

GET {projectURI}/group/{groupIdOrName}/roles/history 
GET {groupURI}{projectURI}/roles/history 

Get all projects and roles where a user group currently is a member

GET {groupURI}/projects/roles 

Get the history of all projects and roles where a user group is or was a direct member

GET {groupURI}/projects/roles/history 

Get all projects visible to a user group and the effective project permissions per project

GET {groupURI}/projects/permissions 

Get the effecitve project permissions of a user group for a specific project

GET {groupURI}{projectURI}/permissions 
GET {projectURI}/group/{groupIdOrName}/permissions 

Documents (Directories/Folders, Files)

Starting with CB-7.4, you can also manage project specific documents via the REST-API.
Each project has a virtual file system, where you can upload files and organize them in folders/directories.
You can also add arbitrary meta-data to files (and directories/folders) and control read/write access based on project roles.

Files have URIs of the form: "/file/{id}" or "{projectURI}/file/{path}", where {id} is the internal unique file id/number and {path} is the relative file path, which is only unique within a project.

Directories/Folders have URIs of the form: "/dir/{id}" or "{projectURI}/dir/{path}", where {id} is the internal unique directory/folder id/number and {path} is the relative directory/folder path, which is only unique within a project.

Get the directory/folder schema

GET /dir/schema

You can extend the basic directory/folder schema by specifying additional meta-data properties (see Entity Metadata). Such declared properties will also be visible at the codeBeamer Web-GUI.

But it is also possible to set additional/undeclared meta-data/properties for a directory/folder. Such properties are only visible for that directory/folder, where they are defined.


Create a new directory/folder

As long as there is no need to set specific meta-data or permissions on directories/folders, you can simply upload, move or copy files by specifying the directory/folder via a "path" (in conjunction with the parameter createIfNecessary=true). This will automatically create any missing directories/folders in that path.

POST /dir

The request body must contain a valid directory/folder specification with at least "project" and "name". You can create sub-directories/folders by additionally specifying either the parent "directory" URI or the relative parent "path". If you do neither specify "directory" nor "path", the new directory will be a top-level directory/folder in the specified project:

{
  "project"             : "/project/Test",
  "name"                : "images",
  "description"         : "A folder for images/pictures",
  "descFormat"          : "Plain"
}

Update directory/folder settings

PUT /dir

The request body must contain the directory/folder URI and the properties to update, e.g. to change the folder's "description":

{
  "uri"         : "/project/Test/dir/images",
  "description" : "A folder __only__ for images/pictures",
  "descFormat"  : "Wiki"
}

You can only change "name", "description", "status" and custom meta-data/properties of a directory/folder.

To move a directory/folder to another project or location, you must use the moveTo command (see below).


Move a directory/folder to another project or location

PUT /dir/{id}/moveTo/{projectURI}[?options]
PUT /dir/{id}/moveTo/{directoryURI}[?options] 
Option Type Required Meaning
createIfNecessary boolean No Should non-existing directories/folders in the specified relative target directory URI ("{projectURI}/file/{path}") be automatically created ? Default is false.
overwrite boolean No If true, existing directories/folders/files at the specified target location will be overwritten by moved directories/folders/files with the same name. Default is false, which will abort the move, if there already exist directories/folders/files with the same name at the destination.

Copy a directory/folder (including content) to another project or location

POST /dir/{id}/copyTo/{projectURI}[?options]
POST /dir/{id}/copyTo/{directoryURI}[?options] 
Option Type Required Meaning
createIfNecessary boolean No Should non-existing directories/folders in the specified relative target directory URI ("{projectURI}/file/{path}") be automatically created ? Default is false.
overwrite boolean No If true, existing directories/folders/files at the specified destination will be overwritten by copied directories/folders/files with the same name. Default is false, which will only copy files and sub-directories/folders from the source directory/folder, if there do not already exist directories/folders/files with the same name at the destination.

This will also copy all files and sub-directories/folders in that directory/folder recursively !

Delete a directory/folder

DELETE {directoryURI} 

This will also delete all files and sub-directories/folders in that directory/folder recursively !


Get the meta-data/properties of a specific directory/folder

GET {directoryURI} 

Get the change history of a directory/folder

GET /dir/{id}/history 

This returns the change history of the specified directory/folder's meta-data/properties in descending order (last/head) revision first.

Changes of directory/folder content will not be visible in this history.


Get the meta-data/properties of a specific directory/folder revision

GET /dir/{id}/version/{version} 

List the top-level directories/folders and files of a project

GET {projectURI}/documents/page/{page}[?query]
Parameter Type Required Meaning
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.

E.g. List the top-level documents of the Test project:

GET https://hostname/cb/rest/project/Test/documents/page/1 
{
  "page" : 1,
  "size" : 100,
  "total" : 1,
  "documents" : [ {
    "uri" : "/dir/3621",
    "name" : "images",
    "description" : "A folder __only__ for images/pictures",
    "descFormat" : "Wiki",
    "version" : 1,
    "createdAt" : "2014-05-30T10:57:32+02:00",
    "owner" : {
      "uri" : "/user/1",
      "name" : "bond"
    },
    "lastModifiedAt" : "2014-05-30T10:57:32+02:00",
    "lastModifiedBy" : {
      "uri" : "/user/1",
      "name" : "bond"
    }
  } ]
}

List the contents (files and sub-directories/folders) of a directory/folder

GET /dir/{id}/page/{page}[?query]
Parameter Type Required Meaning
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.

Get the permissions of a directory/folder

GET /dir/{id}/permissions 

E.g. Get the access permissions of our "images" folder created above:

GET https://hostname/cb/rest/dir/3621/permissions 
[ {
  "role" : {
    "id" : 2,
    "name" : "Developer"
  },
  "access" : 1
}, {
  "field" : {
    "id" : 6,
    "name" : "Owner"
  },
  "access" : 3
}, {
  "role" : {
    "id" : 1,
    "name" : "Project Admin"
  },
  "access" : 3
}, {
  "role" : {
    "id" : 3,
    "name" : "Stakeholder"
  },
  "access" : 1
}, {
  "role" : {
    "id" : 4,
    "name" : "Test Engineer"
  },
  "access" : 1
}, {
  "role" : {
    "id" : 5,
    "name" : "Tester"
  },
  "access" : 1
} ]

Access can be granted to project roles or to the directory/folder owner ("field" : { "id" : 6, "name" : "Owner" } ).

Access can be 1=read, 2=write and 3=read/write.

The list will only contain the owner and those roles, that actually have permission.


Set the permissions of a directory/folder

PUT /dir/{id}/permissions[?options] 
Option Type Required Meaning
recursive boolean No Should the same permissions also recursively be applied to all directories/folders/files in that directory/folder? Default is false.

You can grant access to

  • the directory/folder owner: "field" : { "id" : 6, "name" : "Owner" }
  • any defined project role: GET {projectURI}/roles

Access can be 1=read, 2=write and 3=read/write.

Render Wiki markup to HTML in the context of the specified directory/folder

POST /dir/{id}/wiki2html 

Since CB-7.7.1.

The request body contains the Wiki markup to render.

The response body contains the rendered text/html.


Get the file schema

GET /file/schema

You can extend the basic file schema by specifying additional meta-data properties (see Entity Metadata). Such declared properties will also be visible at the codeBeamer Web-GUI.

But it is also possible to set additional/undeclared meta-data/properties for a file. Such properties are only visible for that file, where they are defined.


Upload a new file

As long as there is no need to set specific meta-data or permissions on directories/folders, you can simply upload, move or copy files by specifying the directory/folder via a "path" (in conjunction with the parameter createIfNecessary=true). This will automatically create any missing directories/folders in that path.

POST /file

A file upload must be a multipart request:

  • The file meta-data must be in the part named "body"
  • The file content/data must be in an additional part.


The meta-data must contain at least "project" and "name". You can upload files into directories/folders by additionally specifying either the "directory" URI or the relative directory "path".
If you do neither specify "directory" nor "path", the new file will be uploaded to the top-level of the specified project.

For example: Upload the file "cube.png" into the previously created "images" folder of the "Test" project, with additional/undeclared attributes ("camera", "aperture" and "exposition"):

POST https://hostname/cb/rest/file
Authorization: (Data not shown)
Accept: application/json
Accept-Language: en
Content-Type: multipart/form-data; boundary=--MULTIPART-BOUNDARY--
Content-Length: 29278

----MULTIPART-BOUNDARY--
Content-Disposition: form-data; name="body"
Content-type: application/json; charset=utf-8

{
  "project"     : "/project/Test",
  "path"        : "images",
  "name"        : "cube.png",
  "description" : "A file to test uploading/downloading files via Rest-Api",
  "status"      : "Draft",
  "camera"      : "Nikon P330",
  "aperture"    : "F1.8",
  "exposition"  : "Bright"
}
----MULTIPART-BOUNDARY--
Content-Disposition: form-data; name="cube.png"; filename="cube.png"
Content-Type: image/png

(Binary data not shown)
----MULTIPART-BOUNDARY----


The directory, where to store the file, is specified in this example via "path" : "images".
We could have also specified the directory as "directory" : "/dir/3621" or "directory" : "/project/Test/dir/images", but then this directory must already exist.

Update file meta-data and/or content

PUT /file

To only update file meta-data, a single-part request is sufficient, that only needs to contain the file URI and those meta-data/properties to update:

{
  "uri"    : "/project/Test/file/images/cube.png",
  "status" : "Review"
}

To update file content, you need a multipart request, where the file URI and the meta-data/properties to update go into the "body" part, and the file content to update is added as an extra part:

PUT https://hostname/cb/rest/file
Authorization: (Data not shown)
Accept: application/json
Accept-Language: en
Content-Type: multipart/form-data; boundary=--MULTIPART-BOUNDARY--
Content-Length: 29278

----MULTIPART-BOUNDARY--
Content-Disposition: form-data; name="body"
Content-type: application/json; charset=utf-8

{
  "uri"         : "/file/3622",
  "status"   	: "Final"
  "aperture"    : "F3.2",
  "exposition"  : "Normal"
}
----MULTIPART-BOUNDARY--
Content-Disposition: form-data; name="cube.png"; filename="cube.png"
Content-Type: image/png

(Binary data not shown)
----MULTIPART-BOUNDARY----

You can only change "name", "description", "status" and custom meta-data/properties of a file.
To move a file to another project or location, you must use the moveTo command (see below).

Move a file to another project or location

PUT /file/{id}/moveTo/{projectURI}[?options]
PUT /file/{id}/moveTo/{directoryURI}[?options] 
Option Type Required Meaning
createIfNecessary boolean No Should non-existing directories/folders in the specified relative target directory URI ("{projectURI}/file/{path}") be automatically created ? Default is false.
overwrite boolean No If true, an existing file with the same name at the destination (if any) will be overwritten. Default is false, which will abort the move, if there already exist a file with the same name at the destination.

Copy a file to another project or location

POST /file/{id}/copyTo/{projectURI}[?options]
POST /file/{id}/copyTo/{directoryURI}[?options] 
Option Type Required Meaning
createIfNecessary boolean No Should non-existing directories/folders in the specified relative target directory URI ("{projectURI}/file/{path}") be automatically created ? Default is false.
overwrite boolean No If true, an existing file with the same name at the destination (if any) will be overwritten. Default is false, which will abort the copy, if there already exist a file with the same name at the destination.

Delete a file

DELETE {fileURI} 

Get the meta-data/properties of a specific file

GET {fileURI} 

Download the content/data of a specific file

GET {fileURI}/content 

Get the change history of a file

GET /file/{id}/history 

This returns the change history of the specified file's meta-data/properties and content in descending order (last/head) revision first.


Get the meta-data/properties of a specific file revision

GET /file/{id}/version/{version} 

Download the content/data of a specific file revision

GET /file/{id}/version/{version}/content 
Please note that in case of retrieveing .wki files:
GET /file/{wikinote-id}/version/{version}/content/?raw=true 

Restore a previous version of a file

PUT /file/{id}/version/{version}/restore 

Get the permissions of a file

GET /file/{id}/permissions 

Similar to directory/folder permissions.


Set the permissions of a file

PUT /file/{id}/permissions[?options] 

Similar to directory/folder permissions.


Get the download statistics about a file

GET /file/{id}/accessStats 

Get the download log of a file

GET /file/{id}/accessLog/page/{pageNo}[?query] 
Parameter Type Required Meaning
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.
newerThen String No A timestamp, to only return log entries for downloads after this date and time.
You can specify a relative timestamp as "[{This | Last [n]}] [{minute | hour | day | week | month | quarter | year}[s]]", where "Today" is a synonym for "This day" and "Yesterday" is a synonym for "Last day", e.g. "Last week", "This month", "Last 2 days"; or as "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".
An absolute timestamp is specified in ISO 8601 format, e.g. "2013-03-12T14:38:06+01:00".
olderThen String No A timestamp, to only return log entries for downloads before this date and time.
You can specify a relative timestamp as "[{This | Last [n]}] [{minute | hour | day | week | month | quarter | year}[s]]", where "Today" is a synonym for "This day" and "Yesterday" is a synonym for "Last day", e.g. "Last week", "This month", "Last 2 days"; or as "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".
An absolute timestamp is specified in ISO 8601 format, e.g. "2013-03-12T14:38:06+01:00".

Check if a file is locked (temporarily)

GET /file/{id}/lock 

E.g.

{
  "lockedBy" : {
    "uri" : "/user/1",
    "name" : "bond"
  },
  "temporary" : false
}

Lock a file (temporarily)

PUT /file/{id}/lock 

The request body must contain a JSON string, that defines whether to lock

  • indefinitely: "hard"
  • or temporarily, for: "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".

Unlock a file

DELETE /file/{id}/lock 

Render Wiki markup to HTML in the context of the specified file

POST /file/{id}/wiki2html 

Since CB-7.7.1.

The request body contains the Wiki markup to render.

The response body contains the rendered text/html.


Wiki Pages

Starting with CB-7.4, you can also manage wiki pages via the REST-API.

Each codeBeamer project also has a Wiki, which is a tree of wiki pages, where the root page is the project's home page: "{projectURI}/wikipage".

You can add, update, move and delete pages to and from a project's wiki, but you cannot delete or move the project home page itself (only update is allowed).

Wiki pages have URIs of the form: "/wikipage/{id}" or "{projectURI}/wikipage/{name}", where {id} is the internal unique wiki page id/number and {name} is the wiki page name, which is only unique within a project.

The content of a wiki page is defined via Wiki markup. You can embed images into a wiki page via special markup, where the image can bei either a file or an attachment to the wiki page.

Get the wiki page schema

GET /wikipage/schema

You can extend the basic wiki page schema by specifying additional meta-data properties (see Entity Metadata). Such declared properties will also be visible at the codeBeamer Web-GUI.

But it is also possible to set additional/undeclared meta-data/properties for a wiki page. Such properties are only visible for that page, where they are defined.


Create a new wiki page

POST /wikipage

To create a wikipage with attachments, you need a multipart request:

  • The wiki page definition must be in the part named "body"
  • Each attachment must be an additional part.

The meta-data must contain at least "project", "parent", "name" and "markup", where the name must be unique within the specified project.

For example: Create a new wiki page as child of the project's home page, with a single image attachment:

POST https://hostname/cb/rest/wikipage
Authorization: (Data not shown)
Accept: application/json
Accept-Language: en
Content-Type: multipart/form-data; boundary=--MULTIPART-BOUNDARY--
Content-Length: 29278

----MULTIPART-BOUNDARY--
Content-Disposition: form-data; name="body"
Content-type: application/json; charset=utf-8

{
  "project"     : "/project/Test",
  "parent       : "/project/Test/wikipage",
  "name"        : "Info about the Project Admin",
  "description" : "A test wikipage for Rest-Api tests",
  "markup"      : "This is a picture of the project admin: [!Bond.jpg!]"
}
----MULTIPART-BOUNDARY--
Content-Disposition: form-data; name="Bond.jpg"; filename="Bond.jpg"
Content-Type: image/jpg

(Binary data not shown)
----MULTIPART-BOUNDARY----

Update wikipage

PUT /wikipage

To only update wiki page meta-data or markup, a single-part request is sufficient. To also add or update attachments, you need a multipart request:

PUT https://hostname/cb/rest/wikipage
Authorization: (Data not shown)
Accept: application/json
Accept-Language: en
Content-Type: multipart/form-data; boundary=--MULTIPART-BOUNDARY--
Content-Length: 29278

----MULTIPART-BOUNDARY--
Content-Disposition: form-data; name="body"
Content-type: application/json; charset=utf-8

{
  "uri"    : "/project/Test/wikipage/Info about the Project Admin",
  "markup" : "This is a picture of the project admin: [!Bond.jpg!], while trying to open Pandora's box [!cube.png!]"
}
----MULTIPART-BOUNDARY--
Content-Disposition: form-data; name="cube.png"; filename="cube.png"
Content-Type: image/png

(Binary data not shown)
----MULTIPART-BOUNDARY----

You can only change "name", "description", "status", "markup" and custom meta-data/properties of a wiki page.
To move a wiki page to another project or location, you must use the moveTo command (see below).

Move a wiki page to another project or location

PUT {wikipageURI}/{id}/moveTo/{wikipageURI}[?options] 
Option Type Required Meaning
overwrite boolean No If true, an existing wiki page with the same name at the destination (if any) will be overwritten. Default is false, which will abort the move, if there already exists a wiki page with the same name at the destination.

Copy a wiki page to another project or location

POST {wikipageURI}/copyTo/{wikipageURI}[?options] 
Option Type Required Meaning
overwrite boolean No If true, an existing wiki page with the same name at the destination (if any) will be overwritten. Default is false, which will abort the copy, if there already exists a wiki page with the same name at the destination.

This will also recursively copy all child pages and attachments of this wiki page.

Delete a wiki page

DELETE {wikipageURI} 

This will also recursively delete all child pages and attachments of this wiki page.


Get the meta-data/properties of a wiki page

GET {wikipageURI} 

Get the meta-data/properties of top level wiki pages

GET {wikipageURI}/topLevelWikiPages 

Render a wiki page as HTML

GET {wikipageURI}/html 

Since CB-7.7.1. The response body contains text/html, not application/json


Render Wiki markup to HTML in the context of the specified wiki page

POST /wikipage/{id}/wiki2html 

Since CB-7.7.1.

The request body contains the Wiki markup to render.

The response body contains the rendered text/html.


Get the change history of a wiki page

GET {wikipageURI}/history 

This returns the change history of the specified wiki page's meta-data/properties in descending order (last/head) revision first.


Get the meta-data/properties of a wiki page revision

GET {wikipageURI}/version/{version} 

Render a previous version of a wiki page as HTML

GET {wikipageURI}/version/{version}/html 

Since CB-7.7.1. The response body contains text/html, not application/json


Restore a previous version of a wiki page

PUT {wikipageURI}/version/{version}/restore 

Get the permissions of a wiki page

GET {wikipageURI}/permissions 

Similar to directory/folder/file permissions.


Set the permissions of a wiki page

PUT {wikipageURI}/permissions[?options] 

Similar to directory/folder/file permissions.


Get the view statistics about a wiki page

GET {wikipageURI}/accessStats 

Get the view log of a wiki page

GET {wikipageURI}/accessLog/page/{pageNo}[?query] 
Parameter Type Required Meaning
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.
newerThen String No A timestamp, to only return log entries for downloads after this date and time.
You can specify a relative timestamp as "[{This | Last [n]}] [{minute | hour | day | week | month | quarter | year}[s]]", where "Today" is a synonym for "This day" and "Yesterday" is a synonym for "Last day", e.g. "Last week", "This month", "Last 2 days"; or as "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".
An absolute timestamp is specified in ISO 8601 format, e.g. "2013-03-12T14:38:06+01:00".
olderThen String No A timestamp, to only return log entries for downloads before this date and time.
You can specify a relative timestamp as "[{This | Last [n]}] [{minute | hour | day | week | month | quarter | year}[s]]", where "Today" is a synonym for "This day" and "Yesterday" is a synonym for "Last day", e.g. "Last week", "This month", "Last 2 days"; or as "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".
An absolute timestamp is specified in ISO 8601 format, e.g. "2013-03-12T14:38:06+01:00".

Check if a wiki page is locked (temporarily)

GET {wikipageURI}/lock 

Similar to file lock.

Lock a wiki page (temporarily)

PUT {wikipageURI}/lock 

The request body must contain a JSON string, that defines whether to lock

  • indefinitely: "hard"
  • or temporarily, for: "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".

Unlock a wiki page

DELETE {wikipageURI}/lock 

Get the child pages of a wiki page

GET {wikipageURI}/children 

Get the attachments of a wiki page

GET {wikipageURI}/attachments 

Get a wiki page attachment by name

GET {wikipageURI}/attachment/{name} 

Get the attachment schema

GET /attachment/schema

Upload a new attachment

POST //attachment

A comment is simply an attachment without content/data. To create a comment, you only need a singlepart request, where the body is the comment specification.

To upload an attachment, you need a multipart request:

  • The attachment meta-data must be in the part named "body"
  • The attachment's file/content/data must be in an additional part.


The meta-data must contain at least "parent" and "name", where parent is the URI of the wiki page, where to add the new comment or attachment.

For example: Upload the file "cube.png" into the previously created "images" folder of the "Test" project, with additional/undeclared attributes ("camera", "aperture" and "exposition"):

POST https://hostname/cb/rest/file
Authorization: (Data not shown)
Accept: application/json
Accept-Language: en
Content-Type: multipart/form-data; boundary=--MULTIPART-BOUNDARY--
Content-Length: 29278

----MULTIPART-BOUNDARY--
Content-Disposition: form-data; name="body"
Content-type: application/json; charset=utf-8

{
  "parent" : "/wikipage/3627",
  "name"   : "cube.png"
}
----MULTIPART-BOUNDARY--
Content-Disposition: form-data; name="cube.png"; filename="cube.png"
Content-Type: image/png

(Binary data not shown)
----MULTIPART-BOUNDARY----

To upload multiple wiki page attachments at once and also optionally modify the wiki page markup to embed some newly attached images, you should use the "Update wiki page" command.

Update attachment meta-data and/or content

PUT /attachment

To only update attachment meta-data, a single-part request is sufficient, that only needs to contain the attachment URI and those meta-data/properties to update.
To update attachment content, you need a multipart request, where the attachment URI and the meta-data/properties to update go into the "body" part, and the file content to update is added as an extra part:

PUT https://hostname/cb/rest/file
Authorization: (Data not shown)
Accept: application/json
Accept-Language: en
Content-Type: multipart/form-data; boundary=--MULTIPART-BOUNDARY--
Content-Length: 29278

----MULTIPART-BOUNDARY--
Content-Disposition: form-data; name="body"
Content-type: application/json; charset=utf-8

{
  "uri"    : "/attachment/3629",
  "status" : "Final"
}
----MULTIPART-BOUNDARY--
Content-Disposition: form-data; name="cube.png"; filename="cube.png"
Content-Type: image/png

(Binary data not shown)
----MULTIPART-BOUNDARY----

You can only change "name", "description", "status" and custom meta-data/properties of an attachment.
Moving or copying attachments is currently not supported.

Delete an attachment

DELETE /attachment/{id} 

Get the meta-data/properties of a specific attachment (revision)

GET /attachment/{id} 

Download the content/data of a specific attachment (revision)

GET /attachment/{id}/content 

Get the change history of an attachment

GET /attachment/{id}/history 

This returns the change history of the specified attachment's meta-data/properties and content in descending order (last/head) revision first.

Get the meta-data/properties of a specific attachment revision

GET /attachment/{id}/version/{version} 

Download the content/data of a specific attachment revision

GET /attachment/{id}/version/{version}/content 

Restore a previous version of an attachment

PUT /attachment/{id}/version/{version}/restore 


CMDB

CMDB Categories have URIs of the form: "/category/{id}" or "{projectURI}/category/{name}", where {id} is the internal unique category id/number and {name} is the category name, which is only unique within a project.

Get the category type schema

GET /category/type/schema

Get the available category types

GET /category/types

All category types are predefined. You cannot create, update or delete category types.


Get a category type definition

GET /category/type/{categoryTypeIdOrName} 

Get the immutable definition of a category type.


Get the available category permissions

GET /category/permissions

All category permissions are predefined. You cannot create, update or delete category permissions.


Get a category permission

GET /category/permission/{permissionIdOrName} 

Get the immutable definition of a category permission.


Get the category schema

GET /category/schema

Create a new category

POST /category

The request body must contain a valid category object with all required properties, e.g.:

{
  "project"     : "/project/1",
  "type"        : "/category/type/Test case",
  "name"        : "Test Cases",
  "keyName"     : "TESTCASE",
  "description" : "Test cases to validate and verify the product",
  "descFormat"  : "Plain",
  "workflow"    : true
}

Create a new category as a clone of another category

POST {categoryURI}/clone

The request body must contain a valid category object, same as above, but the new category will use the specified category as template and inherit the category schema and permissions.


Update category settings

PUT /category

The request body must contain the category URI and the properties to update, e.g. to disable the finite state machine of a category:

{
  "uri"      : "/project/1/category/Test Cases",
  "workflow" : false
}

Delete a category

DELETE {categoryURI} 

Get a category definition

GET {categoryURI} 

Get the basic item schema of a category

GET {categoryURI}/schema

Note: You cannot configure the item schema of a category via the REST API.


Get the schema of a category item property

GET {categoryURI}/field/{fieldIdOrName} 

Note: You cannot configure the schema of a category item field via the REST API.


Get all granted category permissions per role

GET {categoryURI}/roles/permissions 

Get the category permissions granted to a specific role

GET {categoryURI}{roleURI}/permissions 
GET {roleURI}{categoryURI}/permissions 

Set the category permissions for a specific role

PUT {categoryURI}{roleURI}/permissions 
PUT {roleURI}{categoryURI}/permissions 

The request body must contain an array of category permissions to grant to the role (passing the permission id or name is sufficient), e.g.:

 [ "Issue - View Any", "Issue - View Comments/Attachments" ]

Remove all category permissions for a specific role

DELETE {categoryURI}{roleURI}/permissions 
DELETE {roleURI}{categoryURI}/permissions 

Get the effective permissions of a user on a category

GET {categoryURI}{userURI}/permissions 
GET {userURI}{categoryURI}/permissions 

Get a list of all categories in a project

GET {projectURI}/categories[?query] 
Parameter Type Required Meaning
type String No Comma-separated list of category types (ids or names) to only show categories of these types
hidden boolean No True to also show hidden categories. Default is false.
deleted boolean No If true, also show removed categories. Default is false.

E.g. Show all Test Case and Test Set categories in the test project:

GET https://hostname/cb/rest/project/1/categories?type=Test Case,Test Set&hidden=true 

Get a list of all categories visible to a user (grouped by project)

GET {userURI}/categories[?query] 
Parameter Type Required Meaning
type String No Comma-separated list of category types (ids or names) to only show categories of these types
hidden boolean No True to also show hidden categories. Default is false.
deleted boolean No If true, also show removed categories. Default is false.

Get a list of all categories in a project visible to a user

GET {userURI}{projectURI}/categories[?query] 
GET {projectURI}{userURI}/categories[?query] 
Parameter Type Required Meaning
type String No Comma-separated list of category types (ids or names) to only show categories of these types
hidden boolean No True to also show hidden categories. Default is false.
deleted boolean No If true, also show removed categories. Default is false.

Get a list of all categories where a user has a specific permission (grouped by project)

GET {userURI}/categories/permission/{permissionIdOrName}[?query] 
Parameter Type Required Meaning
permissionIdOrName String Yes Id or Name of a category permission
type String No Comma-separated list of category types (ids or names) to only show categories of these types
hidden boolean No True to also show hidden categories. Default is false.
deleted boolean No If true, also show removed categories. Default is false.

E.g. Find all Test Case categories, where the current user has permission to add items:

GET https://hostname/cb/rest/user/self/categories/permission/Issue - Add?type=Test Case 

Get a list of all categories in a project where a user has a specific permission

GET {userURI}{projectURI}/categories/permission/{permissionIdOrName}[?query] 
GET {projectURI}{userURI}/categories/permission/{permissionIdOrName}[?query] 
Parameter Type Required Meaning
permissionIdOrName String Yes Id or Name of a category permission
type String No Comma-separated list of category types (ids or names) to only show categories of these types
hidden boolean No True to also show hidden categories. Default is false.
deleted boolean No If true, also show removed categories. Default is false.

Get a summary of all items in a category

GET {categoryURI}/item/summary

For example:

GET https://hostname/cb/rest/project/1/category/Contacts/item/summary
{
  "total" : 2,
  "open" : 2
}

Get the outline of all items in a category (since CB-7.9.0)

GET {categoryURI}/outline[?query]
Parameter Type Required Meaning
paragraph boolean false Whether to also return the paragraph/chapter number of each tracker item. Default is false.
flat boolean false Whether to return the outline as a flat list, where children directly follow their parent (true).
Default is false, which returns a tree.
depth int false The maximum depth of the outline/hierarchy to return. A depth of 0 only returns the top-level/root items. Default is unlimited (full depth).

For example:

GET https://hostname/cb/rest/project/1/category/TestCases/outline?paragraph=true&depth=0

Will return the top-level/root items (including paragraph/chapter numbers).
The boolean property leaf of each item indicates, whether an item has children (false) or not (true).
You can query the children/descendants of non-leaf items via:

GET {itemURI}/outline[?query]

This allows interactive/on-demand expansion of arbitrarily huge or deep outlines.

Get a page of category items

GET {categoryURI}/items/page/{page}[?query]
Parameter Type Required Meaning
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.
status String No One of {"Open", "Closed", "Resolved", "Unresolved", "Successful", "Unsuccessful"} to only show category items with this (meta) status. Default is any status.
newerThen String No A timestamp, to only return items that were created/modified after this date and time.
You can specify a relative timestamp as "[{This | Last [n]}] [{minute | hour | day | week | month | quarter | year}[s]]", where "Today" is a synonym for "This day" and "Yesterday" is a synonym for "Last day", e.g. "Last week", "This month", "Last 2 days"; or as "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".
An absolute timestamp is specified in ISO 8601 format, e.g. "2013-03-12T14:38:06+01:00".

Get a page of category items matching all of the specified criteria

GET {categoryURI}/items/and/{criteria}/page/{page}[?query]
Parameter Type Required Meaning
criteria String Yes Semicolon-separated list of property=value[, ...] criteria, where each criteria must be matched
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.
newerThen String No A timestamp, to only return items that were created/modified after this date and time.
You can specify a relative timestamp as "[{This | Last [n]}] [{minute | hour | day | week | month | quarter | year}[s]]", where "Today" is a synonym for "This day" and "Yesterday" is a synonym for "Last day", e.g. "Last week", "This month", "Last 2 days"; or as "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".
An absolute timestamp is specified in ISO 8601 format, e.g. "2013-03-12T14:38:06+01:00".

For example: Get functional test cases created by [USER:bond]:

GET https://hostname/cb/rest/project/1/category/Test Cases/items/and/submitter=[USER:bond];type=Functional/page/1

Get a page of category items matching at least one of the specified criteria

GET {categoryURI}/items/or/{criteria}/page/{page}[?query]
Parameter Type Required Meaning
criteria String Yes Semicolon-separated list of property=value[, ...] criteria, where at least one criteria must be matched
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.
newerThen String No A timestamp, to only return items that were created/modified after this date and time.
You can specify a relative timestamp as "[{This | Last [n]}] [{minute | hour | day | week | month | quarter | year}[s]]", where "Today" is a synonym for "This day" and "Yesterday" is a synonym for "Last day", e.g. "Last week", "This month", "Last 2 days"; or as "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".
An absolute timestamp is specified in ISO 8601 format, e.g. "2013-03-12T14:38:06+01:00".

For example: Get first page of contacts where "country" is Germany or the "language" is german:

GET https://hostname/cb/rest/project/1/category/Contacts/items/or/country=DE;language=de/page/1

Get a page of category items matching all of the mandatory criteria and at least one of the optional criteria

GET {categoryURI}/items/and/{mandatoryCriteria}/or/{optionalCriteria}/page/{page}[?query]
Parameter Type Required Meaning
mandatoryCriteria String Yes Semicolon-separated list of property=value[, ...] criteria, where each criteria must be matched
optionalCriteria String Yes Semicolon-separated list of property=value[, ...] criteria, where at least one criteria must be matched
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.
newerThen String No A timestamp, to only return items that were created/modified after this date and time.
You can specify a relative timestamp as "[{This | Last [n]}] [{minute | hour | day | week | month | quarter | year}[s]]", where "Today" is a synonym for "This day" and "Yesterday" is a synonym for "Last day", e.g. "Last week", "This month", "Last 2 days"; or as "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".
An absolute timestamp is specified in ISO 8601 format, e.g. "2013-03-12T14:38:06+01:00".

For example: Get the new business contacts from this week, where "country" is Germany or the "language"is german:

GET https://hostname/cb/rest/project/1/category/Contacts/items/and/type=Company/or/country=DE;language=de/page/1?newerThen=This week

Category Views

Category views have URIs of the form: "{categoryURI}/view/{id}" or "{categoryURI}/view/{name}", where {id} is the internal view id/number and {name} is the view name. Both id and name are only unique within a category and must therefore always be qualified by the {categoryURI}.

You cannot define or configure category views via the REST API, you can only use them.

Get the category view schema

GET /category/view/schema

Get the available views of a category

GET {categoryURI}/views

Get the definition of a specific category view

GET {categoryViewURI} 

Get the item schema of a category view

GET {categoryViewURI}/schema 

Get a page of category view items

GET {categoryViewURI}/items/page/{page} 
Parameter Type Required Meaning
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.

Trackers

Trackers have URIs of the form: "/tracker/{id}" or "{projectURI}/tracker/{name}", where {id} is the internal unique tracker id/number and {name} is the tracker name, which is only unique within a project.

Get the tracker type schema

GET /tracker/type/schema

Get the available tracker types

GET /tracker/types[?query]
Parameter Type Required Meaning
kind String No Which kind of tracker types to return, as a comma-separated list of {Category", "Tracker", "Repository" }. Default is "Tracker".
outline boolean No Whether to only return tracker types (of the specified kind) where an outline is available (true) or not available (false). Default is any of the specified kind.

All tracker types are predefined. You cannot create, update or delete tracker types.

Get a tracker type definition

GET /tracker/type/{trackerTypeIdOrName} 

Get the immutable definition of a tracker type.


Get the available tracker permissions

GET /tracker/permissions

All tracker permissions are predefined. You cannot create, update or delete tracker permissions.


Get a tracker permission

GET /tracker/permission/{permissionIdOrName} 

Get the immutable definition of a tracker permission.


Get the tracker schema

GET /tracker/schema

Create a new tracker

POST /tracker

The request body must contain a valid tracker object with all required properties, e.g.:

{
  "project"     : "/project/1",
  "type"        : "/tracker/type/Test",
  "name"        : "Tests",
  "keyName"     : "TEST",
  "description" : "A Test tracker for Rest-Api tests",
  "descFormat"  : "Wiki",
  "workflow"    : true
}

Create a new tracker as a clone of another tracker

POST {trackerURI}/clone

The request body must contain a valid tracker object, same as above, but the new tracker will use the specified tracker as template and inherit the tracker schema and permissions.


Update tracker settings

PUT /tracker

The request body must contain the tracker URI and the properties to update, e.g. to hide a tracker in the GUI:

{
  "uri"     : "/project/1/tracker/Tests",
  "visible" : false
}

To show a hidden tracker, simply set "visible" to true.

Delete a tracker

DELETE {trackerURI} 

Get a tracker definition

GET {trackerURI} 

Get the basic item schema of a tracker

GET {trackerURI}/schema

Note: You cannot configure the item schema of a tracker via the REST API.


Get the schema of a tracker item property

GET {trackerURI}/field/{fieldIdOrName} 

Note: You cannot configure the schema of a tracker item field via the REST API.


Get all granted tracker permissions per role

GET {trackerURI}/roles/permissions 

Get the tracker permissions granted to a specific role

GET {trackerURI}{roleURI}/permissions 
GET {roleURI}{trackerURI}/permissions 

Set the tracker permissions for a specific role

PUT {trackerURI}{roleURI}/permissions 
PUT {roleURI}{trackerURI}/permissions 

The request body must contain an array of tracker permissions to grant to the role (passing the permission id or name is sufficient), e.g.:

[ "Issue - View Any", "Issue - View Comments/Attachments" ]

Remove all tracker permissions for a specific role

DELETE {trackerURI}{roleURI}/permissions 
DELETE {roleURI}{trackerURI}/permissions 

Get the effective permissions of a user on a tracker

GET {trackerURI}{userURI}/permissions 
GET {userURI}{trackerURI}/permissions 

Get a list of all trackers in a project

GET {projectURI}/trackers[?query] 
Parameter Type Required Meaning
kind String No Which kind of trackers to return, as a comma-separated list of {Category", "Tracker", "Repository" }. Default is "Tracker".
type String No Comma-separated list of tracker types (ids or names) to only show trackers of these types
hidden boolean No True to also show hidden trackers. Default is false.
deleted boolean No If true, also show removed trackers. Default is false.

E.g. Show all Bug and Task trackers in the test project:

GET https://hostname/cb/rest/project/1/trackers?type=Bug,Task&hidden=true 

Get a list of all trackers visible to a user (grouped by project)

GET {userURI}/trackers[?query] 
Parameter Type Required Meaning
kind String No Which kind of trackers to return, as a comma-separated list of {Category", "Tracker", "Repository" }. Default is "Tracker".
type String No Comma-separated list of tracker types (ids or names) to only show trackers of these types
hidden boolean No True to also show hidden trackers. Default is false.
deleted boolean No If true, also show removed trackers. Default is false.

Get a list of all trackers in a project visible to a user

GET {userURI}{projectURI}/trackers[?query] 
GET {projectURI}{userURI}/trackers[?query] 
Parameter Type Required Meaning
kind String No Which kind of trackers to return, as a comma-separated list of {Category", "Tracker", "Repository" }. Default is "Tracker".
type String No Comma-separated list of tracker types (ids or names) to only show trackers of these types
hidden boolean No True to also show hidden trackers. Default is false.
deleted boolean No If true, also show removed trackers. Default is false.

Get a list of all trackers where a user has a specific permission (grouped by project)

GET {userURI}/trackers/permission/{permissionIdOrName}[?query] 
Parameter Type Required Meaning
permissionIdOrName String Yes Id or Name of a tracker permission
kind String No Which kind of trackers to return, as a comma-separated list of {Category", "Tracker", "Repository" }. Default is "Tracker".
type String No Comma-separated list of tracker types (ids or names) to only show trackers of these types
hidden boolean No True to also show hidden trackers. Default is false.
deleted boolean No If true, also show removed trackers. Default is false.

E.g. Find all Bug trackers where the current user has permission to add items:

GET https://hostname/cb/rest/user/self/trackers/permission/Issue - Add?type=Bug 

Get a list of all trackers in a project where a user has a specific permission

GET {userURI}{projectURI}/trackers/permission/{permissionIdOrName}[?query] 
GET {projectURI}{userURI}/trackers/permission/{permissionIdOrName}[?query] 
Parameter Type Required Meaning
permissionIdOrName String Yes Id or Name of a tracker permission
type String No Comma-separated list of tracker types (ids or names) to only show trackers of these types
hidden boolean No True to also show hidden trackers. Default is false.
deleted boolean No If true, also show removed trackers. Default is false.

Get a summary of all items in a tracker

GET {trackerURI}/item/summary

For example:

GET https://hostname/cb/rest/project/1/tracker/Bugs/item/summary
{
  "total" : 1754,
  "open"  : 78
}

Get the outline of all items in a trackers (since CB-7.9.0)

GET {trackerURI}/outline[?query]
Parameter Type Required Meaning
paragraph boolean false Whether to also return the paragraph/chapter number of each tracker item. Default is false.
flat boolean false Whether to return the outline as a flat list, where children directly follow their parent (true).
Default is false, which returns a tree.
depth int false The maximum depth of the outline/hierarchy to return. A depth of 0 only returns the top-level/root items. Default is unlimited (full depth).

For example:

GET https://hostname/cb/rest/project/1/tracker/Requirements/outline?paragraph=true&depth=0

Will return the top-level/root requirements/folders (including paragraph/chapter numbers).
The boolean property leaf of each item indicates, whether an item has children (false) or not (true).
You can query the children/descendants of non-leaf items via:

GET {itemURI}/outline[?query]

This allows interactive/on-demand expansion of arbitrarily huge or deep outlines.

Get a page of tracker items

GET {trackerURI}/items/page/{page}[?query]
Parameter Type Required Meaning
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.
status String No One of {"Open", "Closed", "Resolved", "Unresolved", "Successful", "Unsuccessful"} to only show tracker items with this (meta) status. Default is any status.
newerThen String No A timestamp, to only return items that were created/modified after this date and time.
You can specify a relative timestamp as "[{This | Last [n]}] [{minute | hour | day | week | month | quarter | year}[s]]", where "Today" is a synonym for "This day" and "Yesterday" is a synonym for "Last day", e.g. "Last week", "This month", "Last 2 days"; or as "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".
An absolute timestamp is specified in ISO 8601 format, e.g. "2013-03-12T14:38:06+01:00".

Get a page of tracker items matching all of the specified criteria

GET {trackerURI}/items/and/{criteria}/page/{page}[?query]
Parameter Type Required Meaning
criteria String Yes Semicolon-separated list of property=value[, ...] criteria, where each criteria must be matched
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.
newerThen String No A timestamp, to only return items that were created/modified after this date and time.
You can specify a relative timestamp as "[{This | Last [n]}] [{minute | hour | day | week | month | quarter | year}[s]]", where "Today" is a synonym for "This day" and "Yesterday" is a synonym for "Last day", e.g. "Last week", "This month", "Last 2 days"; or as "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".
An absolute timestamp is specified in ISO 8601 format, e.g. "2013-03-12T14:38:06+01:00".

For example: Get bugs submitted by [USER:bond], where "priority" is 2 and "name" starts with "Test" and "category"is 1, 2 or 3:

GET https://hostname/cb/rest/project/1/tracker/Bugs/items/and/submitter=[USER:bond];priority=2;name=like,Test*;category=1,2,3/page/1

Get a page of tracker items matching at least one of the specified criteria

GET {trackerURI}/items/or/{criteria}/page/{page}[?query]
Parameter Type Required Meaning
criteria String Yes Semicolon-separated list of property=value[, ...] criteria, where at least one criteria must be matched
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.
newerThen String No A timestamp, to only return items that were created/modified after this date and time.
You can specify a relative timestamp as "[{This | Last [n]}] [{minute | hour | day | week | month | quarter | year}[s]]", where "Today" is a synonym for "This day" and "Yesterday" is a synonym for "Last day", e.g. "Last week", "This month", "Last 2 days"; or as "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".
An absolute timestamp is specified in ISO 8601 format, e.g. "2013-03-12T14:38:06+01:00".

For example: Get bugs where "priority" is 2 or "category"is 1, 2 or 3:

GET https://hostname/cb/rest/project/1/tracker/Bugs/items/or/priority=2;category=1,2,3/page/1

Get a page of tracker items matching all of the mandatory criteria and at least one of the optional criteria

GET {trackerURI}/items/and/{mandatoryCriteria}/or/{optionalCriteria}/page/{page}[?query]
Parameter Type Required Meaning
mandatoryCriteria String Yes Semicolon-separated list of property=value[, ...] criteria, where each criteria must be matched
optionalCriteria String Yes Semicolon-separated list of property=value[, ...] criteria, where at least one criteria must be matched
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.
newerThen String No A timestamp, to only return items that were created/modified after this date and time.
You can specify a relative timestamp as "[{This | Last [n]}] [{minute | hour | day | week | month | quarter | year}[s]]", where "Today" is a synonym for "This day" and "Yesterday" is a synonym for "Last day", e.g. "Last week", "This month", "Last 2 days"; or as "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".
An absolute timestamp is specified in ISO 8601 format, e.g. "2013-03-12T14:38:06+01:00".

For example: Get bugs submitted by [USER:bond] today, where "priority" is 2 or "category"is 1, 2 or 3:

GET https://hostname/cb/rest/project/1/tracker/Bugs/items/and/submitter=[USER:bond]/or/priority=2;category=1,2,3/page/1?newerThen=today

Tracker Views

Tracker views have URIs of the form: "{trackerURI}/view/{id}" or "{trackerURI}/view/{name}", where {id} is the internal view id/number and {name} is the view name. Both id and name are only unique within a tracker and must therefore always be qualified by the {trackerURI}.

You cannot define or configure tracker views via the REST API, you can only use them.

Get the tracker view schema

GET /tracker/view/schema

Get the available views of a tracker

GET {trackerURI}/views

Get the definition of a specific tracker view

GET {trackerViewURI} 

Get the item schema of a tracker view

GET {trackerViewURI}/schema 

Get a page of tracker view items

GET {trackerViewURI}/items/page/{page} 
Parameter Type Required Meaning
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.

Tracker/CMDB Items

Tracker/CMDB items have URIs of form "/item/{id}", where {id} is the internal item id/number.

Dealing with Tracker/CMDB items can be complex, because each tracker/category has user and state specific item schemas and optionally a Finite State Machine, that only allows dedicated state transitions.

Get the branched version of an item

To get an item on a branch of the tracker you can use this request:

GET {itemURI}/branch/{branchId} 

For example:

 {GET https://hostname/cb/rest/item/9894/branch/69973} 

The result is the same as when requesting an item

Submit a new top-level CMDB category item

First you have to get the schema and a pre-initialized object for a new top-level CMDB category item:

GET {categoryURI}/newItem 


For example:

GET https://hostname/cb/rest/project/Test/category/Test Cases/newItem

The response contains 4 properties:

  • "transition" (optional, schema: "/transition/schema") is the initial state transition, e.g.
      "transition" : {
        "uri" : "/transition/27",
        "tracker" : {
          "uri" : "/category/1027",
          "name" : "Test Cases"
        },
        "name" : "Create",
        "descFormat" : "Plain",
        "toStatus" : {
          "id" : 1,
          "name" : "New"
        }
      
    }
  • "item"is a CMDB category item object, where properties are already initialized to default values according to transition and initial status, e.g.
      "item" : {
        "version" : 1,
        "tracker" : {
          "project" : {
            "uri" : "/project/1",
            "name" : "Test"
          },
          "uri" : "/category/1027",
          "name" : "Test Cases"
        },
        "status" : {
          "id" : 1,
          "name" : "New"
        },
        "submitter" : {
          "uri" : "/user/1",
          "name" : "bond"
        },
        "descFormat" : "Plain"
      
    }
  • "type"is the JSON schema to edit properties of the new CMDB category "item", e.g.
      "type" : {
        "title" : "Test case",
        "plural" : "Test cases",
        "description" : "Test cases to validate and verify the product",
        "properties" : {
          "uri" : {
            "title" : "URI",
            "type" : "string",
            "format" : "uri"
          },
          "version" : {
            "title" : "Version",
            "type" : "integer",
            "minimum" : 1
          },
          "parent" : {
            "title" : "Parent",
            "type" : "object",
            "properties" : {
              "uri" : {
                "title" : "URI",
                "type" : "string",
                "format" : "uri"
              },
              "name" : {
                "title" : "Name",
                "type" : "string"
              }
            }
          },
          "tracker" : {
            "title" : "Category",
            "type" : "object",
            "properties" : {
              "uri" : {
                "title" : "URI",
                "type" : "string",
                "format" : "uri"
              },
              "name" : {
                "title" : "Name",
                "type" : "string",
                "maxLength" : 255
              }
            },
            "required" : [ "name" ]
          },
          "template" : {
            "title" : "Template",
            "type" : "object",
            "properties" : {
              "uri" : {
                "title" : "URI",
                "type" : "string",
                "format" : "uri"
              },
              "name" : {
                "title" : "Name",
                "type" : "string"
              }
            },
            "optionsURI" : "/category/1027/newItem/field/82/options"
          },
          "priority" : {
            "title" : "Priority",
            "enum" : [ {
              "id" : 5,
              "name" : "Lowest"
            }, {
              "id" : 4,
              "name" : "Low"
            }, {
              "id" : 3,
              "name" : "Normal"
            }, {
              "id" : 2,
              "name" : "High"
            }, {
              "id" : 1,
              "name" : "Highest"
            } ]
          },
          "name" : {
            "title" : "Name",
            "type" : "string",
            "maxLength" : 255
          },
          "status" : {
            "title" : "Status",
            "enum" : [ {
              "id" : 1,
              "name" : "New"
            }, {
              "id" : 2,
              "name" : "In Design"
            }, {
              "id" : 3,
              "name" : "Awaiting approval"
            }, {
              "id" : 4,
              "name" : "Accepted"
            }, {
              "id" : 5,
              "name" : "Rejected"
            }, {
              "id" : 6,
              "name" : "Outdated"
            } ]
          },
          "type" : {
            "title" : "Type",
            "enum" : [ {
              "id" : 1,
              "name" : "Folder"
            }, {
              "id" : 2,
              "name" : "Compatibility"
            }, {
              "id" : 3,
              "name" : "Functional"
            }, {
              "id" : 4,
              "name" : "Integration"
            }, {
              "id" : 5,
              "name" : "Installation"
            }, {
              "id" : 6,
              "name" : "Performance"
            }, {
              "id" : 7,
              "name" : "Security"
            }, {
              "id" : 8,
              "name" : "Smoke"
            } ]
          },
          "submittedAt" : {
            "title" : "Created at",
            "type" : "string",
            "format" : "date-time"
          },
          "submitter" : {
            "title" : "Created by",
            "type" : "object",
            "properties" : {
              "uri" : {
                "title" : "URI",
                "type" : "string",
                "format" : "uri"
              },
              "name" : {
                "title" : "User Name",
                "type" : "string",
                "maxLength" : 40
              }
            },
            "required" : [ "name" ]
          },
          "modifiedAt" : {
            "title" : "Modified at",
            "type" : "string",
            "format" : "date-time"
          },
          "modifier" : {
            "title" : "Modified by",
            "type" : "object",
            "properties" : {
              "uri" : {
                "title" : "URI",
                "type" : "string",
                "format" : "uri"
              },
              "name" : {
                "title" : "User Name",
                "type" : "string",
                "maxLength" : 40
              }
            },
            "required" : [ "name" ]
          },
          "verifies" : {
            "title" : "Verifies",
            "type" : "array",
            "items" : {
              "title" : "Item",
              "plural" : "Items",
              "type" : "object",
              "properties" : {
                "uri" : {
                  "title" : "URI",
                  "type" : "string",
                  "format" : "uri"
                },
                "name" : {
                  "title" : "Name",
                  "type" : "string"
                }
              }
            },
            "uniqueItems" : true,
            "optionsURI" : "/category/1027/newItem/field/17/options"
          },
          "preAction" : {
            "title" : "Pre-Action",
            "type" : "string",
            "format" : "Wiki"
          },
          "testSteps" : {
            "title" : "Test Steps",
            "type" : "array",
            "items" : {
              "type" : "array",
              "items" : [ {
                "title" : "Action",
                "type" : "string",
                "format" : "Wiki"
              }, {
                "title" : "Expected result",
                "type" : "string",
                "format" : "Wiki"
              }, {
                "title" : "Critical?",
                "type" : "boolean"
              } ]
            }
          },
          "postAction" : {
            "title" : "Post-Action",
            "type" : "string",
            "format" : "Wiki"
          },
          "description" : {
            "title" : "Description",
            "type" : "string"
          },
          "descFormat" : {
            "title" : "Description Format",
            "enum" : [ "Plain", "Html", "Wiki" ]
          },
          "comments" : {
            "title" : "Comments/Attachments",
            "type" : "array",
            "items" : {
              "title" : "Comment/Attachment",
              "plural" : "Comments/Attachments",
              "type" : "object",
              "properties" : {
                "uri" : {
                  "title" : "URI",
                  "type" : "string",
                  "format" : "uri"
                },
                "version" : {
                  "title" : "Version",
                  "type" : "integer"
                },
                "replyTo" : {
                  "title" : "Reply To",
                  "description" : "The parent comment where this comment is a reply to",
                  "type" : "object",
                  "properties" : {
                    "uri" : {
                      "title" : "URI",
                      "type" : "string",
                      "format" : "uri"
                    }
                  }
                },
                "depth" : {
                  "title" : "Depth",
                  "type" : "integer"
                },
                "createdAt" : {
                  "title" : "Created",
                  "type" : "string",
                  "format" : "date-time"
                },
                "createdBy" : {
                  "title" : "Created by",
                  "type" : "object",
                  "properties" : {
                    "uri" : {
                      "title" : "URI",
                      "type" : "string",
                      "format" : "uri"
                    },
                    "name" : {
                      "title" : "User Name",
                      "type" : "string",
                      "maxLength" : 40
                    }
                  },
                  "required" : [ "name" ]
                },
                "modifiedAt" : {
                  "title" : "Modified at",
                  "type" : "string",
                  "format" : "date-time"
                },
                "modifier" : {
                  "title" : "Modified by",
                  "type" : "object",
                  "properties" : {
                    "uri" : {
                      "title" : "URI",
                      "type" : "string",
                      "format" : "uri"
                    },
                    "name" : {
                      "title" : "User Name",
                      "type" : "string",
                      "maxLength" : 40
                    }
                  },
                  "required" : [ "name" ]
                },
                "comment" : {
                  "title" : "Comment",
                  "type" : "string"
                },
                "commentFormat" : {
                  "title" : "Description Format",
                  "enum" : [ "Plain", "Html", "Wiki" ]
                },
                "attachments" : {
                  "title" : "Attachments",
                  "type" : "array",
                  "items" : {
                    "title" : "Attachment",
                    "plural" : "Attachments",
                    "type" : "object",
                    "properties" : {
                      "uri" : {
                        "title" : "URI",
                        "type" : "string",
                        "format" : "uri"
                      },
                      "version" : {
                        "title" : "Version",
                        "type" : "integer"
                      },
                      "name" : {
                        "title" : "File",
                        "type" : "string"
                      },
                      "size" : {
                        "title" : "Size",
                        "type" : "integer"
                      },
                      "modifiedAt" : {
                        "title" : "Modified at",
                        "type" : "string",
                        "format" : "date-time"
                      },
                      "modifier" : {
                        "title" : "Modified by",
                        "type" : "object",
                        "properties" : {
                          "uri" : {
                            "title" : "URI",
                            "type" : "string",
                            "format" : "uri"
                          },
                          "name" : {
                            "title" : "User Name",
                            "type" : "string",
                            "maxLength" : 40
                          }
                        },
                        "required" : [ "name" ]
                      }
                    }
                  }
                }
              }
            },
            "uniqueItems" : true
          },
          "children" : {
            "title" : "Children",
            "type" : "array",
            "items" : {
              "title" : "Item",
              "plural" : "Items",
              "type" : "object",
              "properties" : {
                "uri" : {
                  "title" : "URI",
                  "type" : "string",
                  "format" : "uri"
                },
                "name" : {
                  "title" : "Name",
                  "type" : "string"
                }
              }
            },
            "uniqueItems" : true
          }
        },
        "required" : [ "name" ]
      
    }
  • "permissions"defines per schema property, whether the current user can change/set/edit the (pre-set) property value of the item (3) or not (1), e.g.
      "permissions" : {
        "id" : 1,
        "parent" : 3,
        "tracker" : 1,
        "template" : 3,
        "priority" : 3,
        "name" : 3,
        "status" : 1,
        "type" : 3,
        "submittedAt" : 1,
        "submitter" : 1,
        "modifiedAt" : 1,
        "modifier" : 1,
        "verifies" : 3,
        "preAction" : 3,
        "testSteps" : 3,
        "postAction" : 3,
        "description" : 3,
        "descFormat" : 3,
        "comments" : 3,
        "children" : 3
      
    }


After having set all additional "item" properties, you create the CMDB category item via:

POST /item


If you do not have any item attachments to upload, then the body simply contains the item object, otherwise the item to create must be in the part named "body" of a multipart request and each attachment must be an extra part (see the example for creating a new tracker item below).

For example: Create the item only with a plain comment but no attachments

{
  "name"        : "Test dimmer switch",
  "tracker"     : "/project/Test/category/Test Cases",
  "status"      : "New",
  "priority"    : "High",
  "type"        : "Functional",
  "description" : "Test dimmer switch",
  "descFormat"  : "Plain",
  "preAction"   : "Prepare the test environment",
  "testSteps"   : [ ["Switch on",   "Light is on",                    true ],
 		    ["Turn dimmer", "Its getting brighter or darker", false],
		    ["Switch off",  "Light is off", 		      true ]
                  ],
  "postAction"  : "Cleanup the test environment",
  "comments"    : { "comment" : "I have to test this" 

}

}

Submit a new top-level tracker item

First you have to get the schema and a pre-initialized object for a new top-level tracker item:

GET {trackerURI}/newItem 


For example:

GET https://hostname/cb/rest/project/Test/tracker/Tasks/newItem

The response contains 4 properties:

  • "transition" (optional, schema: "/transition/schema") is the initial state transition, e.g.
      "transition" : {
        "uri" : "/transition/79",
        "tracker" : {
          "uri" : "/tracker/1033",
          "name" : "Tasks"
        },
        "name" : "Submit",
        "descFormat" : "Plain",
        "toStatus" : {
          "id" : 1,
          "name" : "New"
        }
      
    }
  • "item"is a tracker item object, where properties are already initialized to default values according to transition and initial status, e.g.
      "item" : {
        "version" : 1,
        "tracker" : {
          "project" : {
            "uri" : "/project/1",
            "name" : "Test"
          },
          "uri" : "/tracker/1033",
          "name" : "Tasks"
        },
        "status" : {
          "id" : 1,
          "name" : "New"
        },
        "submitter" : {
          "uri" : "/user/1",
          "name" : "bond"
        },
        "descFormat" : "Plain"
      
    }
  • "type"is the JSON schema to edit properties of the new tracker "item", e.g.
      "type" : {
        "title" : "Task",
        "plural" : "Tasks",
        "description" : "Activities that need to be accomplished within a defined period of time",
        "properties" : {
          "uri" : {
            "title" : "URI",
            "type" : "string",
            "format" : "uri"
          },
          "version" : {
            "title" : "Version",
            "type" : "integer",
            "minimum" : 1
          },
          "parent" : {
            "title" : "Parent",
            "type" : "object",
            "properties" : {
              "uri" : {
                "title" : "URI",
                "type" : "string",
                "format" : "uri"
              },
              "name" : {
                "title" : "Name",
                "type" : "string"
              }
            }
          },
          "tracker" : {
            "title" : "Tracker",
            "type" : "object",
            "properties" : {
              "uri" : {
                "title" : "URI",
                "type" : "string",
                "format" : "uri"
              },
              "name" : {
                "title" : "Name",
                "type" : "string",
                "maxLength" : 255
              }
            },
            "required" : [ "name" ]
          },
          "priority" : {
            "title" : "Priority",
            "enum" : [ {
              "id" : 5,
              "name" : "Lowest"
            }, {
              "id" : 4,
              "name" : "Low"
            }, {
              "id" : 3,
              "name" : "Normal"
            }, {
              "id" : 2,
              "name" : "High"
            }, {
              "id" : 1,
              "name" : "Highest"
            } ]
          },
          "name" : {
            "title" : "Summary",
            "type" : "string",
            "maxLength" : 255
          },
          "status" : {
            "title" : "Status",
            "enum" : [ {
              "id" : 1,
              "name" : "New"
            }, {
              "id" : 2,
              "name" : "Suspended"
            }, {
              "id" : 3,
              "name" : "In progress"
            }, {
              "id" : 4,
              "name" : "Partly completed"
            }, {
              "id" : 5,
              "name" : "Completed"
            } ]
          },
          "severity" : {
            "title" : "Severity",
            "enum" : [ {
              "id" : 1,
              "name" : "Blocker"
            }, {
              "id" : 2,
              "name" : "Critical"
            }, {
              "id" : 3,
              "name" : "Minor"
            }, {
              "id" : 4,
              "name" : "Trivial"
            } ]
          },
          "resolution" : {
            "title" : "Resolution",
            "enum" : [ {
              "id" : 1,
              "name" : "Successful"
            }, {
              "id" : 2,
              "name" : "Invalid"
            }, {
              "id" : 3,
              "name" : "Duplicate"
            } ]
          },
          "release" : {
            "title" : "Release",
            "type" : "array",
            "items" : {
              "title" : "Item",
              "plural" : "Items",
              "type" : "object",
              "properties" : {
                "uri" : {
                  "title" : "URI",
                  "type" : "string",
                  "format" : "uri"
                },
                "name" : {
                  "title" : "Name",
                  "type" : "string"
                }
              }
            },
            "uniqueItems" : true,
            "optionsURI" : "/tracker/1033/newItem/field/31/options"
          },
          "assignedTo" : {
            "title" : "Assigned to",
            "type" : "array",
            "items" : {
              "anyOf" : [ {
                "title" : "User",
                "plural" : "Accounts",
                "type" : "object",
                "properties" : {
                  "uri" : {
                    "title" : "URI",
                    "type" : "string",
                    "format" : "uri"
                  },
                  "name" : {
                    "title" : "User Name",
                    "type" : "string",
                    "maxLength" : 40
                  }
                },
                "required" : [ "name" ]
              }, {
                "title" : "Role",
                "plural" : "Roles",
                "type" : "object",
                "properties" : {
                  "uri" : {
                    "title" : "URI",
                    "type" : "string",
                    "format" : "uri"
                  },
                  "name" : {
                    "title" : "Name",
                    "type" : "string"
                  }
                },
                "required" : [ "name" ]
              } ]
            },
            "uniqueItems" : true,
            "optionsURI" : "/tracker/1033/newItem/field/5/options"
          },
          "submittedAt" : {
            "title" : "Submitted at",
            "type" : "string",
            "format" : "date-time"
          },
          "submitter" : {
            "title" : "Submitted by",
            "type" : "object",
            "properties" : {
              "uri" : {
                "title" : "URI",
                "type" : "string",
                "format" : "uri"
              },
              "name" : {
                "title" : "User Name",
                "type" : "string",
                "maxLength" : 40
              }
            },
            "required" : [ "name" ]
          },
          "modifiedAt" : {
            "title" : "Modified at",
            "type" : "string",
            "format" : "date-time"
          },
          "modifier" : {
            "title" : "Modified by",
            "type" : "object",
            "properties" : {
              "uri" : {
                "title" : "URI",
                "type" : "string",
                "format" : "uri"
              },
              "name" : {
                "title" : "User Name",
                "type" : "string",
                "maxLength" : 40
              }
            },
            "required" : [ "name" ]
          },
          "startDate" : {
            "title" : "Start Date",
            "type" : "string",
            "format" : "date-time"
          },
          "endDate" : {
            "title" : "End Date",
            "type" : "string",
            "format" : "date-time"
          },
          "plannedEffort" : {
            "title" : "Planned Effort",
            "type" : "integer",
            "minimum" : 0
          },
          "accruedMillis" : {
            "title" : "Accrued Effort",
            "type" : "integer",
            "minimum" : 0
          },
          "spentEffort" : {
            "title" : "Spent Effort",
            "type" : "integer",
            "minimum" : 0
          },
          "spentEstimatedHours" : {
            "title" : "% Spent / Plan",
            "type" : "number"
          },
          "description" : {
            "title" : "Description",
            "type" : "string"
          },
          "descFormat" : {
            "title" : "Description Format",
            "enum" : [ "Plain", "Html", "Wiki" ]
          },
          "comments" : {
            "title" : "Comments/Attachments",
            "type" : "array",
            "items" : {
              "title" : "Comment/Attachment",
              "plural" : "Comments/Attachments",
              "type" : "object",
              "properties" : {
                "uri" : {
                  "title" : "URI",
                  "type" : "string",
                  "format" : "uri"
                },
                "version" : {
                  "title" : "Version",
                  "type" : "integer"
                },
                "replyTo" : {
                  "title" : "Reply To",
                  "description" : "The parent comment where this comment is a reply to",
                  "type" : "object",
                  "properties" : {
                    "uri" : {
                      "title" : "URI",
                      "type" : "string",
                      "format" : "uri"
                    }
                  }
                },
                "depth" : {
                  "title" : "Depth",
                  "type" : "integer"
                },
                "createdAt" : {
                  "title" : "Created",
                  "type" : "string",
                  "format" : "date-time"
                },
                "createdBy" : {
                  "title" : "Created by",
                  "type" : "object",
                  "properties" : {
                    "uri" : {
                      "title" : "URI",
                      "type" : "string",
                      "format" : "uri"
                    },
                    "name" : {
                      "title" : "User Name",
                      "type" : "string",
                      "maxLength" : 40
                    }
                  },
                  "required" : [ "name" ]
                },
                "modifiedAt" : {
                  "title" : "Modified at",
                  "type" : "string",
                  "format" : "date-time"
                },
                "modifier" : {
                  "title" : "Modified by",
                  "type" : "object",
                  "properties" : {
                    "uri" : {
                      "title" : "URI",
                      "type" : "string",
                      "format" : "uri"
                    },
                    "name" : {
                      "title" : "User Name",
                      "type" : "string",
                      "maxLength" : 40
                    }
                  },
                  "required" : [ "name" ]
                },
                "comment" : {
                  "title" : "Comment",
                  "type" : "string"
                },
                "commentFormat" : {
                  "title" : "Description Format",
                  "enum" : [ "Plain", "Html", "Wiki" ]
                },
                "attachments" : {
                  "title" : "Attachments",
                  "type" : "array",
                  "items" : {
                    "title" : "Attachment",
                    "plural" : "Attachments",
                    "type" : "object",
                    "properties" : {
                      "uri" : {
                        "title" : "URI",
                        "type" : "string",
                        "format" : "uri"
                      },
                      "version" : {
                        "title" : "Version",
                        "type" : "integer"
                      },
                      "name" : {
                        "title" : "File",
                        "type" : "string"
                      },
                      "size" : {
                        "title" : "Size",
                        "type" : "integer"
                      },
                      "modifiedAt" : {
                        "title" : "Modified at",
                        "type" : "string",
                        "format" : "date-time"
                      },
                      "modifier" : {
                        "title" : "Modified by",
                        "type" : "object",
                        "properties" : {
                          "uri" : {
                            "title" : "URI",
                            "type" : "string",
                            "format" : "uri"
                          },
                          "name" : {
                            "title" : "User Name",
                            "type" : "string",
                            "maxLength" : 40
                          }
                        },
                        "required" : [ "name" ]
                      }
                    }
                  }
                }
              }
            },
            "uniqueItems" : true
          },
          "children" : {
            "title" : "Children",
            "type" : "array",
            "items" : {
              "title" : "Item",
              "plural" : "Items",
              "type" : "object",
              "properties" : {
                "uri" : {
                  "title" : "URI",
                  "type" : "string",
                  "format" : "uri"
                },
                "name" : {
                  "title" : "Name",
                  "type" : "string"
                }
              }
            },
            "uniqueItems" : true
          }
        },
        "required" : [ "name", "description" ]
      
    }
  • "permissions"defines per schema property, whether the current user can change/set/edit the (pre-set) property value of the item (3) or not (1), e.g.
      "permissions" : {
        "tracker" : 1,
        "priority" : 3,
        "name" : 3,
        "status" : 1,
        "severity" : 3,
        "resolution" : 3,
        "release" : 3,
        "assignedTo" : 3,
        "submittedAt" : 1,
        "submitter" : 1,
        "modifiedAt" : 1,
        "modifier" : 1,
        "startDate" : 3,
        "endDate" : 3,
        "plannedEffort" : 3,
        "spentEffort" : 3,
        "spentEstimatedHours" : 1,
        "description" : 3,
        "descFormat" : 3,
        "comments" : 3
      
    }


After having set all additional "item" properties, you create the tracker item via:

POST /item


If you do not have any item attachments to upload, then the body simply contains the item object, otherwise the item to create must be in the part named "body" of a multipart request and each attachment must be an extra part.

For example: Create the item with an initial comment and two attachments:

POST https://hostname/cb/rest/item
Authorization: (Data not shown)
Accept: application/json
Accept-Language: en
Content-Type: multipart/form-data; boundary=--MULTIPART-BOUNDARY--
Content-Length: 29278

----MULTIPART-BOUNDARY--
Content-Disposition: form-data; name="body"
Content-type: application/json; charset=utf-8

{
  "name"        : "Add dimmer function to light switch",
  "tracker"     : "/project/Test/tracker/Tasks",
  "status"      : "New",
  "priority"    : "High",
  "assignedTo"  : "/role/Developer",
  "description" : "When turning the on/off switch in the on position to the left or right, the light must get darker/brighter.",
  "descFormat"  : "Plain",
  "comments"    : [ {
		    "comment"       : "This is an __example__ comment with two attachments",
		    "commentFormat" : "Wiki",
		    "attachments"   : [ { "name" : "file1.png" }, { "name" : "file2.jpg" } ]
		  } ]
}
----MULTIPART-BOUNDARY--
Content-Disposition: form-data; name="file1.png"; filename="file1.png"
Content-Type: image/png

(Binary data not shown)
----MULTIPART-BOUNDARY--
Content-Disposition: form-data; name="file2.jpg"; filename="file2.jpg"
Content-Type: image/jpg

(Binary data not shown)
----MULTIPART-BOUNDARY----

Submit a new sub/child item of an already existing tracker/category item

First you have to get the schema and a pre-initialized object for a new child of the specified item:

GET {itemURI}/newChild

The rest is equivalent to creating a new top-level tracker/category item above.

Edit an existing item

For tracker/category items with a Finite State Machine, editing means updating properties within the context of the current status. To change the status, you must execute a state transition (see below).

First you have to get the schema and object for editing the item:

GET {itemURI}/edit


The response contains 3 properties:

  • "item" is the item object to edit, with it's current property values.
  • "type" is the JSON schema to edit properties of the "item".
  • "permissions" defines per schema property, whether the current user can change/edit the property value (3) or not (1).


After having modified "item" properties, you update the item via:

PUT /item


If you do not have any additional attachments to upload, then the body simply contains the item URI and the properties to update, otherwise the item URI and updated properties must be in the part named "body" of a multipart request and each new attachment must be an extra part.

The following is a simple example for updating a single field.

For example GET {itemURI}/edit returns something like the JSON below:

{
  "item" : {
    "uri" : "/item/1234",
    "version" : 1,
    "tracker" : {
      "project" : {
        "uri" : "/project/1",
        "name" : "Intland Software's Scrum Template"
      },
      "uri" : "/tracker/5678",
      "name" : "Requirements"
    },
    "name" : "Test",
    "status" : {
      "id" : 1,
      "name" : "New"
    },
    "submitter" : {
      "uri" : "/user/1",
      "name" : "bond"
    },
    "submittedAt" : "2017-04-19T13:52:42+02:00",
    "modifier" : {
      "uri" : "/user/1",
      "name" : "bond"
    },
    "modifiedAt" : "2017-04-19T13:52:42+02:00",
    "description" : "This is a test.",
    "descFormat" : "Wiki"
  },
  "type" : {
    "title" : "Requirement",
    "plural" : "Requirements",
    "description" : "Requirements Specification",
    "properties" : {
      "uri" : {
        "title" : "URI",
        "type" : "string",
        "format" : "uri"
      },

	.
	.
	.

}

Just to update the Description field, send the following JSON in the body of PUT /item request.

{
    "uri" : "/item/1234",
    "description" : "This description has been updated via REST API."

}

Get the possible state transitions of an item

GET {itemURI}/transitions


Returns an array of the possible state transitions (schema: "/transition/schema") in the current item status, e.g.

GET https://hostname/cb/rest/item/1000/transitions
[ {
  "uri" : "/transition/81",
  "name" : "Start",
  "descFormat" : "Plain"
}, {
  "uri" : "/transition/83",
  "name" : "Complete",
  "descFormat" : "Plain"
} ]

Execute a state transition

To execute a state transition for an item, you first have to get the schema and a pre-initialized object for the item and transition target status:

GET {itemURI}/transition/{transitionId} 


For example:

GET https://hostname/cb/rest/item/1000/transition/81

The response contains 4 properties:

  • "transition" (schema: "/transition/schema") is the requested state transition, e.g.
      "transition" : {
        "uri" : "/transition/81",
        "tracker" : {
          "uri" : "/tracker/1033",
          "name" : "Tasks"
        },
        "name" : "Start",
        "descFormat" : "Plain",
        "fromStatus" : {
          "id" : 1,
          "name" : "New"
        },
        "toStatus" : {
          "id" : 3,
          "name" : "In progress"
        }
      
    }
  • "item"is the item object, where "status" already reflects the transition target status, and any transition specific default values have been applied, e.g.
      "item" : {
        "uri" : "/item/1000",
        "version" : 1,
        "tracker" : {
          "project" : {
            "uri" : "/project/1",
            "name" : "Test"
          },
          "uri" : "/tracker/1033",
          "name" : "Tasks"
        },
        "subject" : {
          "uri" : "/item/1002",
          "name" : "The light must be dimmable"
        },
        "priority" : {
          "id" : 2,
          "name" : "High"
        },
        "name" : "Add dimmer function to light switch",
        "status" : {
          "id" : 3,
          "name" : "In progress"
        },
        "submittedAt" : "2013-03-12T14:38:06+01:00",
        "submitter" : {
          "uri" : "/user/1",
          "name" : "bond"
        },
        "modifiedAt" : "2013-03-12T14:38:59+01:00",
        "modifier" : {
          "uri" : "/user/1",
          "name" : "bond"
        },
        "description" : "When turning the on/off switch in the on position to the left or right, the light must get darker/brighter.",
        "descFormat" : "Wiki",
        "comments" : [ {
          "uri" : "/item/1000/comment/1047",
          "version" : 1,
          "depth" : 0,
          "createdAt" : "2013-03-12T14:38:59+01:00",
          "createdBy" : {
            "uri" : "/user/1",
            "name" : "bond"
          },
          "modifiedAt" : "2013-03-12T14:38:59+01:00",
          "modifier" : {
            "uri" : "/user/1",
            "name" : "bond"
          },
          "comment" : "This is an __example__ comment with two attachments",
          "commentFormat" : "Wiki",
          "attachments" : [ {
            "uri" : "/item/1000/attachment/1047",
            "version" : 1,
            "name" : "file1.png",
            "size" : 406,
            "modifiedAt" : "2013-03-12T14:38:59+01:00",
            "modifier" : {
              "uri" : "/user/1",
              "name" : "bond"
            }
          }, {
            "uri" : "/item/1000/attachment/1048",
            "version" : 1,
            "name" : "file2.jpg",
            "size" : 17828,
            "modifiedAt" : "2013-03-12T14:38:59+01:00",
            "modifier" : {
              "uri" : "/user/1",
              "name" : "bond"
            }
          } ]
        } ]
      
    }
  • "type" is the JSON schema to edit properties of the "item".
  • "permissions" defines per schema property, whether the current user can change/edit the property value (3) or not (1).


After having optionally modified additional "item" properties, you update the tracker item via:

PUT /item


If you do not have any additional attachments to upload, then the body must contain the "item" object, otherwise the "item" object must be in the part named "body" of a multipart request and each new attachment must be an extra part.

For example: Execute the transition with a comment and add an additional attachment:

PUT https://hostname/cb/rest/item
Authorization: (Data not shown)
Accept: application/json
Accept-Language: en
Content-Type: multipart/form-data; boundary=--MULTIPART-BOUNDARY--
Content-Length: 43278

----MULTIPART-BOUNDARY--
Content-Disposition: form-data; name="body"
Content-type: application/json; charset=utf-8

{
    "uri" : "/item/1000",
    "version" : 1,
    "tracker" : {
      "project" : {
        "uri" : "/project/1",
        "name" : "Test"
      },
      "uri" : "/tracker/1033",
      "name" : "Tasks"
    },
    "priority" : {
      "id" : 1,
      "name" : "Highest"
    },
    "name" : "Add dimmer function to light switch",
    "status" : {
      "id" : 3,
      "name" : "In progress"
    },
    "submittedAt" : "2013-03-12T14:38:06+01:00",
    "submitter" : {
      "uri" : "/user/1",
      "name" : "bond"
    },
    "modifiedAt" : "2013-03-12T14:38:59+01:00",
    "modifier" : {
      "uri" : "/user/1",
      "name" : "bond"
    },
    "description" : "When turning the on/off switch in the on position to the left or right, the light must get darker/brighter.",
    "descFormat" : "Wiki",
    "comments" : {
      "comment" : "Starting work is absolutely necessary, in order to get things done ;-)",
      "commentFormat" : "Plain",
      "attachments" : { "name" : "ToDo.doc" }
     }
}
----MULTIPART-BOUNDARY--
Content-Disposition: form-data; name="ToDo.doc"; filename="ToDo.doc"
Content-Type: application/msword

(Binary data not shown)
----MULTIPART-BOUNDARY----

In order to add new comments/attachments, simply add them to the "attachments" array property as shown above. It is not necessary (even preferrable) to not re-send existing comments in the PUT /item request. This does not harm, because you cannot update or delete comments via PUT /item, only via the special requests below.

Add a new item comment (plus attachments)

POST {itemURI}/comment


If you only want to add a comment without attachments, then the body simply contains the comment object, otherwise the comment object must be in the part named "body" of a multipart request and each new attachment must be an extra part.

For example: Add a comment, which is a reply to a previous comment, without attachments:

POST https://hostname/cb/rest/item/1000/comment
{
  "replyTo" : "/item/1000/comment/1049",
  "comment" : "Now, that we've got so far, we should also bring it to an end !"

}

Update an existing item comment (including attachments)

PUT {itemURI}/comment


If you only want to modify a comment, then the body simply contains the comment uri and the comment text, otherwise the comment object must be in the part named "body" of a multipart request and each attachment to add or replace must be an extra part.

For example: Add a picture to the comment and also embed the picture into the comment text (via a Wiki image reference).

PUT https://hostname/cb/rest/item/1000/comment
Authorization: (Data not shown)
Accept: application/json
Accept-Language: en
Content-Type: multipart/form-data; boundary=--MULTIPART-BOUNDARY--
Content-Length: 43278

----MULTIPART-BOUNDARY--
Content-Disposition: form-data; name="body"
Content-type: application/json; charset=utf-8

{
    "uri"           : "/item/1000/comment/1050",
    "version"       : 1,
    "comment"       : "Now, that we've got so far, we should also bring it to an end ! [!cube.png!]",
    "commentFormat" : "Wiki",
    "attachments"   : { "name" : "cube.png" }
}
----MULTIPART-BOUNDARY--
Content-Disposition: form-data; name="cube.png"; filename="cube.png"
Content-Type: image/png

(Binary data not shown)
----MULTIPART-BOUNDARY----

Delete an existing item comment (including attachments)

DELETE {itemCommentURI} 

This will also delete all replies to the comment (recursively).

Add new item attachments

POST {itemURI}/attachment

This is a special variant to attach files without a comment. The request must be a multipart request, one part per file to attach. No "body" part.

Get the content of a file attached to an item

GET {itemAttachmentURI} 

For example:

GET https://hostname/cb/rest/item/1000/attachment/1047

This will return the content of the attached file (in the example "file1.png") in the response body (incl. file name and content type).

Get the content of a file attached to an item by name

You can also get the attachments of an item by name, just use the attachment name as last part of the uri.

For example:

GET https://hostname/cb/rest/item/1000/attachment/file1.png

This will return the content of the attached file named "file1.png" in the response body (incl. file name and content type).

Update the content of a file attached to an item

PUT {itemAttachmentURI} 

The request body must contain the new file content (either singlepart or multipart with one part).

Remove a file attached to an item

REMOVE {itemAttachmentURI} 

Get the schema for an item

GET {itemURI}/schema

Get information about an item

GET {itemURI} 

Get the item history schema

GET /item/history/schema

Get the change history of an item

GET {itemURI}/history


For example:

GET https://hostname/cb/rest/item/1001/history
[ {
  "version" : 1,
  "submittedAt" : "2013-03-20T10:52:43+01:00",
  "submitter" : {
    "uri" : "/user/1",
    "name" : "bond"
  },
  "transition" : {
    "uri" : "/transition/null",
    "name" : "Submit",
    "descFormat" : "Plain"
  },
  "changes" : [ ]
}, {
  "version" : 2,
  "submittedAt" : "2013-03-20T10:52:44+01:00",
  "submitter" : {
    "uri" : "/user/1",
    "name" : "bond"
  },
  "transition" : {
    "uri" : "/transition/232",
    "name" : "Design",
    "descFormat" : "Plain"
  },
  "changes" : [ {
    "field" : "status",
    "oldValue" : {
      "id" : 1,
      "name" : "New"
    },
    "newValue" : {
      "id" : 2,
      "name" : "In Design"
    }
  } ]
} ]

Get the outline of all sub-items of an item (since CB-7.9.0)

GET {itemURI}/outline[?query]
Parameter Type Required Meaning
paragraph boolean false Whether to also return the paragraph/chapter number of each sub item. Default is false.
flat boolean false Whether to return the outline as a flat list, where children directly follow their parent (true).
Default is false, which returns a tree.
depth int false The maximum depth of the outline/hierarchy to return. A depth of 0 only returns the direct child items. Default is unlimited (full depth).

Get the children (sub items) of an item

GET {itemURI}/children


This returns fully populated objects for all children of the specified item, in contrast to the "children" property of the item, that only contains children reference information.

Get a summary of other items referring to an item

GET {itemURI}/references/summary[?query]
Parameter Type Required Meaning
type String No Comma-separated list of Tracker/CMDB (item) types (ids or names (singular or plural)) to only show referring items of these types. Default is any type.
status String No One of {"Open", "Closed", "Resolved", "Unresolved", "Successful", "Unsuccessful"} to only show referring items with this (meta) status. Default is any status.


E.g. Get a summary of items referencing the requirement /item/1001:

GET https://hostname/cb/rest/item/1001/references/summary
{
  "All" : [ {
    "field" : "Total",
    "label" : "Total",
    "total" : 2,
    "open" : 2,
    "overTime" : 0
  }, {
    "field" : "Subject",
    "label" : "Subject",
    "total" : 1,
    "open" : 1,
    "overTime" : 0
  }, {
    "field" : "Verifies",
    "label" : "Verifies",
    "total" : 1,
    "open" : 1,
    "overTime" : 0
  } ],
  "Tasks" : [ {
    "field" : "Total",
    "label" : "Total",
    "total" : 1,
    "open" : 1,
    "overTime" : 0
  }, {
    "field" : "Subject",
    "label" : "Subject",
    "total" : 1,
    "open" : 1,
    "overTime" : 0
  } ],
  "Test cases" : [ {
    "field" : "Total",
    "label" : "Total",
    "total" : 1,
    "open" : 1,
    "overTime" : 0
  }, {
    "field" : "Verifies",
    "label" : "Verifies",
    "total" : 1,
    "open" : 1,
    "overTime" : 0
  } ]

}


In this example, there are two items referring to the requirement:

  • one Test Case, that "Verifies" the requirement, and
  • one Task whose "Subject" is to implement the requirement.

Get other items referring to an item

GET {itemURI}/references[?query]
Parameter Type Required Meaning
field String No Name of a reference field, to only show referring items, that refer to this item via this field. Default is any field.
type String No Comma-separated list of Tracker/CMDB (item) types (ids or names (singular or plural)) to only show referring items of these types. Default is any type.
status String No One of {"Open", "Closed", "Resolved", "Unresolved", "Successful", "Unsuccessful"} to only show referring items with this (meta) status. Default is any status.


E.g. Get all items (any type, any status) referencing the requirement /item/1001via any field:

GET https://hostname/cb/rest/item/1001/references
[ {
  "uri" : "/item/1004",
  "version" : 1,
  "field" : [ "verifies" ],
  "tracker" : {
    "uri" : "/category/1027",
    "name" : "Test Cases"
  },
  "priority" : {
    "id" : 2,
    "name" : "High"
  },
  "name" : "Test dimmer switch",
  "status" : {
    "id" : 1,
    "name" : "New"
  },
  "type" : {
    "id" : 3,
    "name" : "Functional"
  },
  "submittedAt" : "2013-03-20T11:06:53+01:00",
  "submitter" : {
    "uri" : "/user/1",
    "name" : "bond"
  },
  "modifiedAt" : "2013-03-20T11:06:53+01:00",
  "modifier" : {
    "uri" : "/user/1",
    "name" : "bond"
  },
  "verifies" : [ {
    "uri" : "/item/1002",
    "name" : "The light must be dimmable"
  } ],
  "preAction" : "Prepare the test environment",
  "testSteps" : [ [ "Switch on", "Light is on", true ], [ "Turn dimmer", "Its getting brighter or darker", false ], [ "Switch off", "Light is off", true ] ],
  "postAction" : "Cleanup the test environment",
  "description" : "Test dimmer switch",
  "descFormat" : "Wiki"
}, {
  "uri" : "/item/1003",
  "version" : 1,
  "field" : [ "subject" ],
  "tracker" : {
    "uri" : "/tracker/1033",
    "name" : "Tasks"
  },
  "priority" : {
    "id" : 2,
    "name" : "High"
  },
  "name" : "Add dimmer function to light switch",
  "status" : {
    "id" : 1,
    "name" : "New"
  },
  "subject" : {
    "uri" : "/item/1002",
    "name" : "The light must be dimmable"
  },
  "severity" : {
    "id" : 2,
    "name" : "Critical"
  },
  "assignedTo" : [ {
    "uri" : "/role/2",
    "name" : "Developer"
  } ],
  "submittedAt" : "2013-03-20T11:04:06+01:00",
  "submitter" : {
    "uri" : "/user/1",
    "name" : "bond"
  },
  "modifiedAt" : "2013-03-20T11:04:06+01:00",
  "modifier" : {
    "uri" : "/user/1",
    "name" : "bond"
  },
  "description" : "When turning the on/off switch in the on position to the left or right, the light must get darker/brighter.",
  "descFormat" : "Wiki"
} ]

Get other items related to an item

GET {itemURI}/relatedIssues/page/{pageNo} 
Parameter Type Required Meaning
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.

Get a summary of all items related to a user

GET {userURI}/item/summary[?query] 
Parameter Type Required Meaning
role String No Comma-separated list of item member fields (ids or names), that must refer to the user (if onlyDirect=true) or to a role owned by the user (if onlyDirect=false), e.g. submitter, assignee, owner, supervisor.
type String No Comma-separated list of Tracker/CMDB (item) types (ids or names (singular or plural)) to only show referring items of these types. Default is any type.
status String No One of {"Open", "Closed", "Resolved", "Unresolved", "Successful", "Unsuccessful"} to only show referring items with this (meta) status. Default is any status.
newerThen String No A timestamp, to only return items that were created/modified after this date and time.
You can specify a relative timestamp as "[{This | Last [n]}] [{minute | hour | day | week | month | quarter | year}[s]]", where "Today" is a synonym for "This day" and "Yesterday" is a synonym for "Last day", e.g. "Last week", "This month", "Last 2 days"; or as "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".
An absolute timestamp is specified in ISO 8601 format, e.g. "2013-03-12T14:38:06+01:00".
onlyDirect boolean No Whether to only show items directly related to the user (true) or also items indirectly related via the user's role (false). Default is false.


E.g. Get summary of all unresolved bugs and tasks assigned to the user bond directly or indirectly

GET https://hostname/cb/rest/user/bond/item/summary?role=assigned to&type=Bugs,Tasks&status=Unresolved
{
  "Total" : {
    "total" : 2,
    "today" : 0,
    "tomorrow" : 0,
    "next7Days" : 0
  },
  "assignedTo" : {
    "total" : 2,
    "today" : 0,
    "tomorrow" : 0,
    "next7Days" : 0
  

}

}

Get items by cbQL query string

GET {queryURI}/page/{page}[?queryString]
Parameter Type Required Meaning
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.
queryString String Yes A valid cbQL query string

E.g. Get the first page of work items assigned to a user.

https://hostname/cb/rest/query/page/1?queryString=%20assignedTo%20=%20%27gabor.toth%27

Alternatively from codeBeamer 9.3.0:

POST {queryURI}/page/{page}

Get the first page of work items assigned to a user:

https://hostname/cb/rest/query/page/1

Request body:

{
 "pageSize": 25,
 "queryString": "assignedTo='gabor.toth'"
}

Get items by query id

Returns the result of a query specified by its id number.
GET /query/{queryId}/page/{pageNo}?pagesize={pageSize} 
Parameter Type Required Meaning
pageNo int Yes Number of the result page to return. First page has number 1.
pageSize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.
queryId int Yes A valid cbQL query id

For example:

https://hostname/cb/rest/query/149620/page/1?pagesize=10 

Get items related to a user

GET {userURI}/items/page/{page}[?query]
Parameter Type Required Meaning
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.
role String No Comma-separated list of item member fields (ids or names), that must refer to the user (if onlyDirect=true) or to a role owned by the user (if onlyDirect=false), e.g. submitter, assignee, owner, supervisor.
type String No Comma-separated list of Tracker/CMDB (item) types (ids or names (singular or plural)) to only show referring items of these types. Default is any type.
status String No One of {"Any status", "Open", "Closed", "Resolved", "Unresolved", "Successful", "Unsuccessful"} to only show referring items with this (meta) status. Default is "Unresolved".
newerThen String No A timestamp, to only return items that were created/modified after this date and time.
You can specify a relative timestamp as "[{This | Last [n]}] [{minute | hour | day | week | month | quarter | year}[s]]", where "Today" is a synonym for "This day" and "Yesterday" is a synonym for "Last day", e.g. "Last week", "This month", "Last 2 days"; or as "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".
An absolute timestamp is specified in ISO 8601 format, e.g. "2013-03-12T14:38:06+01:00".
onlyDirect boolean No Whether to only show items directly related to the user (true) or also items indirectly related via the user's role (false). Default is false.


E.g. Get first page of all unresolved bugs and tasks assigned to the user bond directly or indirectly

GET https://hostname/cb/rest/user/bond/items/page/1?role=assigned to&type=Bugs,Tasks&status=Unresolved
{
  "page" : 1,
  "size" : 100,
  "total" : 2,
  "items" : [ {
    "uri" : "/item/1009",
    "version" : 1,
    "tracker" : {
      "project" : {
        "uri" : "/project/1",
        "name" : "Test"
      },
      "uri" : "/tracker/1032",
      "name" : "Bugs"
    },
    "priority" : {
      "id" : 5,
      "name" : "Lowest"
    },
    "name" : "Documentation is not complete",
    "status" : {
      "id" : 1,
      "name" : "New"
    },
    "submittedAt" : "2013-03-20T15:03:21+01:00",
    "submitter" : {
      "uri" : "/user/1",
      "name" : "bond"
    },
    "modifiedAt" : "2013-03-20T15:03:21+01:00",
    "modifier" : {
      "uri" : "/user/1",
      "name" : "bond"
    },
    "assignedTo" : [ {
      "uri" : "/user/1",
      "name" : "bond"
    } ],
    "description" : "Finish it!",
    "descFormat" : "Wiki"
  }, {
    "uri" : "/item/1007",
    "version" : 1,
    "tracker" : {
      "project" : {
        "uri" : "/project/1",
        "name" : "Test"
      },
      "uri" : "/tracker/1033",
      "name" : "Tasks"
    },
    "priority" : {
      "id" : 2,
      "name" : "High"
    },
    "name" : "Check Rest API documentation",
    "status" : {
      "id" : 1,
      "name" : "New"
    },
    "assignedTo" : [ {
      "uri" : "/role/1",
      "name" : "Project Admin"
    } ],
    "submittedAt" : "2013-03-20T15:02:31+01:00",
    "submitter" : {
      "uri" : "/user/1",
      "name" : "bond"
    },
    "modifiedAt" : "2013-03-20T15:02:31+01:00",
    "modifier" : {
      "uri" : "/user/1",
      "name" : "bond"
    },
    "description" : "Check Rest API documentation",
    "descFormat" : "Wiki"
  } ]

}

Get a summary of all items related to a user, grouped per project

GET {userURI}/projects/item/summary[?query] 
Parameter Type Required Meaning
role String No Comma-separated list of item member fields (ids or names), that must refer to the user (if onlyDirect=true) or to a role owned by the user (if onlyDirect=false), e.g. submitter, assignee, owner, supervisor.
type String No Comma-separated list of Tracker/CMDB (item) types (ids or names (singular or plural)) to only show referring items of these types. Default is any type.
status String No One of {"Open", "Closed", "Resolved", "Unresolved", "Successful", "Unsuccessful"} to only show referring items with this (meta) status. Default is any status.
newerThen String No A timestamp, to only return items that were created/modified after this date and time.
You can specify a relative timestamp as "[{This | Last [n]}] [{minute | hour | day | week | month | quarter | year}[s]]", where "Today" is a synonym for "This day" and "Yesterday" is a synonym for "Last day", e.g. "Last week", "This month", "Last 2 days"; or as "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".
An absolute timestamp is specified in ISO 8601 format, e.g. "2013-03-12T14:38:06+01:00".
onlyDirect boolean No Whether to only show items directly related to the user (true) or also items indirectly related via the user's role (false). Default is false.

Get a summary of items related to a user in a specific project

GET {userURI}{projectURI}/item/summary[?query] 
GET {projectURI}{userURI}/item/summary[?query] 
Parameter Type Required Meaning
role String No Comma-separated list of item member fields (ids or names), that must refer to the user (if onlyDirect=true) or to a role owned by the user (if onlyDirect=false), e.g. submitter, assignee, owner, supervisor.
type String No Comma-separated list of Tracker/CMDB (item) types (ids or names (singular or plural)) to only show referring items of these types. Default is any type.
status String No One of {"Open", "Closed", "Resolved", "Unresolved", "Successful", "Unsuccessful"} to only show referring items with this (meta) status. Default is any status.
newerThen String No A timestamp, to only return items that were created/modified after this date and time.
You can specify a relative timestamp as "[{This | Last [n]}] [{minute | hour | day | week | month | quarter | year}[s]]", where "Today" is a synonym for "This day" and "Yesterday" is a synonym for "Last day", e.g. "Last week", "This month", "Last 2 days"; or as "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".
An absolute timestamp is specified in ISO 8601 format, e.g. "2013-03-12T14:38:06+01:00".
onlyDirect boolean No Whether to only show items directly related to the user (true) or also items indirectly related via the user's role (false). Default is false.

Get items related to a user in a specific project

GET {userURI}{projectURI}/items/page/{page}[?query]
GET {projectURI}{userURI}/items/page/{page}[?query]
Parameter Type Required Meaning
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.
role String No Comma-separated list of item member fields (ids or names), that must refer to the user (if onlyDirect=true) or to a role owned by the user (if onlyDirect=false), e.g. submitter, assignee, owner, supervisor.
type String No Comma-separated list of Tracker/CMDB (item) types (ids or names (singular or plural)) to only show referring items of these types. Default is any type.
status String No One of {"Any status", "Open", "Closed", "Resolved", "Unresolved", "Successful", "Unsuccessful"} to only show referring items with this (meta) status. Default is "Unresolved".
newerThen String No A timestamp, to only return items that were created/modified after this date and time.
You can specify a relative timestamp as "[{This | Last [n]}] [{minute | hour | day | week | month | quarter | year}[s]]", where "Today" is a synonym for "This day" and "Yesterday" is a synonym for "Last day", e.g. "Last week", "This month", "Last 2 days"; or as "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".
An absolute timestamp is specified in ISO 8601 format, e.g. "2013-03-12T14:38:06+01:00".
onlyDirect boolean No Whether to only show items directly related to the user (true) or also items indirectly related via the user's role (false). Default is false.

Get a summary of items related to a user in a specific tracker/category

GET {userURI}{trackerURI}/item/summary[?query] 
GET {trackerURI}{userURI}/item/summary[?query] 
GET {userURI}{categoryURI}/item/summary[?query] 
GET {categoryURI}{userURI}/item/summary[?query] 
Parameter Type Required Meaning
role String No Comma-separated list of item member fields (ids or names), that must refer to the user (if onlyDirect=true) or to a role owned by the user (if onlyDirect=false), e.g. submitter, assignee, owner, supervisor.
status String No One of {"Open", "Closed", "Resolved", "Unresolved", "Successful", "Unsuccessful"} to only show referring items with this (meta) status. Default is any status.
newerThen String No A timestamp, to only return items that were created/modified after this date and time.
You can specify a relative timestamp as "[{This | Last [n]}] [{minute | hour | day | week | month | quarter | year}[s]]", where "Today" is a synonym for "This day" and "Yesterday" is a synonym for "Last day", e.g. "Last week", "This month", "Last 2 days"; or as "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".
An absolute timestamp is specified in ISO 8601 format, e.g. "2013-03-12T14:38:06+01:00".
onlyDirect boolean No Whether to only show items directly related to the user (true) or also items indirectly related via the user's role (false). Default is false.

Get items related to a user in a specific tracker/category

GET {userURI}{trackerURI}/items/page/{page}[?query]
GET {trackerURI}{userURI}/items/page/{page}[?query]
GET {userURI}{categoryURI}/items/page/{page}[?query]
GET {categoryURI}{userURI}/items/page/{page}[?query]
Parameter Type Required Meaning
page int Yes Number of the result page to return. First page has number 1.
pagesize int No Page size in number of items, valid range is [1 .. 500]. Default is 100.
role String No Comma-separated list of item member fields (ids or names), that must refer to the user (if onlyDirect=true) or to a role owned by the user (if onlyDirect=false), e.g. submitter, assignee, owner, supervisor.
status String No One of {"Any status", "Open", "Closed", "Resolved", "Unresolved", "Successful", "Unsuccessful"} to only show referring items with this (meta) status. Default is "Unresolved".
newerThen String No A timestamp, to only return items that were created/modified after this date and time.
You can specify a relative timestamp as "[{This | Last [n]}] [{minute | hour | day | week | month | quarter | year}[s]]", where "Today" is a synonym for "This day" and "Yesterday" is a synonym for "Last day", e.g. "Last week", "This month", "Last 2 days"; or as "hh[:mm[:ss]]"; or as "n {h[our] | m[in[ute]] | s[ec[ond]]}[s]", e.g. "30 min", "6 hours".
An absolute timestamp is specified in ISO 8601 format, e.g. "2013-03-12T14:38:06+01:00".
onlyDirect boolean No Whether to only show items directly related to the user (true) or also items indirectly related via the user's role (false). Default is false.

Render Wiki markup to HTML in the context of a work/configuration item

POST /item/{id}/wiki2html 

Since CB-7.7.1.
The request body contains the Wiki markup to render.
The response body contains the rendered text/html.

Use this method to render item Wiki descriptions or item Wiki fields into HTML.

Item Reviews

Tracker item reviews is a feature, that was introduced in CB-8.0.

Get item review schema

GET /item/review/schema 

Start a new item review

POST /item/review 

This is equivalent to the workflow action Start a new review.
The request body must contain the review specification, that consists of

  • the item to review,
  • the review configuration and
  • the list of reviewers (users)

E.g.: Create a new review for /item/1000, where

  • Users bond and klaus should be the reviewers.
  • Reviewers must enter their password in order to submit his vote (signature: 1).
    • signature: 0
      No extra reviewer authentication necessary (This is the default)
    • signature: 1
      Reviewers must enter their password
    • signature: 2
      Reviewers are require to enter their username and password.
  • The review should be considered as rejected, if more than one reviewer rejects.
    {
      "item" : {
        "uri"  : "/item/1000",
        "name" : "Provide a new item review functionality"
      },
      "config" : {
        "signature" : 1,
        "rejects"   : 1
      },
      "reviewers" : [{
        "uri"  : "/user/1",
        "name" : "bond"
      }, {
        "uri"  : "/user/3",
        "name" : "klaus"
      }]
    }

Update the review configuration

PUT /item/review 

The request body must contain the URI and configuration of the review to update.

E.g. disable extra reviewer authentication and explicitly specify number of required approvals:

{
   "uri" : "/item/1000/version/2/review",
   "config" : {
      "signature" : 0,
      "approvals" : 2
   

}

}

Please note, that the number of approvals (positive votes) requested, will be adjusted to match the actual number of reviewers and the number of allowed rejects.

In the example above, there are 2 reviewers and 1 allowed reject, so the actual number of necessary approvals will be 1 (see below).

Get all reviews for an item

GET {itemURI}/reviews 

The result is a list of item review summary/statistics.

E.g.: GET https://hostname/cb/rest/item/1000/reviews

[ {
  "uri" : "/item/1000/version/2/review",
  "item" : {
    "uri" : "/item/1000",
    "name" : "Provide a new item review functionality",
    "version" : 2,
    "status" : {
      "id" : 3,
      "name" : "Waiting for approval"
    }
  },
  "config" : {
    "approvals" : 1,
    "rejects" : 1,
    "signature" : 0,
    "closed" : false
  },
  "voters" : 2,
  "votes" : 0,
  "approvals" : 0,
  "approved" : false,
  "rejected" : false
} ]

Get the summary/statistics about a specific item revision review

GET {itemURI}/version/{version}/review 

Get all reviewers/votes for an item review

GET {itemURI}/version/{version}/reviewers 


E.g.: GET https://hostname/cb/rest/item/1000/version/2/reviewers

[ {
  "reviewer" : {
    "uri" : "/user/1",
    "name" : "bond"
  },
  "reviewedAt" : "2016-07-18T16:38:45+02:00",
  "rating" : 1
}, {
  "reviewer" : {
    "uri" : "/user/3",
    "name" : "klaus"
  }
} ]

Submit an item review (vote)

POST {itemURI}/version/{version}/review 

The request body must contain the reviewer URI and his/her vote/rating (0=rejected, 1=approved) for the specified item revision, e.g.

{
   "reviewer": "/user/bond"
   "rating"  : 1

}

If the submitted vote was a decisive vote and an appropriate designated target status was defined, e.g. "approvedStatus", then the response will contain all necessary information to execute this state transition immediately (see response of Execute a state transition).

Get all item reviews for a specific reviewer/user

GET {userURI}/item/reviews[?reviewed={true|false}] 

The boolean parameter reviewed is optional. The default is to return submitted (true) and pending (false) reviews.

E.g.: GET https://hostname/cb/rest/user/bond/item/reviews

[ {
  "uri" : "/item/1000/version/2/user/1/review",
  "item" : {
    "uri" : "/item/1000",
    "name" : "Provide a new item review functionality",
    "version" : 2,
    "status" : {
      "id" : 3,
      "name" : "Waiting for approval"
    }
  },
  "reviewedAt" : "2016-07-18T16:38:45+02:00",
  "rating" : 1
} ]

Get all reviews for a specific reviewer/user and item

GET {userURI}/{itemURI}/reviews[?reviewed={true|false}] 
GET {itemURI}/{userURI}/reviews[?reviewed={true|false}] 

Get the vote/rating of a specific reviewer/user for a specific item revision

GET {userURI}/{itemURI}/version/{version}/review[?reviewed={true|false}] 
GET {itemURI}/version/{version}/{userURI}/review[?reviewed={true|false}] 

Test Management

Test Management is supported by REST API since CB 9.0.

Create a new TestSetRun

POST /testRun 

This REST API call will create a new TestSetRun from a TestSet or a group of TestCases, and generates all TestCaseRuns for them.

The request body can be null/empty, this case the TestSetRun will be automatically created in the first TestRun tracker in the same project where the TestSet or TestCases are.

Alternatively if you want to set the fields of the new TestSetRun then you can send these properties in the request body. To do this prepare the template of the new TestSetRun using the REST API new-item REST api call, and modify them as necessary.

This REST request can also contain these parameters:

Parameter name Value/Meaning
testSetId This should be a single integer id of the TestSet from this the TestRun is created
testCaseIds Multiple integer ids of the TestCases: the TestRun will run these TestCases
runOnlyAcceptedTestCases Boolean (true/false) if the TestSetRun will contain only the Accepted TestCases. If missing then this defaults to "false".

Note: that you must provide either {testSetId} or {testCaseIds} or otherwise the request will be rejected.

The respons will contain the created TestSetRun's JSON representation. An example is:

{
  "uri" : "/item/31686",
  "version" : 1,
  "tracker" : {
    "project" : {
      "uri" : "/project/31",
      "name" : "Best Tool29555764"
    },
    "uri" : "/tracker/48608",
    "name" : "Test Runs1498708521949"
  },
  "name" : "Quick Test Run for 5 Test Cases at Jun 29 2017",
  "submitter" : {
    "uri" : "/user/26",
    "name" : "username_1498708520199"
  },
  "modifier" : {
    "uri" : "/user/26",
    "name" : "username_1498708520199"
  },
  "submittedAt" : "2017-06-29T05:55:48+02:00",
  "modifiedAt" : "2017-06-29T05:55:48+02:00",
  "sequential" : false,
  "testCases" : [ [ [ {
    "uri" : "/item/31681",
    "name" : "TestCase #0"
  } ], null, null, null ], [ [ {
    "uri" : "/item/31682",
    "name" : "TestCase #1"
  } ], null, null, null ], [ [ {
    "uri" : "/item/31683",
    "name" : "TestCase #2"
  } ], null, null, null ], [ [ {
    "uri" : "/item/31684",
    "name" : "TestCase #3"
  } ], null, null, null ], [ [ {
    "uri" : "/item/31685",
    "name" : "TestCase #4"
  } ], null, null, null ] ],
  "descFormat" : "Plain",
  "children" : [ {
    "uri" : "/item/31687",
    "name" : "Run of TestCase #0"
  }, {
    "uri" : "/item/31688",
    "name" : "Run of TestCase #1"
  }, {
    "uri" : "/item/31689",
    "name" : "Run of TestCase #2"
  }, {
    "uri" : "/item/31690",
    "name" : "Run of TestCase #3"
  }, {
    "uri" : "/item/31691",
    "name" : "Run of TestCase #4"
  } ]

}

Find TestCases of a TestSetRun

GET /testRun/{testRunId}/testCases 

Once you have a TestSetRun created by either using REST api or inside CB then you may want to query the TestCases inside the TestRun. This REST call will return them.

An example reponse is:

[ {
  "uri" : "/item/31681",
  "version" : 1,
  "tracker" : {
    "project" : {
      "uri" : "/project/31",
      "name" : "Best Tool29555764"
    },
    "uri" : "/category/48527",
    "name" : "Test Cases1498708521589"
  },
  "name" : "TestCase #0",
  "status" : {
    "id" : 4,
    "name" : "Accepted"
  },
  "submittedAt" : "2017-06-29T05:55:21+02:00",
  "submitter" : {
    "uri" : "/user/26",
    "name" : "username_1498708520199"
  },
  "modifiedAt" : "2017-06-29T05:55:21+02:00",
  "modifier" : {
    "uri" : "/user/26",
    "name" : "username_1498708520199"
  },
  "description" : "A sample TestCase",
  "descFormat" : "Plain"
}, {
  "uri" : "/item/31682",
  "version" : 1,
  "tracker" : {
    "project" : {
      "uri" : "/project/31",
      "name" : "Best Tool29555764"
    },
    "uri" : "/category/48527",
    "name" : "Test Cases1498708521589"
  },
  "name" : "TestCase #1",
  "status" : {
    "id" : 4,
    "name" : "Accepted"
  },
  "submittedAt" : "2017-06-29T05:55:21+02:00",
  "submitter" : {
    "uri" : "/user/26",
    "name" : "username_1498708520199"
  },
  "modifiedAt" : "2017-06-29T05:55:21+02:00",
  "modifier" : {
    "uri" : "/user/26",
    "name" : "username_1498708520199"
  },
  "description" : "A sample TestCase",
  "descFormat" : "Plain"
}, {
  "uri" : "/item/31683",
  "version" : 1,
  "tracker" : {
    "project" : {
      "uri" : "/project/31",
      "name" : "Best Tool29555764"
    },
    "uri" : "/category/48527",
    "name" : "Test Cases1498708521589"
  },
  "name" : "TestCase #2",
  "status" : {
    "id" : 4,
    "name" : "Accepted"
  },
  "submittedAt" : "2017-06-29T05:55:21+02:00",
  "submitter" : {
    "uri" : "/user/26",
    "name" : "username_1498708520199"
  },
  "modifiedAt" : "2017-06-29T05:55:21+02:00",
  "modifier" : {
    "uri" : "/user/26",
    "name" : "username_1498708520199"
  },
  "description" : "A sample TestCase",
  "descFormat" : "Plain"
}, {
  "uri" : "/item/31684",
  "version" : 1,
  "tracker" : {
    "project" : {
      "uri" : "/project/31",
      "name" : "Best Tool29555764"
    },
    "uri" : "/category/48527",
    "name" : "Test Cases1498708521589"
  },
  "name" : "TestCase #3",
  "status" : {
    "id" : 4,
    "name" : "Accepted"
  },
  "submittedAt" : "2017-06-29T05:55:21+02:00",
  "submitter" : {
    "uri" : "/user/26",
    "name" : "username_1498708520199"
  },
  "modifiedAt" : "2017-06-29T05:55:21+02:00",
  "modifier" : {
    "uri" : "/user/26",
    "name" : "username_1498708520199"
  },
  "description" : "A sample TestCase",
  "descFormat" : "Plain"
}, {
  "uri" : "/item/31685",
  "version" : 1,
  "tracker" : {
    "project" : {
      "uri" : "/project/31",
      "name" : "Best Tool29555764"
    },
    "uri" : "/category/48527",
    "name" : "Test Cases1498708521589"
  },
  "name" : "TestCase #4",
  "status" : {
    "id" : 4,
    "name" : "Accepted"
  },
  "submittedAt" : "2017-06-29T05:55:21+02:00",
  "submitter" : {
    "uri" : "/user/26",
    "name" : "username_1498708520199"
  },
  "modifiedAt" : "2017-06-29T05:55:21+02:00",
  "modifier" : {
    "uri" : "/user/26",
    "name" : "username_1498708520199"
  },
  "description" : "A sample TestCase",
  "descFormat" : "Plain"
} ]

Set the result of a TestCase

POST /testRun/{testRunId}/result

Using this call you can set the result of a TestCase inside of a TestSetRun.

To use this:

  • The {testRunId} parameter must contain the id of the TestSetRun which will contain te Test result.
  • The request body can contain results of multiple TestCases in this form:
    {
       "testCaseId or testCaseRunId" : {
           "success": "true/PASSED or "false/FAILED" or "null/BLOCKED",
           "conclusion":  "optional conclusion text",
           "runTime": 123,
           "reportedBugIds": [1234,1235,1236]
       },
       "testCaseId#2": {
          ...
       
    }}

So the request body is a JSON object, where the:

  • The key is the id number of the TestCase or the id number of the TestCaseRun.
  • The value can contain the:
    • success is a boolean. "true" means PASSED, "false" means FAILED, "null" means BLOCKED. Alternatively you can use "PASSED"/"FAILED"/"BLOCKED" strings too.
    • conclusion is an optional string which is added to the TestRun as conclusion. This will be put to the "description" of the TestCaseRun.
    • runTime optional run-time in seconds
    • reportedBugIds is an optional array of integer ids of Bugs belong to the Test-result

As seen this request can update multiple TestCases/TestCaseRuns in one go. The request will return the updated TestCaseRun details as JSON response.

If all the TestCases in the TestSetRun has result then also the TestSetRun will become automatically Finished and its Result is automatically updated.

An example response is:

[ {
  "uri" : "/item/31687",
  "version" : 2,
  "parent" : {
    "uri" : "/item/31686",
    "name" : "Quick Test Run for 5 Test Cases at Jun 29 2017"
  },
  "tracker" : {
    "project" : {
      "uri" : "/project/31",
      "name" : "Best Tool29555764"
    },
    "uri" : "/tracker/48608",
    "name" : "Test Runs1498708521949"
  },
  "name" : "Run of TestCase #0",
  "status" : {
    "id" : 4,
    "name" : "Finished"
  },
  "result" : {
    "id" : 2,
    "name" : "Failed"
  },
  "completedAt" : "2017-06-29T06:01:18+02:00",
  "submitter" : {
    "uri" : "/user/26",
    "name" : "username_1498708520199"
  },
  "modifier" : {
    "uri" : "/user/26",
    "name" : "username_1498708520199"
  },
  "submittedAt" : "2017-06-29T05:55:48+02:00",
  "modifiedAt" : "2017-06-29T06:01:18+02:00",
  "sequential" : false,
  "testCases" : [ [ [ {
    "uri" : "/item/31681",
    "name" : "TestCase #0"
  } ], null, null, null ] ],
  "description" : "conclusion of TestCase #0\r\n//TEST_CASE_INDEX:0",
  "descFormat" : "Wiki"
} ]

Associations

Starting with CB-7.3, you can also manage assocations via the REST-API.
Associations establish ad-hoc relations between two codeBeamer entities, or between a codeBeamer entity and an external Web-Resource, identified via an URL.
Assocations have URIs of the form: "/association/{id}", where {id} is the internal unique association id/number.

Get the available association types

GET /association/types

All association types are predefined. You cannot create, update or delete association types, although new types may be introduced with new codeBeamer releases.

Get an association type

GET /association/type/{typeIdOrName} 

Get the immutable definition of an association type.

Get the association schema

GET /association/schema

Create a new association

POST /association

The request body must contain a valid association object with at least "from", "type" and either "to" (URI of codeBeamer entity) or "url" (of external WEB resource)), e.g.:

{
  "from"                : "/item/54252",
  "to"                  : "/item/75266",
  "type"                : "/association/type/depends",
  "propagatingSuspects" : true,
  "description"         : "This Test Case depends on the specified Use Case",
  "descFormat"          : "Plain"

}

Update association settings

You can only change "type", "description", "propagatingSuspects" and "suspected" of an association (the latter only if "propagatingSuspects" is true). The association endpoints are immutable.

PUT /association

The request body must contain the association URI and the properties to update, e.g. to clear the "suspected" flag of an association:

{
  "uri"       : "/association/96415",
  "suspected" : false

}

Delete an association

DELETE {associationURI} 

Get the change history of an association

GET {associationURI}/history 

This returns the change history of the specified association in descending order (last/head) revision first.

Get the associations of (and to) a codeBeamer entity

This gets all associations of (originating at) the specified codeBeamer entity, plus optionally, all associations pointing to this entity.

GET {entityURI}/associations[?query] 

Parameter Type Required Meaning
type String No Comma-separated list of association type ids or names. If present only associations of these types will be returned.
only String No PropagateSuspect, Suspected or both, to only return associations where "propagatingSuspects", "suspected" or both are true
not String No PropagateSuspect, Suspected or both, to exclude associations where "propagatingSuspects", "suspected" or both are true
inout boolean No If true, also associations pointing to the entity will be returned. Default is false.


E.g. Find all "depends" or "copy of" associations of and to the Use Case "/item/75266", where the "suspected" flag is set:

GET https://hostname/cb/rest/item/75266/associations?type=depends,copy of&only=Suspected&inout=true

Client side implementations

Because the REST API is completely platform independent, your are free to choose the development and runtime environment most suitable to you.

Support for HTTP, JSON and JSON Schema is available in almost any modern programming language/environment.

Any implementation examples given here or elsewhere do not mean that this is the preferred or best way to implement things, it's just one way to implement it.

Java sample implementation

We show a sample Java client for the REST API based on the Spring 3.2Rest Template.

Again: This is not the preferred or best Java implementation, it is just one way to implement it!

In the examples, we either use generic Java Maps or JSON objects, to represent objects as sparse sets of name/value pairs.
There are tools to convert JSON Schema into Java Classes, e.g. http://www.jsonschema2pojo.org/, but we do not recommend to do it that way (at least not for tracker/category item schemas), because these schemas can be extended and customized at run time, which would break any clients relying on a pre-compiled schema to class model.

The examples also assume, that a project with name "Test" already exists and that the user whose username and password are used for the REST API calls has the role "Project Admin" in the "Test" project.

Setup the REST API connection

final String restUrl 	= "http://localhost:8080/cb/rest";
final String username   = ...
final String password   = ...
final String authHeader = "Basic " + Base64.encode((username + ":" + password).getBytes("UTF-8"));

// Create a HttpRequestFactory that passes the required Basic "Authorization" header
final SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory() {
	@Override
	protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
		super.prepareConnection(connection, httpMethod);

		connection.setRequestProperty("Authorization", authHeader);
	}
};

// Create a RestTemplate that uses the pre-configured HttpRequestFactory
final RestTemplate restApi = new RestTemplate(requestFactory);

// We need two HttpMessageConverters for the Rest API:
// A JSON converter for singlepart messages and for multipart message parts with "Content-type: application/json"
MappingJacksonHttpMessageConverter jsonConverter = new MappingJacksonHttpMessageConverter();

// And a converter for Content-type: multipart/form-data
FormHttpMessageConverter multiPartConverter = new FormHttpMessageConverter();
multiPartConverter.addPartConverter(jsonConverter);

List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>(2);
converters.add(multiPartConverter);
converters.add(jsonConverter);

restApi.setMessageConverters(converters);

Create a new Test Case

// Get the necessary information to create a new test case
Map<String,Object> newTestCaseContext = restApi.getForObject(restUrl + "/project/Test/category/Test Cases/newItem", Map.class);

// Set additional test case attributes
Map<String,Object> testCaseAttrs = newTestCaseContext.get("item");

testCaseAttrs.put("name",        "Test dimmer switch");
testCaseAttrs.put("description", "Test the new dim function of the lights switch");
testCaseAttrs.put("priority",    "High");
testCaseAttrs.put("type",        "Functional");
testCaseAttrs.put("preAction",   "Prepare the test environment");
testCaseAttrs.put("postAction",  "Cleanup the test environment");
testCaseAttrs.put("testSteps",    Arrays.asList(
                                    Arrays.asList("Switch on",   "Light is on",                    Boolean.TRUE,  ""),
                                    Arrays.asList("Turn dimmer", "Its getting brighter or darker", Boolean.FALSE, ""),
                                    Arrays.asList("Switch off",  "Light is off",                   Boolean.TRUE,  "")
                                  ));
testCaseAttrs.put("comments",    Collections.singletonMap("comment", "I have to test this"));

// Now create the new Test Case
ObjectNode testCaseRef = restApi.postForObject(restUrl + "/item", testCaseAttrs, ObjectNode.class);

// Get URI of the newly created Test Case
String testCaseURI = testCaseRef.get("uri").asText();

Find unresolved Test Cases by category

ArrayNode newUnresolvedTestCases = restApi.getForObject(restUrl + "/project/Test/category/Test Cases/items?status=Unresolved&newerThen=10 min", ArrayNode.class);

Find Test Cases created by ourselves within the last 10min

ArrayNode myRecentlySubmittedTestCases = restApi.getForObject(restUrl + "/user/self/items?role=submitter&type=Test Case&newerThen=10 min", ArrayNode.class);

Execute a state transition on the new Test Case

// Get the next possible state transitions for the test case
ArrayNode transitions = restApi.getForObject(restUrl + testCaseURI + "/transitions", ArrayNode.class);

// Pick the first transition (not very useful, but this is only an example)
String transitionURI = transitions.get(0).get("uri").asText();

// Prepare transition execution
Map<String,Object> transitionContext = restApi.getForObject(restUrl + testCaseURI + transitionURI, Map.class);

// Add a comment with a single file attachment to the Test Case
Map<String,Object> comment = new LinkedHashMap<String,Object>(4);
comment.put("comment",       "__This__ is only for testing: Here goes the image: [!Image.jpg!]");
comment.put("commentFormat", "Wiki");
comment.put("attachments",   Collections.singletonMap("name", "Image.jpg"));

// Set additional attributes we want to change upon this state transition
Map<String,Object> testCaseAttrs = transitionContext.get("item");
testCaseAttrs.put("comments", comment);

// Because we have an attachment, we need a multipart message
MultiValueMap<String,Object> multipart = new LinkedMultiValueMap<String,Object>();

// The TestCase object goes into the "body" part
multipart.add("body", testCaseAttrs);

// The image file to attach goes into an extra part (we simply assume the "Image.jpg" file is in our class path)
multipart.add("Image.jpg", new ClassPathResource("Image.jpg", getClass());

// Execute the TestCase state transition
restApi.put(restUrl + "/item", multipart);

Add a reply to a previous comment on the Test Case

// Reload the Test Case object, in order to get accurate comments list
ObjectNode testCase = restApi.getForObject(restUrl + testCaseURI, ObjectNode.class);

// Now create a reply to the first comment on the TestCase
String firstCommentURI = testCase.get("comments").get(0).get("uri").asText();

// We simply reply to the first comment on the TestCase
Map<String,Object> reply = new LinkedHashMap<String,Object>(4);
reply.put("replyTo", firstCommentURI);
reply.put("comment", "Yes, I totally agree !");

// Now post the reply
URI replyURI = restApi.postForLocation(restUrl + testCaseURI + "/comment", reply);

Update an existing comment on the Test Case

We use the reply from the previous example, because we already know it's URI.

// We need a multipart request, because we add an additional attachment
LinkedMultiValueMap<String,Object> update = new LinkedMultiValueMap<String,Object>(4);

// The comment to update goes into the "body" part (We only need the URI, because we don't want to update other comment properties)
update.add("body", Collections.singletonMap("uri", replyURI));

// The new image to attach goes into an extra part
update.add("cube.png", new ClassPathResource("cube.png", getClass()));

// Update the reply
restApi.put(restUrl + testCaseURI + "/comment", update);

Download a file attached to the Test Case

In order to download files with the Rest Template, we need a helper class to extract a downloaded file from a ClientHttpResponse:

public class FileExtractor implements ResponseExtractor<File> {
	private File file;

	/**
	 * Create a new FileExtractor that will write the extracted file content to the specified file,
	 * or, if the specified file is a directory, to a file with the filename extracted from the response in that directory.
	 * @param file either a file, a directory or null, to return a new temporary file.
	 */
	public FileExtractor(File file) {
		this.file = file;
	}

	public File extractData(ClientHttpResponse response) throws IOException {
		InputStream body = response.getBody();
		if (body != null) {
			try {
				String name = StringUtils.substringBetween(response.getHeaders().getFirst("Content-Disposition"), "filename=\"", "\"");

				if (file == null) {
					String prefix = StringUtils.defaultIfEmpty(StringUtils.substringBeforeLast(name, "."), "download");
					String suffix = StringUtils.substringAfterLast(name, ".");

					file = File.createTempFile(prefix, suffix != null ? "." + suffix : null);
				} else if (file.isDirectory()) {
					file = new File(file, name);
				}

				OutputStream out = new FileOutputStream(file);
				try {
					IOUtils.copyLarge(body, out);
				} finally {
					IOUtils.closeQuietly(out);
				}
			} finally {
				IOUtils.closeQuietly(body);
			}
		}

		return file ;
	}

}


Again, we use the reply from the previous example, because we already know it's URI.

// Reload the reply object, in order to find the URI of the attachment
ObjectNode reply = restApi.getForObject(restUrl + replyURI, ObjectNode.class);

// Find the URI of the "cube.png" image, that we attached to the reply in the previous example
String attachmentURI = null;

for (Iterator<JsonNode> it = reply.get("attachments").getElements(); it.hasNext();) {
	JsonNode attachment = it.next();
	if ("cube.png".equals(attachment.get("name").asText()) {
		attachmentURI = attachment.get("uri").asText();
		break;
   	}
}

// Now we can download the attached file into some download directory
File downloadDir = ...
File attachment = restApi.execute(restUrl + attachmentURI, HttpMethod.GET, null, new FileExtractor(downloadDir));

C# sample implementation

Will be added soon.

Other sample implementations

Will be added, as soon as our dear customers and partners are willing to share their implementations with us.