Tags:
not added yet
For new development it is strongly recommend using the new Swagger API. REST API (v1) remains maintained however no further development is planned.
Due to critical fixes in the Codebeamer 2.2.0.0, 2.1.0.3, and 2.0.0.5, all the endpoints need to be rewritten with a forward ending slash “/”.
Update the urlrewrite.xml with the following rewrite rule: <rule> <from>^/rest/(.*)(?<!/)(?<!\.spr)$</from> <to>/rest/$1/</to> </rule> This will only rewrite the endpoint (and add a "/" at the end) if the trailing "/" is missing, otherwise the filter is skipped. Legacy REST API (v1)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:
Table of Contents
Accessing resourcesIn 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.
Please note that newerThan and olderThan parameters are only supported starting from codeBeamer 9.3.0 version with backward compability of old newerThen or olderThen parameters. Using latter releases please use the old newerThen or olderThen parameters instead.
For example: The URI of the default system administrator "bond" is: /user/1 or /user/bond GET https://hostname/cb/rest/user/bond
The following HTTP methods are supported by the REST API:
{ "exception" : "Type of failure", "message" : "Explanation of failure" }
The following headers must be present in all requests to the REST API:
Data descriptionIn 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" ] }
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". { "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. ... "country" : { "title" : "Country", "type" : "string", "format" : "ISO 3166", "maxLength" : 2 }, "language" : { "title" : "Language", "type" : "array", "items" : { "type" : "string", "format" : "ISO 639", "maxLength" : 2 }, "dependsOn" : [ "country" ], "optionsURI" : "/tracker/11164/field/10005/options" }, ...
To get the possible/allowed values for a field, whose value depends on the values of other fields, you must POST to the specified optionsURI POST {RestURL}{optionsURI}
and provide the values of all fields listed in "dependsOn" in the request body. { "country" : "CH" }
would return: [ "de", "en", "it", "fr" ]
Again, caching the result of an options query is not recommendable! Data interchangeData is passed to and returned from the REST API in form of JSON objects or arrays of objects. { "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" }
{ "uri" : "/user/TestUser", "status" : "Disabled" }
{ "uri" : "/user/2", "name" : "TestUser" }
{ "assignedTo" : [{ "uri" : "/user/1", "name" : "bond" }, { "uri" : "/role/1", "name" : "Project Admin" }] }
or simply { "assignedTo" : ["/user/1", "/role/1"] }
you can also use any valid form of resource URI: { "assignedTo" : ["/user/bond", "/role/Project Admin"] }
{ "assignedTo" : ["/user/bond"] }
you can also simply pass the single value without enclosing it into an array: { "assignedTo" : "/user/bond" }
SystemGet server versionGET /version The response body contains the version String, e.g. "7.7.0".
The V1 GET /version endpoint has been removed since Codebeamer release 22.04 (FELICITY).
Get server time
The V1 GET /time endpoint has been removed since Codebeamer release 22.04 (FELICITY).
For a possible workaround, see article "GET /rest/time" REST API V1 endpoint does no longer exist on Codebeamer 22.04 or any major versions. 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 GroupsUsers 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. Get user schemaGET /user/schema Create a new userPOST /user The request body must contain a valid user object with all required properties. Update an existing userPUT /user The request body must contain a user object with the "uri" and the properties to update.
Get information about an existing userGET {userURI} Get list of usersGET /users/page/{page}[?query] Returns the specified page of all users (matching the specified filter).
GET https://hostname/cb/rest/users/page/1?pagesize=50&filter=Intland Get the user license schemaGET /user/license/schema Get the available user licensesGET /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 userGET {userURI}/licenses Set the licenses assigned to a specific userPUT {userURI}/licenses E.g.: { "ALM" : "USER_WITH_FLOATING_LICENSE", "RM" : "USER_WITH_NAMED_LICENSE } Get the user permission schemaGET /user/permission/schema Get all available user permissionsGET /user/permissions You cannot create, update or delete user permissions, only assign permissions to user groups.
Get the permissions of a specific userGET {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 schemaGET /user/group/schema Get the defined user groupsGET /user/groups Create a new user groupPOST /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 groupPUT /user/group/{userGroupId} The request body must contain the properties to update, for example: { "name" : "My User Group edited" } Delete a user groupDELETE {groupURI} Get information about a user groupGET {groupURI} Get the group change historyGET {groupURI}/history Get all current members of a user groupGET {groupURI}/members Set the members of a user groupPUT {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 schemaGET /user/group/members/history/schema Get the members history of a user groupGET {groupURI}/members/history Get the groups where a specific user currently is a memberGET {userURI}/groups Get the group membership history of a specific userGET {userURI}/groups/history Set the groups where a specific user is a memberPUT {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 groupPUT {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 groupDELETE {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 groupGET {userURI}{groupURI}/history GET {groupURI}{userURI}/history Get the photo of a specific userGET {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 userPUT {userURI}/photo Caution! The request body must not contain JSON, but image data "Content-type: image/*". Remove the photo of a specific userDELETE {userURI}/photo RolesRoles are stereotypes for project roles. You must first define the role stereotype, before you can instantiate a role in project. Get the role schemaGET /role/schema Get all defined role stereotypesGET /roles Define a new role stereotypePOST /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 stereotypePUT /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 stereotypeDELETE {roleURI} Please note: You can only delete role stereotypes, as long as no project roles with this stereotyp exist.
Get a role stereotype definitionGET {roleURI} ProjectsProjects 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. Get the project schemaGET /project/schema Create a new projectPOST /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 projectPOST {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 definitionPUT /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 projectPUT /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 projectPUT /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 projectDELETE {projectURI} Please note: Deleting a project is irreversible.
Get a project definitionGET {projectURI} Get the project definition change historyGET {projectURI}/history Get list of projectsGET /projects/page/{page}[?query] Returns the specified page of all projects (visible to the current user and matching the specified filter).
GET https://hostname/cb/rest/projects/page/1?pagesize=50&category=Education Get all available project permissionsGET /project/permissions You cannot create, update or delete project permissions, only assign permissions to project roles.
Get a project permission definitionGET /project/permission/{permissionIdOrName} Get the project role schemaGET /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) rolePOST {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 rolePUT {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 roleDELETE {projectURI}{roleURI} Get a project role definitionGET {projectURI}{roleURI} Get the change history of a project roleGET {projectURI}{roleURI}/history Get a list of all roles defined in a projectGET {projectURI}/roles Get a list of all roles defined in a project plus all current role membersGET {projectURI}/roles/members[?query]
Get a list of all roles defined in a project plus all current/former role membersGET {projectURI}/roles/members/history Get a list of all members currently assigned to a specific project roleGET {projectURI}{roleURI}/members[?query]
Get the members history of a project roleGET {projectURI}{roleURI}/members/history Set all (current) members of a project rolePUT {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 roleGET {projectURI}{roleURI}/users/page/{page}
Grant a project role to a userPUT {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 userDELETE {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 roleGET {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) memberGET {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 projectGET {projectURI}{userURI}/roles/history GET {userURI}{projectURI}/roles/history Get all projects and roles where a user is currently a (direct) memberGET {userURI}/projects/roles[?direct=true] Get the history of all projects and roles where a user is or was a direct memberGET {userURI}/projects/roles/history Get all projects visible to a user and the effective project permissions per projectGET {userURI}/projects/permissions Get the effecitve project permissions of a user for a specific projectGET {userURI}{projectURI}/permissions GET {projectURI}{userURI}/permissions Get a page of all projects accessible to a userGET {userURI}/projects/page/{page}[?query]
Returns the requested page of projects accessible to a user. Get a page of all projects where a user has a specific permissionGET {userURI}/projects/permission/{permissionIdOrName}/page/{page}[?query]
Returns the requested page of projects, where the user has the requested permission. GET https://hostname/cb/rest/user/bond/projects/permission/Project - Admin/page/1 Grant a project role to a user groupPUT {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 groupDELETE {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 roleGET {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 memberGET {projectURI}/group/{groupIdOrName}/roles GET {groupURI}{projectURI}/roles Get the history of all project roles a user group has or had in a specific projectGET {projectURI}/group/{groupIdOrName}/roles/history GET {groupURI}{projectURI}/roles/history Get all projects and roles where a user group currently is a memberGET {groupURI}/projects/roles Get the history of all projects and roles where a user group is or was a direct memberGET {groupURI}/projects/roles/history Get all projects visible to a user group and the effective project permissions per projectGET {groupURI}/projects/permissions Get the effecitve project permissions of a user group for a specific projectGET {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. Get the directory/folder schemaGET /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/folderAs 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 settingsPUT /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 locationPUT /dir/{id}/moveTo/{projectURI}[?options] PUT /dir/{id}/moveTo/{directoryURI}[?options]
Copy a directory/folder (including content) to another project or locationPOST /dir/{id}/copyTo/{projectURI}[?options] POST /dir/{id}/copyTo/{directoryURI}[?options]
This will also copy all files and sub-directories/folders in that directory/folder recursively ! Delete a directory/folderDELETE {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/folderGET {directoryURI} Get the change history of a directory/folderGET /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 revisionGET /dir/{id}/version/{version} List the top-level directories/folders and files of a projectGET {projectURI}/documents/page/{page}[?query]
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/folderGET /dir/{id}/page/{page}[?query]
Get the permissions of a directory/folderGET /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/folderPUT /dir/{id}/permissions[?options]
You can grant access to
Access can be 1=read, 2=write and 3=read/write. Render Wiki markup to HTML in the context of the specified directory/folderPOST /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 schemaGET /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 fileAs 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:
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----
Update file meta-data and/or contentPUT /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. Move a file to another project or locationPUT /file/{id}/moveTo/{projectURI}[?options] PUT /file/{id}/moveTo/{directoryURI}[?options]
Copy a file to another project or locationPOST /file/{id}/copyTo/{projectURI}[?options] POST /file/{id}/copyTo/{directoryURI}[?options]
Delete a fileDELETE {fileURI} Get the meta-data/properties of a specific fileGET {fileURI} Download the content/data of a specific fileGET {fileURI}/content Get the change history of a fileGET /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 revisionGET /file/{id}/version/{version} Download the content/data of a specific file revisionGET /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 filePUT /file/{id}/version/{version}/restore Get the permissions of a fileGET /file/{id}/permissions Similar to directory/folder permissions.
Set the permissions of a filePUT /file/{id}/permissions[?options] Similar to directory/folder permissions.
Get the download statistics about a fileGET /file/{id}/accessStats Get the download log of a fileGET /file/{id}/accessLog/page/{pageNo}[?query]
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
Unlock a fileDELETE /file/{id}/lock Render Wiki markup to HTML in the context of the specified filePOST /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 PagesStarting with CB-7.4, you can also manage wiki pages via the REST-API. Get the wiki page schemaGET /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 pagePOST /wikipage To create a wikipage with attachments, you need a multipart request:
The meta-data must contain at least "project", "parent", "name" and "markup", where the name must be unique within the specified project. 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 wikipagePUT /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. Move a wiki page to another project or locationPUT {wikipageURI}/{id}/moveTo/{wikipageURI}[?options]
Copy a wiki page to another project or locationPOST {wikipageURI}/copyTo/{wikipageURI}[?options]
This will also recursively copy all child pages and attachments of this wiki page. Delete a wiki pageDELETE {wikipageURI} This will also recursively delete all child pages and attachments of this wiki page.
Get the meta-data/properties of a wiki pageGET {wikipageURI} Get the meta-data/properties of top level wiki pagesGET {wikipageURI}/topLevelWikiPages Render a wiki page as HTMLGET {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 pagePOST /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 pageGET {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 revisionGET {wikipageURI}/version/{version} Render a previous version of a wiki page as HTMLGET {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 pagePUT {wikipageURI}/version/{version}/restore Get the permissions of a wiki pageGET {wikipageURI}/permissions Similar to directory/folder/file permissions.
Set the permissions of a wiki pagePUT {wikipageURI}/permissions[?options] Similar to directory/folder/file permissions.
Get the view statistics about a wiki page - deprecatedGET {wikipageURI}/accessStats Not supported since cB 9.4 Get the view log of a wiki page - deprecatedGET {wikipageURI}/accessLog/page/{pageNo}[?query]
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
Unlock a wiki pageDELETE {wikipageURI}/lock Get the child pages of a wiki pageGET {wikipageURI}/children Get the attachments of a wiki pageGET {wikipageURI}/attachments Get a wiki page attachment by nameGET {wikipageURI}/attachment/{name} Get the attachment schemaGET /attachment/schema Upload a new attachmentPOST //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.
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 contentPUT /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. 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. Delete an attachmentDELETE /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 attachmentGET /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 revisionGET /attachment/{id}/version/{version} Download the content/data of a specific attachment revisionGET /attachment/{id}/version/{version}/content Restore a previous version of an attachmentPUT /attachment/{id}/version/{version}/restore CMDBCMDB 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 schemaGET /category/type/schema Get the available category typesGET /category/types All category types are predefined. You cannot create, update or delete category types.
Get a category type definitionGET /category/type/{categoryTypeIdOrName} Get the immutable definition of a category type.
Get the available category permissionsGET /category/permissions All category permissions are predefined. You cannot create, update or delete category permissions.
Get a category permissionGET /category/permission/{permissionIdOrName} Get the immutable definition of a category permission.
Get the category schemaGET /category/schema Create a new categoryPOST /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 categoryPOST {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 settingsPUT /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 categoryDELETE {categoryURI} Get a category definitionGET {categoryURI} Get the basic item schema of a categoryGET {categoryURI}/schema Note: You cannot configure the item schema of a category via the REST API.
Get the schema of a category item propertyGET {categoryURI}/field/{fieldIdOrName} Note: You cannot configure the schema of a category item field via the REST API.
Get all granted category permissions per roleGET {categoryURI}/roles/permissions Get the category permissions granted to a specific roleGET {categoryURI}{roleURI}/permissions GET {roleURI}{categoryURI}/permissions Set the category permissions for a specific rolePUT {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 roleDELETE {categoryURI}{roleURI}/permissions DELETE {roleURI}{categoryURI}/permissions Get the effective permissions of a user on a categoryGET {categoryURI}{userURI}/permissions GET {userURI}{categoryURI}/permissions Get a list of all categories in a projectGET {projectURI}/categories[?query]
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]
Get a list of all categories in a project visible to a userGET {userURI}{projectURI}/categories[?query] GET {projectURI}{userURI}/categories[?query]
Get a list of all categories where a user has a specific permission (grouped by project)GET {userURI}/categories/permission/{permissionIdOrName}[?query]
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 permissionGET {userURI}{projectURI}/categories/permission/{permissionIdOrName}[?query] GET {projectURI}{userURI}/categories/permission/{permissionIdOrName}[?query]
Get a summary of all items in a categoryGET {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]
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). 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 compability of old newerThen parameter. Using latter releases please use the old newerThen parameter instead.
Get a page of category itemsGET {categoryURI}/items/page/{page}[?query]
Get a page of category items matching all of the specified criteriaGET {categoryURI}/items/and/{criteria}/page/{page}[?query]
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 criteriaGET {categoryURI}/items/or/{criteria}/page/{page}[?query]
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 criteriaGET {categoryURI}/items/and/{mandatoryCriteria}/or/{optionalCriteria}/page/{page}[?query]
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 ViewsCategory 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}. Get the category view schemaGET /category/view/schema Get the available views of a categoryGET {categoryURI}/views Get the definition of a specific category viewGET {categoryViewURI} Get the item schema of a category viewGET {categoryViewURI}/schema Get a page of category view itemsGET {categoryViewURI}/items/page/{page}
TrackersTrackers 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 schemaGET /tracker/type/schema Get the available tracker typesGET /tracker/types[?query]
All tracker types are predefined. You cannot create, update or delete tracker types. Get a tracker type definitionGET /tracker/type/{trackerTypeIdOrName} Get the immutable definition of a tracker type.
Get the available tracker permissionsGET /tracker/permissions All tracker permissions are predefined. You cannot create, update or delete tracker permissions.
Get a tracker permissionGET /tracker/permission/{permissionIdOrName} Get the immutable definition of a tracker permission.
Get the tracker schemaGET /tracker/schema Create a new trackerPOST /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 trackerPOST {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 settingsPUT /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 trackerDELETE {trackerURI} Get a tracker definitionGET {trackerURI} Get the basic item schema of a trackerGET {trackerURI}/schema Note: You cannot configure the item schema of a tracker via the REST API.
Get the schema of a tracker item propertyGET {trackerURI}/field/{fieldIdOrName} Note: You cannot configure the schema of a tracker item field via the REST API.
Get all granted tracker permissions per roleGET {trackerURI}/roles/permissions Get the tracker permissions granted to a specific roleGET {trackerURI}{roleURI}/permissions GET {roleURI}{trackerURI}/permissions Set the tracker permissions for a specific rolePUT {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 roleDELETE {trackerURI}{roleURI}/permissions DELETE {roleURI}{trackerURI}/permissions Get the effective permissions of a user on a trackerGET {trackerURI}{userURI}/permissions GET {userURI}{trackerURI}/permissions Get a list of all trackers in a projectGET {projectURI}/trackers[?query]
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]
Get a list of all trackers in a project visible to a userGET {userURI}{projectURI}/trackers[?query] GET {projectURI}{userURI}/trackers[?query]
Get a list of all trackers where a user has a specific permission (grouped by project)GET {userURI}/trackers/permission/{permissionIdOrName}[?query]
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 permissionGET {userURI}{projectURI}/trackers/permission/{permissionIdOrName}[?query] GET {projectURI}{userURI}/trackers/permission/{permissionIdOrName}[?query]
Get a summary of all items in a trackerGET {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]
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). GET {itemURI}/outline[?query]
This allows interactive/on-demand expansion of arbitrarily huge or deep outlines.
The supported tracker types are: Not supported ones: Get a page of tracker itemsGET {trackerURI}/items/page/{page}[?query]
Get a page of tracker items matching all of the specified criteriaGET {trackerURI}/items/and/{criteria}/page/{page}[?query]
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 Datetime 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 criteriaGET {trackerURI}/items/or/{criteria}/page/{page}[?query]
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 criteriaGET {trackerURI}/items/and/{mandatoryCriteria}/or/{optionalCriteria}/page/{page}[?query]
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 ViewsTracker 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}. Get the tracker view schemaGET /tracker/view/schema Get the available views of a trackerGET {trackerURI}/views Get the definition of a specific tracker viewGET {trackerViewURI} Get the item schema of a tracker viewGET {trackerViewURI}/schema Get a page of tracker view itemsGET {trackerViewURI}/items/page/{page}
Tracker/CMDB ItemsTracker/CMDB items have URIs of form "/item/{id}", where {id} is the internal item id/number. Get the branched version of an itemTo 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 itemTo get a specific item's version you can use this request: GET {itemURI}/version/{version}
Submit a new top-level CMDB category itemFirst you have to get the schema and a pre-initialized object for a new top-level CMDB category item: GET {categoryURI}/newItem
GET https://hostname/cb/rest/project/Test/category/Test Cases/newItem
The response contains 4 properties:
POST /item
{ "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 itemFirst you have to get the schema and a pre-initialized object for a new top-level tracker item: GET {trackerURI}/newItem
GET https://hostname/cb/rest/project/Test/tracker/Tasks/newItem
The response contains 4 properties:
POST /item
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 itemFirst 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 itemFor 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). GET {itemURI}/edit
PUT /item
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 itemGET {itemURI}/transitions
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 transitionTo 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}
GET https://hostname/cb/rest/item/1000/transition/81
The response contains 4 properties:
PUT /item
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
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
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 attachmentsPOST {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 itemGET {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 nameYou 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 itemPUT {itemAttachmentURI} The request body must contain the new file content (either singlepart or multipart with one part). Remove a file attached to an itemREMOVE {itemAttachmentURI} Get the schema for an itemGET {itemURI}/schema Get information about an itemGET {itemURI} Get the item history schemaGET /item/history/schema Get the change history of an itemGET {itemURI}/history
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]
Get the children (sub items) of an itemGET {itemURI}/children
Get a summary of other items referring to an itemGET {itemURI}/references/summary[?query]
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 } ]
}
Get other items referring to an itemGET {itemURI}/references[?query]
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 itemGET {itemURI}/relatedIssues/page/{pageNo}
Get a summary of all items related to a userGET {userURI}/item/summary[?query]
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 stringGET {queryURI}/page/{page}[?queryString]
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 idReturns the result of a query specified by its id number. GET /query/{queryId}/page/{pageNo}?pagesize={pageSize}
For example: https://hostname/cb/rest/query/149620/page/1?pagesize=10 Get items related to a userGET {userURI}/items/page/{page}[?query]
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 projectGET {userURI}/projects/item/summary[?query]
Get a summary of items related to a user in a specific projectGET {userURI}{projectURI}/item/summary[?query] GET {projectURI}{userURI}/item/summary[?query]
Get items related to a user in a specific projectGET {userURI}{projectURI}/items/page/{page}[?query] GET {projectURI}{userURI}/items/page/{page}[?query]
Get a summary of items related to a user in a specific tracker/categoryGET {userURI}{trackerURI}/item/summary[?query] GET {trackerURI}{userURI}/item/summary[?query] GET {userURI}{categoryURI}/item/summary[?query] GET {categoryURI}{userURI}/item/summary[?query]
Get items related to a user in a specific tracker/categoryGET {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]
Render Wiki markup to HTML in the context of a work/configuration itemPOST /item/{id}/wiki2html Since CB-7.7.1. Item ReviewsTracker item reviews is a feature, that was introduced in CB-8.0. Please note - Review Hub is a different feature, its items cannot be accessed by this endpoint.Get item review schemaGET /item/review/schema Start a new item reviewPOST /item/review This is equivalent to the workflow action Start a new review.
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
Update the review configurationPUT /item/review The request body must contain the URI and configuration of the review to update. { "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. Get all reviews for an itemGET {itemURI}/reviews The result is a list of item review summary/statistics. [{ "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 reviewGET {itemURI}/version/{version}/review Get all reviewers/votes for an item reviewGET {itemURI}/version/{version}/reviewers E.g.: GET https://hostname/cb/rest/item/1000/version/2/reviewers [{ "reviewer" : { "uri" : "/user/1", "name" : "bond" }, "reviewedAt" : "2016-07-18T16:38:45+02:00", "role" : { "uri" : "/role/3", "name" : "Product Owner" }, "rating" : 1 }, { "reviewer" : { "uri" : "/user/3", "name" : "klaus" } }]
In this example:
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/userGET {userURI}/item/reviews[?reviewed={true|false}] The boolean parameter reviewed is optional. The default is to return submitted (true) and pending (false) 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 itemGET {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 revisionGET {userURI}/{itemURI}/version/{version}/review[?reviewed={true|false}] GET {itemURI}/version/{version}/{userURI}/review[?reviewed={true|false}] Test ManagementTest Management is supported by REST API since CB 9.0. Create a new TestSetRunPOST /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 Legacy REST API (v1) new-item REST api call, and modify them as necessary. This REST request can also contain these parameters:
Notes:
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 TestSetRunGET /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 TestCasePOST /testRun/{testRunId}/result Using this call you can set the result of a TestCase inside of a TestSetRun. To use this:
So the request body is a JSON object, where the:
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 updatePOST /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:
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 }
Test results 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.
AssociationsStarting with CB-7.3, you can also manage assocations via the REST-API. Get the available association typesGET /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 typeGET /association/type/{typeIdOrName} Get the immutable definition of an association type. Get the association schemaGET /association/schema Create a new associationPOST /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 settingsYou 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 associationDELETE {associationURI} Get the change history of an associationGET {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 entityThis gets all associations of (originating at) the specified codeBeamer entity, plus optionally, all associations pointing to this entity. GET {entityURI}/associations[?query]
GET https://hostname/cb/rest/item/75266/associations?type=depends,copy of&only=Suspected&inout=true Client side implementationsBecause the REST API is completely platform independent, your are free to choose the development and runtime environment most suitable to you. Java sample implementationWe show a sample Java client for the REST API based on the Spring 3.2Rest Template. Setup the REST API connectionfinal 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 categoryArrayNode 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 10minArrayNode 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 CaseWe 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 CaseIn 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 ; }
}
// 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 implementationWill be added soon. Other sample implementationsWill be added, as soon as our dear customers and partners are willing to share their implementations with us. |
Fast Links
codebeamer Overview codebeamer Knowledge Base Services by Intland Software |
This website stores cookies on your computer. These cookies are used to improve your browsing experience, constantly optimize the functionality and content of our website, furthermore helps us to understand your interests and provide more personalized services to you, both on this website and through other media. With your permission we and our partners may use precise geolocation data and identification through device scanning. You may click accept to consent to our and our partners’ processing as described above. Please be aware that some processing of your personal data may not require your consent, but you have a right to object to such processing. By using our website, you acknowledge this notice of our cookie practices. By accepting and continuing to browse this site, you agree to this use. For more information about the cookies we use, please visit our Privacy Policy.Your preferences will apply to this website only.