# Group Projects ## Actions | Link | Description | Condition | |:--------------------------:|----------------------------------------------------------------------| --------------------------------- | | createWorkPackage | Form endpoint that aids in preparing and creating a work package | **Permission**: add work packages | | createWorkPackageImmediate | Directly creates a work package in the project | **Permission**: add work packages | ## Linked Properties | Link | Description | Type | Constraints | Supported operations |Condition | | :----------: | ------------- | ---- | ----------- | -------------------- |----------------------------------------- | | self | This project | Project | not null | READ | | | categories | Categories available in this project | Collection | not null | READ | | | types | Types available in this project | Collection | not null | READ | **Permission**: view work pacakges or manage types | | versions | Versions available in this project | Collection | not null | READ | **Permission**: view work packages or manage versions | | memberships | Memberships in the project | Collection | not null | READ | **Permission**: view members | | workPackages | Work Packages of this project | Collection | not null | READ | | Depending on custom fields defined for projects, additional links might exist. ## Local Properties | Property | Description | Type | Constraints | Supported operations | | :---------: | ------------- | ---- | ----------- | -------------------- | | id | Projects's id | Integer | x > 0 | READ | | identifier | | String | | READ | | name | | String | | READ | | status | The project's status | String | 'active' or 'archived' | READ | | public | Indicates whether the project is accessible for everybody | Boolean | | READ | | description | | Formattable | | READ | | createdAt | Time of creation | DateTime | | READ | | updatedAt | Time of the most recent change to the project | DateTime | | READ | Depending on custom fields defined for projects, additional properties might exist. ## Project [/api/v3/projects/{id}] + Model + Body { "_type": "Project", "_links": { "self": { "href": "/api/v3/projects/1", "title": "Lorem" }, "createWorkPackage": { "href": "/api/v3/projects/1/work_packages/form", "method": "post" }, "createWorkPackageImmediate": { "href": "/api/v3/projects/1/work_packages", "method": "post" }, "categories": { "href": "/api/v3/projects/1/categories" }, "types": { "href": "/api/v3/projects/1/types" }, "versions": { "href": "/api/v3/projects/1/versions" }, "workPackages": { "href": "/api/v3/projects/1/work_packages" } "memberships": { "href": "/api/v3/memberships?filters=[{"project":{"operator":"=","values":["1"]}}] }, "customField456: { "href": "/api/v3/users/315", "method": "A user" }, }, "id": 1, "identifier": "project_identifier", "name": "Project example", "status": active, "public": false, "description": { "format": "markdown", "raw": "Lorem **ipsum** dolor sit amet", "html": "

Lorem ipsum dolor sit amet

" }, "createdAt": "2014-05-21T08:51:20Z", "updatedAt": "2014-05-21T08:51:20Z", "customField123": 123 } ## View project [GET] + Parameters + id (required, integer, `1`) ... Project id + Response 200 (application/hal+json) [Project][] + Response 404 (application/hal+json) Returned if the project does not exist or the client does not have sufficient permissions to see it. **Required permission:** view project *Note: A client without sufficient permissions shall not be able to test for the existence of a project. That's why a 404 is returned here, even if a 403 might be more appropriate.* + Body { "_type": "Error", "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound", "message": "The specified project does not exist." } ## Projects [/api/v3/projects{?filters}] + Model + Body { "_links": { "self": { "href": "/api/v3/projects" } }, "_type": "Collection", "total": 2, "count": 2, "_embedded": { "elements": [ { "_type": "Project", "_links": { "self": { "href": "/api/v3/projects/6", "title": "A project" }, "createWorkPackage": { "href": "/api/v3/projects/6/work_packages/form", "method": "post" }, "createWorkPackageImmediate": { "href": "/api/v3/projects/6/work_packages", "method": "post" }, "categories": { "href": "/api/v3/projects/6/categories" }, "versions": { "href": "/api/v3/projects/6/versions" } }, "id": 6, "identifier": "a_project", "name": "A project", "status": "active", "public": false, "description": { "format": "markdown", "raw": "Lorem **ipsum** dolor sit amet", "html": "

Lorem ipsum dolor sit amet

" }, "createdAt": "2015-07-06T13:28:14+00:00", "updatedAt": "2015-10-01T09:55:02+00:00", "type": "Customer Project" }, { "_type": "Project", "_links": { "self": { "href": "/api/v3/projects/14", "title": "Another project" }, "createWorkPackage": { "href": "/api/v3/projects/14/work_packages/form", "method": "post" }, "createWorkPackageImmediate": { "href": "/api/v3/projects/14/work_packages", "method": "post" }, "categories": { "href": "/api/v3/projects/14/categories" }, "versions": { "href": "/api/v3/projects/14/versions" } }, "id": 14, "identifier": "another_project", "name": "Another project", "status": "archived", "public": true, "description": { "format": "markdown", "raw": "", "html": "" }, "createdAt": "2016-02-29T12:50:20+00:00", "updatedAt": "2016-02-29T12:50:20+00:00", "type": null }] } } } ## List projects [GET] Returns a collection of projects. The collection can be filtered via query parameters similar to how work packages are filtered. In addition to the provided filter, the result set is always limited to only contain projects the client is allowed to see. + Parameters + filters (optional, string, `[{ "ancestor": { "operator": "=", "values": ['1'] }" }]`) ... JSON specifying filter conditions. Accepts the same format as returned by the [queries](#queries) endpoint. Currently supported filters are: + status: based on the status of the project + ancestor: filters projects by their ancestor. A project is not considered to be it's own ancestor. + created_on: based on the time the project was created + latest_activity_at: based on the time the last activity was registered on a project. + name_and_identifier: based on both the name and the identifier. + parent_id: filters projects by their parent. + principal: based on members of the project. + type_id: based on the types active in a project. + id: based on projects' id. There might also be additional filters based on the custom fields that have been configured. + Response 200 (application/hal+json) [Projects][] ## Create project [POST] Creates a new project, applying the attributes provided in the body. You can use the form and schema to be retrieve the valid attribute values and by that be guided towards successful creation. + Request Create project + Body { "identifier": "new_project_identifier", "name": "New project name", "customField35": "Text custom field value" "_links": { "customField12": { "href": "/api/v3/users/5" } } } + Response 201 [Project][] + Response 400 (application/hal+json) Occurs when the client did not send a valid JSON object in the request body. + Body { "_type": "Error", "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody", "message": "The request body was not a single JSON object." } + Response 403 (application/hal+json) Returned if the client does not have sufficient permissions. **Required permission:** add project which is a global permission + Body { "_type": "Error", "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission", "message": "You are not authorized to access this resource." } + Response 422 (application/hal+json) Returned if: * a constraint for a property was violated (`PropertyConstraintViolation`) + Body { "_type": "Error", "errorIdentifier": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation", "message": "Name can't be blank.", "_embedded": { "details": { "attribute": "name" } } } ## Projects schema [/api/v3/projects/schemas] + Model + Body { "_type": "Schema", "_dependencies": [], "id": { "type": "Integer", "name": "ID", "required": true, "hasDefault": false, "writable": false }, "name": { "type": "String", "name": "Name", "required": true, "hasDefault": false, "writable": true, "minLength": 1, "maxLength": 255 }, "identifier": { "type": "String", "name": "Identifier", "required": true, "hasDefault": false, "writable": true, "minLength": 1, "maxLength": 100 }, "description": { "type": "Formattable", "name": "Description", "required": false, "hasDefault": false, "writable": true }, "public": { "type": "Boolean", "name": "Public", "required": true, "hasDefault": false, "writable": true }, "status": { "type": "String", "name": "Status", "required": true, "hasDefault": false, "writable": true, "visibility": "default", "_links": {} }, "createdAt": { "type": "DateTime", "name": "Created on", "required": true, "hasDefault": false, "writable": false }, "updatedAt": { "type": "DateTime", "name": "Updated on", "required": true, "hasDefault": false, "writable": false }, "customField30": { "type": "Integer", "name": "Integer project custom field", "required": false, "hasDefault": false, "writable": true, "visibility": "default" }, "customField31": { "type": "CustomOption", "name": "List project custom field", "required": false, "hasDefault": false, "writable": true, "visibility": "default", "_links": {} }, "customField32": { "type": "Version", "name": "Version project custom field", "required": false, "hasDefault": false, "writable": true, "visibility": "default", "_links": {} }, "customField34": { "type": "Boolean", "name": "Boolean project custom field", "required": false, "hasDefault": false, "writable": true, "visibility": "default" }, "customField35": { "type": "String", "name": "Text project custom field", "required": true, "hasDefault": false, "writable": true, "visibility": "default" }, "_links": { "self": { "href": "/api/v3/projects/schema" } } } ## View project schema [GET] + Response 200 (application/hal+json) [Projects schema][] ## Project create form [/api/v3/project/form] This endpoint returns a form allowing a guided creation of new projects. For more details and all possible responses see the general specification of [Forms](#forms). ## Project create form [POST] + Request Create project form + Body { "identifier": "new_project_identifier", "name": "New project name", "customField35": "Text custom field value" } + Response 200 (application/hal+json) + Body { "_type": "Form", "_embedded": { "payload": { "identifier": "new_project_identifier", "name": "New project name", "status": "active", "public": false, "description": { "format": "markdown", "raw": null, "html": "" }, "customField30": null, "customField34": null, "customField35": "Text custom field value", "customField41": { "format": "markdown", "raw": "", "html": "" }, "customField42": null, "_links": { "customField26": { "href": null, "title": null }, "customField31": { "href": null, "title": null } } }, "schema": { "_type": "Schema", "_dependencies": [], "id": { "type": "Integer", "name": "ID", "required": true, "hasDefault": false, "writable": false }, "name": { "type": "String", "name": "Name", "required": true, "hasDefault": false, "writable": true, "minLength": 1, "maxLength": 255 }, "identifier": { "type": "String", "name": "Identifier", "required": true, "hasDefault": false, "writable": true, "minLength": 1, "maxLength": 100 }, "description": { "type": "Formattable", "name": "Description", "required": false, "hasDefault": false, "writable": true }, "public": { "type": "Boolean", "name": "Public", "required": true, "hasDefault": false, "writable": true }, "status": { "type": "String", "name": "Status", "required": true, "hasDefault": false, "writable": true, "visibility": "default", "_embedded": { "allowedValues": [ "active", "archived" ] }, "_links": {} }, "createdAt": { "type": "DateTime", "name": "Created on", "required": true, "hasDefault": false, "writable": false }, "updatedAt": { "type": "DateTime", "name": "Updated on", "required": true, "hasDefault": false, "writable": false }, "customField26": { "type": "User", "name": "Project user", "required": false, "hasDefault": false, "writable": true, "visibility": "default", "_links": { "allowedValues": { "href": "/api/v3/principals?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22%21%22%2C%22values%22%3A%5B%220%22%2C%223%22%5D%7D%7D%2C%7B%22type%22%3A%7B%22operator%22%3A%22%3D%22%2C%22values%22%3A%5B%22User%22%5D%7D%7D%2C%7B%22member%22%3A%7B%22operator%22%3A%22%3D%22%2C%22values%22%3A%5B%22%22%5D%7D%7D%5D&pageSize=0" } } }, "customField30": { "type": "Integer", "name": "some project cf", "required": false, "hasDefault": false, "writable": true, "visibility": "default" }, "customField31": { "type": "CustomOption", "name": "list project cf", "required": false, "hasDefault": false, "writable": true, "visibility": "default", "_embedded": { "allowedValues": [ { "_type": "CustomOption", "id": 513, "value": "abc", "_links": { "self": { "href": "/api/v3/custom_options/513", "title": "abc" } } }, { "_type": "CustomOption", "id": 514, "value": "def", "_links": { "self": { "href": "/api/v3/custom_options/514", "title": "def" } } }, { "_type": "CustomOption", "id": 515, "value": "ghi", "_links": { "self": { "href": "/api/v3/custom_options/515", "title": "ghi" } } } ] }, "_links": { "allowedValues": [ { "href": "/api/v3/custom_options/513", "title": "abc" }, { "href": "/api/v3/custom_options/514", "title": "def" }, { "href": "/api/v3/custom_options/515", "title": "ghi" } ] } }, "customField34": { "type": "Boolean", "name": "Bool Project CF", "required": false, "hasDefault": false, "writable": true, "visibility": "default" }, "customField35": { "type": "String", "name": "text project cf", "required": true, "hasDefault": false, "writable": true, "visibility": "default" }, "customField41": { "type": "Formattable", "name": "Long text project cf", "required": false, "hasDefault": false, "writable": true, "visibility": "default" }, "customField42": { "type": "Date", "name": "Date project cf", "required": false, "hasDefault": false, "writable": true, "visibility": "default" }, "_links": {} }, "validationErrors": { "identifier": { "_type": "Error", "errorIdentifier": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation", "message": "Identifier has already been taken.", "_embedded": { "details": { "attribute": "identifier" } } } } }, "_links": { "self": { "href": "/api/v3/projects/form", "method": "post" }, "validate": { "href": "/api/v3/projects/form", "method": "post" } } } + Response 400 (application/hal+json) Occurs when the client did not send a valid JSON object in the request body. + Body { "_type": "Error", "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody", "message": "The request body was not a single JSON object." } + Response 403 (application/hal+json) Returned if the client does not have sufficient permissions. **Required permission:** add project which is a global permission + Body { "_type": "Error", "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission", "message": "You are not authorized to access this resource." } ## Projects by version [/api/v3/versions/{id}/projects] + Model + Body { "_links": { "self": { "href": "/api/v3/versions/2/projects" } }, "total": 1, "count": 1, "_type": "Collection", "_embedded": { "elements": [ { "_type": "Project", "_links": { "self": { "href": "/api/v3/projects/1", "title": "Lorem" }, "categories": { "href": "/api/v3/projects/1/categories" }, "versions": { "href": "/api/v3/projects/1/versions" } }, "id": 1, "identifier": "project_identifier", "name": "Project example", "description": { "format": "markdown", "raw": "Lorem **ipsum** dolor sit amet", "html": "

Lorem ipsum dolor sit amet

" }, "createdAt": "2014-05-21T08:51:20Z", "updatedAt": "2014-05-21T08:51:20Z" } ] } } ## List projects with version [GET] This endpoint lists the projects where the given version is available. The projects returned depend on the sharing settings of the given version, but are also limited to the projects that the current user is allowed to see. + Parameters + id (required, integer, `1`) ... Version id + Response 200 (application/hal+json) [Projects by version][] + Response 404 (application/hal+json) Returned if the version does not exist or the client does not have sufficient permissions to see it. **Required permission:** view work packages **or** manage versions (any project where the given version is available) *Note: A client without sufficient permissions shall not be able to test for the existence of a version. That's why a 404 is returned here, even if a 403 might be more appropriate.* + Body { "_type": "Error", "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound", "message": "The specified version does not exist." }