Tags:
not added yet
The codeBeamer REST APIStarting with codeBeamer 7.1, you can also access codeBeamer resources via a REST The REST API is the replacement for the old Hessian
Table of Contents
Accessing resourcesIn the REST API, each codeBeamer resource is identified, accessed and referenced via an URI 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:
The optional request body (POST/PUT only), can be either
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". 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] 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 { "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"] } 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" }
SystemGet server versionGET /version The response body contains the version String, e.g. "7.7.0". Get server timeGET /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
Update an existing userPUT /user
Get information about an existing userGET {userURI} Get list of usersGET /users/page/{page}[?query]
Example: 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
Get the licenses assigned to a specific userGET {userURI}/licenses Set the licenses assigned to a specific userPUT {userURI}/licenses
{ "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
Get the permissions of a specific userGET {userURI}/permissions
Get the user group schemaGET /user/group/schema Get the defined user groupsGET /user/groups Create a new user groupPOST /user/group
{ "name" : "REST API Users", "description" : "All users that are allowed to use the REST API", "permissions" : ["Own Account - Admin", "Account - View Address"] }
Update an existing user groupPUT /user/group
{ "uri" : "/user/group/REST API Users", "permissions" : [1, 2, 4, 8, 16] }
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
[ "/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
[ "/user/group/1001", "/user/group/External" ]
Make a user a member of a groupPUT {userURI}{groupURI} PUT {groupURI}{userURI}
"Why it was necessary to add this user to this group"
Remove a user from a groupDELETE {userURI}{groupURI} DELETE {groupURI}{userURI}
"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
Set the photo of a specific userPUT {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
{ "name" : "Tester", "description" : "Testers of the REST API" }
Update the description of a role stereotypePUT /role
{ "uri" : "/role/Tester", "description" : "Testers of the REST API" }
Delete an unused role stereotypeDELETE {roleURI}
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
{ "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
Update a project definitionPUT /project
{ "uri" : "/project/1", "propagation" : "Public with join approval", "defaultMemberRoleId" : 2 }
Close/Re-Open a projectPUT /project
{ "uri" : "/project/1", "closed" : true }
Remove/Restore a projectPUT /project
{ "uri" : "/project/1", "deleted" : true }
Delete a projectDELETE {projectURI}
Get a project definitionGET {projectURI} Get the project definition change historyGET {projectURI}/history Get list of projectsGET /projects/page/{page}[?query]
Example: GET https://hostname/cb/rest/projects/page/1?pagesize=50&category=Education Get all available project permissionsGET /project/permissions
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}
[ "Wiki Space - View", "Document - View", "Tracker - View", "CMDB - View" ]
Create a new project role based on an existing (template) rolePOST {projectURI}{roleURI}/clone/{roleIdOrName}
[ "Wiki Space - View", "Document - View", "Tracker - View", "CMDB - View" ]
POST https://hostname/cb/rest/project/1/role/Developer/clone/Tester Change the permissions granted to a roject rolePUT {projectURI}{roleURI}
[ "Wiki Space - View", "Document - View", "Tracker - 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
[ "/user/TestUser", "/user/group/REST API Users" ]
Get a page of all users assigned to a project roleGET {projectURI}{roleURI}/users/page/{page}
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 userPUT {projectURI}{roleURI}{userURI} PUT {projectURI}{userURI}{roleURI} PUT {userURI}{projectURI}{roleURI}
"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}
"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
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. E.g. Find first page of projects, where the /user/bondis project administrator: 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}
"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}
"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
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 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. 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. 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" } ). Set the permissions of a directory/folderPUT /dir/{id}/permissions[?options]
You can grant access to
Render Wiki markup to HTML in the context of the specified directory/folderPOST /dir/{id}/wiki2htmlSince 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 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:
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 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 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}/wiki2htmlSince 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. 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". Get the wiki page schemaGET /wikipage/schema You can extend the basic wiki page schema by specifying additional meta-data properties (see 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. 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 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]
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} Render a wiki page as HTMLGET {wikipageURI}/htmlSince 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}/wiki2htmlSince 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}/historyThis 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}/htmlSince 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 pageGET {wikipageURI}/accessStats Get the view log of a wiki pageGET {wikipageURI}/accessLog/page/{pageNo}[?query]
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.
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 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
Get a category type definitionGET /category/type/{categoryTypeIdOrName}
Get the available category permissionsGET /category/permissions
Get a category permissionGET /category/permission/{permissionIdOrName}
Get the category schemaGET /category/schema Create a new categoryPOST /category
{ "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
Update category settingsPUT /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
Get the schema of a category item propertyGET {categoryURI}/field/{fieldIdOrName}
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
[ "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
GET https://hostname/cb/rest/project/1/category/Contacts/item/summary { "total" : 2, "open" : 2 } 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 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?newerThen=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
Get a tracker type definitionGET /tracker/type/{trackerTypeIdOrName}
Get the available tracker permissionsGET /tracker/permissions
Get a tracker permissionGET /tracker/permission/{permissionIdOrName}
Get the tracker schemaGET /tracker/schema Create a new trackerPOST /tracker
{ "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
Update tracker settingsPUT /tracker
{ "uri" : "/project/1/tracker/Tests", "visible" : false }
Delete a trackerDELETE {trackerURI} Get a tracker definitionGET {trackerURI} Get the basic item schema of a trackerGET {trackerURI}/schema
Get the schema of a tracker item propertyGET {trackerURI}/field/{fieldIdOrName}
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
[ "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
GET https://hostname/cb/rest/project/1/tracker/Bugs/item/summary { "total" : 1754, "open" : 78 } 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 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?newerThen=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. 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:
After having set all additional "item" properties, you create the CMDB category item via: 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", true ], ["Turn dimmer", "Its getting brighter or darker", false], ["Switch off", "Light is off", true ] ], "postAction" : "Cleanup the test environment", "comments" : { "comment" : "I have to test this" } }
Submit a new top-level tracker 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:
After having set all additional "item" properties, you create the tracker item via: 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
After having modified "item" properties, you update the item via: PUT /item
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:
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
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). 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 children (sub items) of an itemGET {itemURI}/children
Get a summary of other items referring to an itemGET {itemURI}/references/summary[?query]
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 } ] }
Get other items referring to an itemGET {itemURI}/references[?query]
E.g. Get all items (any type, any status) referencing the requirement /item/1001via any field: GET https://hostname/cb/rest/item/1001/references [ { "uri" : "/item/1004", "version" : 1, "field" : [ "verifies" ], "tracker" : { "uri" : "/category/1027", "name" : "Test Cases" }, "priority" : { "id" : 2, "name" : "High" }, "name" : "Test dimmer switch", "status" : { "id" : 1, "name" : "New" }, "type" : { "id" : 3, "name" : "Functional" }, "submittedAt" : "2013-03-20T11:06:53+01:00", "submitter" : { "uri" : "/user/1", "name" : "bond" }, "modifiedAt" : "2013-03-20T11:06:53+01:00", "modifier" : { "uri" : "/user/1", "name" : "bond" }, "verifies" : [ { "uri" : "/item/1002", "name" : "The light must be dimmable" } ], "preAction" : "Prepare the test environment", "testSteps" : [ [ "Switch on", "Light is on", true ], [ "Turn dimmer", "Its getting brighter or darker", false ], [ "Switch off", "Light is off", true ] ], "postAction" : "Cleanup the test environment", "description" : "Test dimmer switch", "descFormat" : "Wiki" }, { "uri" : "/item/1003", "version" : 1, "field" : [ "subject" ], "tracker" : { "uri" : "/tracker/1033", "name" : "Tasks" }, "priority" : { "id" : 2, "name" : "High" }, "name" : "Add dimmer function to light switch", "status" : { "id" : 1, "name" : "New" }, "subject" : { "uri" : "/item/1002", "name" : "The light must be dimmable" }, "severity" : { "id" : 2, "name" : "Critical" }, "assignedTo" : [ { "uri" : "/role/2", "name" : "Developer" } ], "submittedAt" : "2013-03-20T11:04:06+01:00", "submitter" : { "uri" : "/user/1", "name" : "bond" }, "modifiedAt" : "2013-03-20T11:04:06+01:00", "modifier" : { "uri" : "/user/1", "name" : "bond" }, "description" : "When turning the on/off switch in the on position to the left or right, the light must get darker/brighter.", "descFormat" : "Wiki" } ] Get other items related to an itemGET {itemURI}/relatedIssues/page/{pageNo}
Get a summary of all items related to a userGET {userURI}/item/summary[?query]
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 related to a userGET {userURI}/items/page/{page}[?query]
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 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}/wiki2htmlSince 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. ForumsForums were removed in CB-7.6.0. You should use Trackers instead. Forums have URIs of the form: "/forum/{id}" or "{projectURI}/forum/{name}", where {id} is the internal unique forum id/number and {name} is the forum name, which is only unique within a project.Get the available forum permissionsGET /forum/permissions
Get a forum permissionGET /forum/permission/{permissionIdOrName}
Get the forum schemaGET /forum/schema Create a new forumPOST /forum
{ "project" : "/project/1", "name" : "News", "keyName" : "NEWS", "description" : "News about the project", "descFormat" : "Plain" }
Create a new forum as a clone of another forumPOST {forumURI}/clone
Update forum settingsPUT /forum
{ "uri" : "/project/1/forum/News", "description" : "__Important__ News about the project", "descFormat" : "Wiki" }
Delete a forumDELETE {forumURI} Get a forum definitionGET {forumURI} Get the forum post schemaGET {forumURI}/schema
Get all granted forum permissions per roleGET {forumURI}/roles/permissions Get the forum permissions granted to a specific roleGET {forumURI}{roleURI}/permissions GET {roleURI}{forumURI}/permissions Set the forum permissions for a specific rolePUT {forumURI}{roleURI}/permissions PUT {roleURI}{forumURI}/permissions
[ "Issue - View Any", "Issue - View Comments/Attachments" ]
Remove all forum permissions for a specific roleDELETE {forumURI}{roleURI}/permissions DELETE {roleURI}{forumURI}/permissions Get the effective permissions of a user on a forumGET {forumURI}{userURI}/permissions GET {userURI}{forumURI}/permissions Get a list of all forums in a projectGET {projectURI}/forums[?query]
E.g. Show all forums in the test project: GET https://hostname/cb/rest/project/1/forums?hidden=true Get a list of all forums visible to a user (grouped by project)GET {userURI}/forums[?query]
Get a list of all forums in a project visible to a userGET {userURI}{projectURI}/forums[?query] GET {projectURI}{userURI}/forums[?query]
Get a list of all forums where a user has a specific permission (grouped by project)GET {userURI}/forums/permission/{permissionIdOrName}[?query]
E.g. Find all forums where the current user has permission to add posts: GET https://hostname/cb/rest/user/self/forums/permission/Issue - Add Get a list of all forums in a project where a user has a specific permissionGET {userURI}{projectURI}/forums/permission/{permissionIdOrName}[?query] GET {projectURI}{userURI}/forums/permission/{permissionIdOrName}[?query]
Get a summary of all posts in a forumGET {forumURI}/post/summary
GET https://hostname/cb/rest/project/1/forum/News/post/summary { "total" : 12, "open" : 12 } Get a page of forum postsGET {forumURI}/posts/page/{page}[?query]
Submit a new forum postSimilar to CMDB/Tracker items, you can also request the initial "item", "schema" and "permissions" for a new forum post via GET {forumURI}/newPost
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 a simple forum post, without attachments { "tracker" : "/project/Test/forum/News", "name" : "New REST API available now!", "description" : "Did you know, that you can now also create forum posts via REST API ?", "descFormat" : "Plain" } Please note: Only top level forum posts are items! You can apply all item operations also on forum posts, including updating and deleting items. Replies to top-level forum posts or to other replies are comments. See the description of adding, updating and removing item comments. 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]
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 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 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&newerThen=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&newerThen=10 min", ArrayNode.class); Execute a state transition on the new Test Case// Get the next possible state transitions for the test case ArrayNode transitions = restApi.getForObject(restUrl + testCaseURI + "/transitions", ArrayNode.class); // Pick the first transition (not very useful, but this is only an example) String transitionURI = transitions.get(0).get("uri").asText(); // Prepare transition execution Map<String,Object> transitionContext = restApi.getForObject(restUrl + testCaseURI + transitionURI, Map.class); // Add a comment with a single file attachment to the Test Case Map<String,Object> comment = new LinkedHashMap<String,Object>(4); comment.put("comment", "__This__ is only for testing: Here goes the image: [!Image.jpg!]"); comment.put("commentFormat", "Wiki"); comment.put("attachments", Collections.singletonMap("name", "Image.jpg")); // Set additional attributes we want to change upon this state transition Map<String,Object> testCaseAttrs = transitionContext.get("item"); testCaseAttrs.put("comments", comment); // Because we have an attachment, we need a multipart message MultiValueMap<String,Object> multipart = new LinkedMultiValueMap<String,Object>(); // The TestCase object goes into the "body" part multipart.add("body", testCaseAttrs); // The image file to attach goes into an extra part (we simply assume the "Image.jpg" file is in our class path) multipart.add("Image.jpg", new ClassPathResource("Image.jpg", getClass()); // Execute the TestCase state transition restApi.put(restUrl + "/item", multipart); Add a reply to a previous comment on the Test Case// Reload the Test Case object, in order to get accurate comments list ObjectNode testCase = restApi.getForObject(restUrl + testCaseURI, ObjectNode.class); // Now create a reply to the first comment on the TestCase String firstCommentURI = testCase.get("comments").get(0).get("uri").asText(); // We simply reply to the first comment on the TestCase Map<String,Object> reply = new LinkedHashMap<String,Object>(4); reply.put("replyTo", firstCommentURI); reply.put("comment", "Yes, I totally agree !"); // Now post the reply URI replyURI = restApi.postForLocation(restUrl + testCaseURI + "/comment", reply); Update an existing comment on the Test 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 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, and help us 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. Your preferences will apply to this website only.
Note that user-behavior analytics are being captured on this server to improve the Codebeamer user experience.