REST API (v1)
* 
For new development, it is strongly recommended to use Swagger API. REST API (v1) remains maintained however no further development is planned
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 (available at the /cb/remote-api URL) 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.
* 
For a better readability, we will omit 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.
* 
The newerThan and olderThan parameters are only supported starting from Codebeamer 9.3.0 version with backward compatibly of old newerThen or olderThen parameters. For users of Codebeamer prior to the 9.3.0 version, it is advised to use the old newerThen or olderThen parameters instead.
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:
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}
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"

}]

}

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".
* 
The V1 GET /version endpoint has been removed since Codebeamer 22.04 (FELICITY) release.
Get server time
* 
The V1 GET /time endpoint has been removed since Codebeamer release 22.04 (FELICITY).
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/{userGroupId}

The request body must contain the properties to update, for example:

{

"name" : "My User Group edited"

}

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", "Trackers - 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", "Trackers - 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 project 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", "Trackers - 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 effective 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.
newerThan
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".
olderThan
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 be 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 wiki page 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 - deprecated
GET {wikipageURI}/accessStats
Not supported since cB 9.4
Get the view log of a wiki page - deprecated
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.
newerThan
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".
olderThan
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".
Not supported since cB 9.4
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.
* 
Please note that newerThan parameter is only supported starting from Codebeamer 9.3.0 version with backward compatibility of old newerThen parameter. Using latter releases please use the old newerThen parameter instead.
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.
newerThan
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.
newerThan
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.
newerThan
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
Loading the items modified at today.
GET https://hostname/cb/rest/project/1/category/Contacts/items/page/1?newerThan=Today
Loading the items modified at yesterday or today.
GET https://hostname/cb/rest/project/1/category/Contacts/items/page/1?newerThan=Yesterday
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.
newerThan
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?newerThan=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.
The supported tracker types are: Change Request, Requirement, Risk, RPE Report, Task, User Story, Epic, Configuration Item, Test Case, Component, Contact, Test Set
Not supported ones: Issue, Bug, Test, Pull Request, Work Log, Test Run, Milestone, Forum Post, Release, Platform, Test Configuration, Team, Area
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.
newerThan
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.
newerThan
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
Loading the items modified at today.
GET https://hostname/cb/rest/project/1/tracker/Bugs/items/page/1?newerThan=Today
Loading the items modified at yesterday or today.
GET https://hostname/cb/rest/project/1/tracker/Bugs/items/page/1?newerThan=Yesterday
Loading the items before an exact Date-time with specific Status
GET https://hostname/cb/rest/project/1/tracker/Bugs/items/page/1?Status=new&newerThen=2019-01-23T16:18:00%2B01:00
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.
newerThan
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.
newerThan
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?newerThan=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
Get the specific version of an item
To get a specific item's version you can use this request:
GET {itemURI}/version/{version}
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", Boolean.TRUE, ""),

["Turn dimmer", "Its getting brighter or darker", Boolean.FALSE, ""),

["Switch off", "Light is off", Boolean.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/1001 via 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.
newerThan
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".
newerThan
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.
newerThan
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.
newerThan
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".
newerThan
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.
newerThan
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".
newerThan
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.
* 
Please note — Hub is a different feature, its items cannot be accessed by this endpoint.
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 tem to review,
The list of reviewers (users),
An the review configuration.
E.g.: Specification for a review of /item/1000:

{

"item" : {

"uri" : "/item/1000",

"name" : "Provide a new item review functionality"

},

"reviewers" : [{

"uri" : "/user/1",

"name" : "bond"

}, {

"uri" : "/user/3",

"name" : "klaus"

}],

"config" : {

"signature" : 1,

"plusRole" : false,

"rejects" : 1

}

}

where
Users bond and klaus should be the reviewers.
Reviewers must enter their password in order to submit their 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.
If you configure "plusRole": true (only CB-10.0 and newer), then upon submitting a review (see below), you must also specify, in which "role" the "reviewer" performed the review.
The review should be considered as rejected, if more than one reviewer rejects.
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,

"plusRole" : true,

"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,

"plusRole" : true,

"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/reviewerss
[{

"reviewer" : {

"uri" : "/user/1",

"name" : "bond"

},

"reviewedAt" : "2016-07-18T16:38:45+02:00",

"role" : {

"uri" : "/role/3",

"name" : "Product Owner"

},

"rating" : 1

}, {

"reviewer" : {

"uri" : "/user/3",

"name" : "klaus"

}

}]
In this example:
The reviewer "bond" has already reviewed and accepted ("rating" : 1) the item in his "role" (function) of "Product Owner".
Please note: Information about the "role" is only present in CB-10.0 and newer, if the review configuration requests "plusRole" : true
The reviewer "klaus" has not reviewed the item yet.
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/klaus",

"rating" : 1

}

In CB-10.0 and newer, and only if the review configuration also asks for the "role", in which the "reviewer" performed the review: ("plusRole" : true), then the body must also contain a role reference, e.g.

{

"reviewer" : "/user/klaus",

"role" : "/role/Project Admin",

"rating" : 1

}

If a role is requested and you do not specify the "role", or the reviewer does not have this role for the item to review (GET {userURI}/{itemURI}/roles), the vote/rating is rejected.
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",

"role" : {

"uri" : "/role/3",

"name" : "Product Owner"

},

"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 (v1) 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".
* 
You must provide either {testSetId} or {testCaseIds} or otherwise the request will be rejected.
When the testStep id is not specified ( null ) then the algorithm generates the id with a hash using the other teststep values.
The key concept is that the teststep id needs to be unique within a test case.
Once the id is set - either by explicitely giving or generated - it will not be able to be overwritten, to preserve the integrity and provide the re-usability of teststeps.
The response 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 the 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"

} ]
Batch test result update
POST /rest/xunitresults
With this endpoint you can create and update test runs and test cases in batch mode.
It requires a form-data POST request with two parameters:
A configuration text field where the test context can be configured.
A file field having a zip file containing all the test results in XML files (see an example below.)
Configuration
JSON string with the following format:


{

"testConfigurationId":"1125", // Test configuration

"testCaseTrackerId":"2286", // The tracker id of the test cases

"testCaseId":"", // The parent test case id

"releaseId":"", // Release id for the tests

"testRunTrackerId":"2290", // The tracker id where the test runs going to be populated

"buildIdentifier":"", // Build id

"defaultPackagePrefix":"" // Package prefix

}

A ZIP file containing one or more xml files with any name. The format of the xml files should be the following:
__<?xml version=__"1.0" __encoding=__"UTF-8"__?>__

''<!-- Generated by org.testng.reporters.JUnitReportReporter -->''

__<testsuite__ skipped__=__"0" hostname__=__"win-2012" name__=__"com.intland.codebeamer.functionaltest.test.AuthenticationTests" tests__=__"4" failures__=__"0" timestamp__=__"16 Jan 2019 23:35:21 GMT" time__=__"50.020" errors__=__"0"__>__

<testcase classname="com.intland.xunit.GatherComputerInfoTest" name="testIsSystemRecommended" time="0.01">

<failure type="junit.framework.AssertionFailedError">junit.framework.AssertionFailedError at com.intland.xunit.GatherComputerInfoTest.testIsSystemRecommended(Unknown Source)

</failure>

</testcase>

<testcase classname="com.intland.xunit.GatherComputerInfoTest" name="testIsMaxMemGreaterThan100Mb" time="0.001" />

<testcase classname="com.intland.xunit.GatherComputerInfoTest" name="testThrowFalseError" time="0.001">

<error message="ThrowFalseError" type="java.lang.Exception">java.lang.Exception: ThrowFalseError at com.intland.xunit.GatherComputerInfoTest.testThrowFalseError(Unknown Source)

</error>

</testcase>

__</testsuite>__ ''<!-- com.intland.codebeamer.functionaltest.test.AuthenticationTests -->''
It defines 3 testcases in a testsuite and the endpoint will generate the following test case hierarchy.
* 
Starting from Codebeamer 9.3.0 this endpoint requires 'Issue - Add' and 'Issue - Edit' permissions for both test case and test run trackers defined in the configuration JSON.
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&newerThan=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&newerThan=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.
Was this helpful?