Back to top

OpenProject API v3

General

This is the current DRAFT of the specification for OpenProject APIv3.

Please note that everything in this document might be subject to change in a future version of OpenProject. We intend to keep this specification as accurate as possible, however as long as the APIv3 is not in a stable state it is possible that there are intermediary differences between this specification and the real implementation. While we try to only specify what we want to keep, it might also happen that parts of this specification will be replaced incompatibly until the APIv3 is considered stable.

Hypermedia

TODO: Description & Resources

Formats

TODO: Description and why only JSON

HAL+JSON

HAL is a simple format that gives a consistent and easy way to hyperlink between resources in your API. Read more: http://stateless.co/hal_specification.html

OpenProject API implementation of HAL+JSON format enriches JSON and introduces a few meta properties:

  • _type - specifies the type of the resource (e.g.: WorkPackage, Project)
    • _links - contains all links available for the resource
    • _embedded - contains all embedded objects

HAL does not guarantee that embedded resources are embedded in their full representation, they might as well be partially represented (e.g. some properties can be left out). However in this API you have the guarantee that whenever a resource is embedded, it is embedded in its full representation.

API response structure

All API responses contain a single HAL+JSON object, even collections of objects are technically represented by a single HAL+JSON object that itself contains its members. More details on collections can be found in the Collections Section.

Authentication

For now the API only supports two authentication schemes: session based authentication and basic auth. Depending on the settings of the OpenProject instance many resources can be accessed without being authenticated. In case the instance requires authentication on all requests the client will receive an HTTP 401 status code in response to any request. Otherwise unauthenticated clients have all the permissions of the anonymous user.

Session-based Authentication

This means you have to login to OpenProject via the Web-Interface to be authenticated in the API. This method is well-suited for clients acting within the browser, like the Angular-Client built into OpenProject.

API Key through Basic Auth

Users can authenticate towards the API v3 using basic auth with ‘apikey’ as the user name and their API key as the password. Users can find their API key on their account page.

Example:

API_KEY=2519132cdf62dcf5a66fd96394672079f9e9cad1
curl -u apikey:$API_KEY https://community.openproject.com/api/v3/users/42

Why not username and password?

The simplest way to do basic auth would be to use a user’s username and password naturally. However, OpenProject already has supported API keys in the past for the API v2, though not through basic auth.

Using username and password directly would have some advantages:

  • It is intuitive for the user who then just has to provide those just as they would when logging into OpenProject.

  • No extra logic for token managment necessary.

On the other hand using API keys has some advantages too, which is why we went for that:

  • If compromised while saved on an insecure client the user only has to regenerate the API key instead of changing their password, too.

  • They are naturally long and random which makes them invulnerable to dictionary attacks and harder to crack in general.

Most importantly users may not actually have a password to begin with. Specifically when they have registered through an OpenID Connect provider.

Future Work

For the future we plan to add authentication modes based on OAuth2 and OpenID Connect.

Allowed HTTP methods

  • GET - Get a single resource or collection of resources

  • POST - Create a new resource or perform

  • PATCH - Update a resource

  • DELETE - Delete a resource

Compression

Responses are compressed if requested by the client. Currently gzip and deflate are supported. The client signals the desired compression by setting the Accept-Encoding header. If no Accept-Encoding header is send, Accept-Encoding: identity is assumed which will result in the API responding uncompressed.

Basic Objects

Links

Links to other resources in the API are represented uniformly by so called link objects.

Local Properties

Property Description Type Required Nullable Default
href URL to the referenced resource (might be relative) String
title Representative label for the resource String
templated If true the href contains parts that need to be replaced by the client Boolean false
method The HTTP verb to use when requesting the resource String GET
payload The payload to send in the request to achieve the desired result String unspecified
identifier An optional unique identifier to the link object String unspecified

All link objects must contain the href property, though it might be null. Thus the following is a valid link object:

{ “href”: null }

whereas { } is not a valid link object. The meaning of "href": null is that no resource is referenced. For example a work package without an assignee will still have an assignee link, but its href will be null.

If a title is present, the client can display the title to the user when referring to the resource.

Templated links are links that contain client replaceable parts. Replaceable parts are enclosed in braces. For example the link api/v3/example/{id} is not complete in itself, but the client needs to replace the string {id} itself. As of now the API does not indicate the valid replacement values.

The method indicates which HTTP verb the client must use when following the link for the intended purpose.

If a payload is specified, it needs to be sent as the body of the request to achieve the desired result (e.g. perform the action represented by the link). If no payload is specified, there is either no payload to send or a valid payload is not specified by the link object. A payload might also be templated slightly. If the templated property is true, a payload might contain replaceable parts in its strings (e.g. { "href": "/api/v3/examples/{example_id}" }).

Note: When writing links (e.g. during a PATCH operation) only changes to href are accepted. Changes to all other properties will be silently ignored.

Errors

In case of an error, the API will respond with an apropriate HTTP status code. For responses with an HTTP status of 4xx and 5xx the body will always contain a single error object. Error objects shall give the client additional details about the cause of an errorneous response.

General errors

  • Error objects have their _type set to Error

  • The errorIdentifier serves as a unique (and machine readable) identifier for a specific error cause

    • There may be multiple possible error identifiers per HTTP status code
    • There may be multiple possible HTTP status codes per error identifier
    • The “List of Error Identifiers” defines the possible mappings between HTTP status and error identifier
  • The message contains a human readable concise message describing the error

    • It optionally includes specific information, for example which permission would have been needed to perform an action
    • It is localized depending on the users preferences
    • It must not include HTML or other kind of markup
    • Error messages form complete sentences including punctuation

Example

{ “_type”: “Error”, “errorIdentifier”: “urn:openproject-org:api:v3:errors:InternalServerError”, “message”: “An internal server error occured. This is not your fault.” }

Embedded error information

Errors might optionally contain embedded objects that contain further information.

Error details

Under the embedded key details there might be an object describing the error more verbosely. For example if the error affects a specific field, this field could be defined there.

Example

{ “_type”: “Error”, “errorIdentifier”: “urn:openproject-org:api:v3:examples:ExampleError”, “message”: “This is an example error.”, “_embedded”: { “details”: { “_type”: “ExampleErrorDetailInformation”, “errorneousField”: “subject” } } }

Multiple error objects

To ease implementation of basic clients it is guaranteed that the response body always only contains a single error object. However it is allowed that an error object embeds other error objects under the key errors, thereby aggregating them.

The errorIdentifier of such an object is always urn:openproject-org:api:v3:errors:MultipleErrors. The message can either describe one of the embedded errors or simply state that multiple errors occured.

Example

{ “_type”: “Error”, “errorIdentifier”: “urn:openproject-org:api:v3:errors:MultipleErrors”, “message”: “Multiple fields violated their constraints.”, “_embedded”: { “errors”: [ { “_type”: “Error”, “errorIdentifier”: “urn:openproject-org:api:v3:errors:PropertyConstraintViolation”, “…”: “…” }, { “_type”: “Error”, “errorIdentifier”: “urn:openproject-org:api:v3:errors:PropertyConstraintViolation”, “…”: “…” } ] } }

List of Error Identifiers

  • urn:openproject-org:api:v3:errors:InvalidQuery (HTTP 400) - The query contained a value that did not match the servers expectation

  • urn:openproject-org:api:v3:errors:InvalidRequestBody (HTTP 400) - The format of the request body did not match the servers expectation

  • urn:openproject-org:api:v3:errors:InvalidRenderContext (HTTP 400) - The client specified a rendering context that does not exist

  • urn:openproject-org:api:v3:errors:InvalidUserStatusTransition (HTTP 400) - The client used an invalid transition in the attempt to change the status of a user account.

  • urn:openproject-org:api:v3:errors:Unauthenticated (HTTP 401) - The client has to authenticate to access the requested resource.

  • urn:openproject-org:api:v3:errors:MissingPermission (HTTP 403) - The client does not have the needed permissions to perform the requested action

  • urn:openproject-org:api:v3:errors:NotFound (HTTP 404) - Default for HTTP 404 when no further information is available

  • urn:openproject-org:api:v3:errors:UpdateConflict (HTTP 409) - The resource changed between GET-ing it and performing an update on it

  • urn:openproject-org:api:v3:errors:TypeNotSupported (HTTP 415) - The request contained data in an unsupported media type (Content-Type)

  • urn:openproject-org:api:v3:errors:PropertyIsReadOnly (HTTP 422) - The client tried to set or change a property that is not writable

  • urn:openproject-org:api:v3:errors:PropertyConstraintViolation (HTTP 422) - The client tried to set a property to an invalid value

  • urn:openproject-org:api:v3:errors:PropertyValueNotAvailableAnymore (HTTP 422) - An unchanged property needs to be changed, because other changes to the resource make it unavailable

  • urn:openproject-org:api:v3:errors:ResourceTypeMismatch (HTTP 422) - A link to a resource of a specific type was expected, but the link to another type of resource was provided

  • urn:openproject-org:api:v3:errors:PropertyFormatError (HTTP 422) - A property value was provided in a format that the server does not understand or accept

  • urn:openproject-org:api:v3:errors:InternalServerError (HTTP 500) - Default for HTTP 500 when no further information is available

  • urn:openproject-org:api:v3:errors:MultipleErrors - Multiple errors occured. See the embedded errors array for more details.

Formattable Text

OpenProject supports text formatting in Textile. Other text formats may be introduced in the future. Properties that contain formattable text have a special representation in this API. In this specification their type is indicated as Formattable. Their representation contains the following properties:

Property Description Type Example Supported operations
format Indicates the formatting language of the raw text String textile READ
raw The raw text, as entered by the user String I *am* formatted! READ / WRITE
html The text converted to HTML according to the format String I <strong>am</strong> formatted! READ

format can as of today have one of the following values:

  • plain - only basic formatting, e.g. inserting paragraphs and line breaks into HTML

  • textile - formatting using Textile

  • custom - There is no apparent formatting rule that transforms the raw version to HTML (only used for read only properties)

More formats might be added in the future.

Note that raw is the only property supporting the write operation. A property of type Formattable that is marked as read and write, will only accept changes to the raw property. Changes to format and html will be silently ignored. It is thus sufficient to solely provide the raw property for changes.

If the Formattable is marked as read only, the raw attribute also becomes read only.

Example

{ “format”: “textile”, “raw”: “I am formatted!”, “html”: “I am formatted!” }

Dates, Times and Durations

Representation of time related values in this API is done according to ISO 8601. In this specification the following terms will be used as type specifiers (e.g. in tables):

  • Date - refers to an ISO 8601 date, e.g. “2014-05-21”

  • DateTime - refers to an ISO 8601 combined date and time, e.g. “2014-05-21T13:37:00Z”

  • Duration - refers to an ISO 8601 duration, e.g. “P1DT18H”

Colors

Colors are represented in RGB using hexadecimal notation as specified in CSS Color Module Level 3. That is a # followed by either three or six hexadecimal digits.

Examples

red: #ff0000 or #f00 green: #00ff00 or #0f0 black: #000000 or #000 white: #ffffff or #fff

Digests

Digests (or Hashes) are one way functions that map data of arbitrary size to data of a fixed size. In OpenProject they are for example used to calculate checksums for (attachment) files. The checksum calculated depends on the hashed data and the algorithm used as hash function.

Therefore all digests are represented in the following form:

Property Description Type Example
algorithm The algorithm used to compute the digest String md5
hash The calculated digest in hexadecimal notation String 64c26a8403cd796ea4cf913cda2ee4a9

Example

{ “algorithm”: “md5”, “hash”: “64c26a8403cd796ea4cf913cda2ee4a9” }

Collections

Whenever a client calls a resource that can return more than one element, it will receive a collection of elements. However as collections can become quite large, the API will not simply return a JSON array, but a special collection object that will contain the actual elements in its embedded property elements.

Collections may be paginated, this means that a single response from the server will not contain all elements of the collection, but only a subset. In this case the client can issue further requests to retrieve the remaining elements. There are two ways to access the result pages of a paginated collection:

  • offset based pagination

  • cursor based pagination

The available ways of pagination depend on the collection queried. Some collections feature no pagination at all, meaning they will always return all elements. Others might only offer one of the two pagination methods or both of them. An explanation of offset and cursor based pagination can be found below the links table.

A collection also carries meta information like the total count of elements in the collection or - in case of a paginated collection - the amount of elements returned in this response and action links to retrieve the remaining elements.

Local Properties

Property Description Type Availability
total The total amount of elements available in the collection Integer always
pageSize Amount of elements that a response will hold Integer when paginated
count Actual amount of elements in this response Integer always
offset The page number that is requested from paginated collection Integer when offset based available
groups Summarized information about aggregation groups Object when grouping
totalSums Aggregations of supported values for elements of the collection Object when showing sums
Link Description Availability
self Link to the current page in the collection always
changeSize Templated link to change the page size, might change relative position when paginated
jumpTo Templated link to jump to a specified offset when offset based available
nextByOffset Link to retrieve the following page of elements (offset based) when offset based available
previousByOffset Link to retrieve the preceding page of elements (offset based) when offset based available
nextByCursor Link to retrieve the elements following the current page (cursor based) when cursor based available
previousByCursor Link to retrieve the elements preceding the current page (cursor based) when cursor based available

Offset based pagination

Offset based pagination works by specifying two values: the offset and the pageSize. The page size determines how many items there will be in a single response at most. The offset determines which page is returned as response, with 1 being the first page (one-indexed). Note that the server might not allow arbitrarily large page sizes, a client should therefore always check the page size accepted by the server using the pageSize property of the response.

The benefit of offset based pagination is that the total number of pages can be easily determined and that it is possible to jump to arbitrary pages within the collection. Offset based pagination is therefore well suited when a result is displayed to the end user in the form of multiple pages anyway.

A drawback of offset based pagination comes with concurrent modification of the collection. If the collection is modified between two page requests, it is possible that the client receives elements close to the page boundaries twice or does not see them at all.

view offset based
GET/api/v3/examples{?offset,pageSize}

Example URI

GET /api/v3/examples?offset=25&pageSize=25
URI Parameters
HideShow
offset
integer (optional) Default: 1 Example: 25

Page number inside the requested collection.

pageSize
integer (optional) Example: 25

Number of elements to display per page.

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/examples?offset=25&pageSize=25"
    },
    "jumpTo": {
      "href": "/api/v3/examples?offset={offset}&pageSize=25",
      "templated": true
    },
    "changeSize": {
      "href": "/api/v3/examples?offset=25&pageSize={size}",
      "templated": true
    },
    "previousByOffset": {
      "href": "/api/v3/examples?offset=0&pageSize=25"
    },
    "previousByCursor": {
      "href": "/api/v3/examples?before=bar&pageSize=25"
    }
  },
  "_type": "Collection",
  "total": 27,
  "pageSize": 25,
  "count": 2,
  "offset": 25,
  "_embedded": {
    "elements": [
      {
        "foo": "bar"
      },
      {
        "foo": "baz"
      }
    ]
  }
}

Cursor based pagination

Cursor based pagination is intended to be used, when the client needs a consistent and complete (sub-) range of the collection, e.g. in infinite scrolling scenarios. In cursor based pagination the client will receive a link to the next and the previous page in the result set. The guarantee is, that the boundaries of that page will align with the boundaries of the current page, regardless of changes to the collection.

The drawback for cursor based pagination is, that it is not immediately determinable how many “next” and how many “previous” pages there are. Cursor based pagination is therefore less suited for use cases where you want to directly “jump” to an arbitrary page.

view cursor based
GET/api/v3/examples{?before,after,pageSize}

Example URI

GET /api/v3/examples?before=bar&after=buz&pageSize=25
URI Parameters
HideShow
before
string (optional) Example: bar

Display the elements preceding the given element. Note that the value of this parameter is very specific to the collection, a client should not try to infer values, but use the previous link offered by the collection.

after
string (optional) Example: buz

Display the elements succeeding the given element. Note that the value of this parameter is very specific to the collection, a client should not try to infer values, but use the next link offered by the collection.

pageSize
integer (optional) Example: 25

Number of elements to display per page.

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/examples?after=buz&pageSize=25"
    },
    "changeSize": {
      "href": "/api/v3/examples?after=buz&pageSize={size}",
      "templated": true
    },
    "previousByCursor": {
      "href": "/api/v3/examples?before=bar&pageSize=25"
    }
  },
  "_type": "Collection",
  "total": 27,
  "pageSize": 25,
  "count": 2,
  "_embedded": {
    "elements": [
      {
        "foo": "bar"
      },
      {
        "foo": "baz"
      }
    ]
  }
}

Aggregations

Collections may support different kinds of aggregations. Some properties can be summed up. If requested the collection will include the totalSums property, which is a dictionary, where the keys represent the names of the summed properties and the values represent their sums. Note that you have to mark a column as summable in the instance settings, to be able to retrieve its sums.

It is also possible to group the contents of a collection. In this case:

  • the elements will be ordered by the specified group key (so that the client receives one group after another)

  • The groups property will contain a collection of group objects

A group object contains aggregation data for the elements of a group:

Local Properties

Property Description Type Availability
value The value to which the group belongs (e.g. the Status’ name) String always
count Actual amount of elements in this response Integer always
sums A dictionary with property sums inside this group (see totalSums) Dictionary when sums requested
Link Description Availability
valueLink Link to the corresponding grouping object (e.g. the Status) only if grouping by a linkable object

Note that you will always receive a value, but only receive a valueLink if the grouping was performed on a linkable property.

view aggregated result
GET/api/v3/examples{?groupBy,showSums}

Example URI

GET /api/v3/examples?groupBy=status&showSums=
URI Parameters
HideShow
groupBy
string (optional) Example: status

The column to group by. Note: Aggregation is as of now only supported by the work package collection. You can pass any column name as returned by the queries endpoint.

showSums
string (optional) Default: false 
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_links": {
        "self": { "href": "/api/v3/examples?groupBy=foo&showSums=true" },
        "changeSize": {
            "href": "/api/v3/examples?after=buz&pageSize={size}",
            "templated": true
        }
    },
    "_type": "Collection",
    "total": 5,
    "pageSize": 25,
    "count": 5,
    "_embedded": {
        "elements": [
            { "foo": "bar", "i": 1 },
            { "foo": "bar", "i": 2 },
            { "foo": "bar", "i": 3 },
            { "foo": "baz", "i": 4 },
            { "foo": "baz", "i": 5 }
        ],
        "groups": [
            {
                "value : "bar",
                "count": 3,
                "sums": {
                    "i": 6
                }
            },
            {
                "value : "baz",
                "count": 2,
                "sums": {
                    "i": 9
                }
            }
        ],
        "totalSums": {
            "i": 15
        }
    }
}

Activities

Local Properties

Property Description Type Constraints Supported operations
id Activity id Integer x > 0 READ
version Activity version Integer x > 0 READ
comment Formattable READ / WRITE
details Array of Formattable READ
createdAt Time of creation DateTime READ

Activity can be either _type Activity or _type Activity::Comment.

Activity

View activity
GET/api/v3/activities/{id}

Example URI

GET /api/v3/activities/1
URI Parameters
HideShow
id
integer (required) Example: 1

Activity id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Activity::Comment",
  "_links": {
    "self": {
      "href": "/api/v3/activity/1",
      "title": "Priority changed from High to Low"
    },
    "workPackage": {
      "href": "/api/v3/work_packages/1",
      "title": "quis numquam qui voluptatum quia praesentium blanditiis nisi"
    },
    "user": {
      "href": "/api/v3/users/1",
      "title": "John Sheppard - admin"
    }
  },
  "id": 1,
  "details": [
    {
      "format": "textile",
      "raw": "Lorem ipsum dolor sit amet.",
      "html": "<p>Lorem ipsum dolor sit amet.</p>"
    }
  ],
  "comment": {
    "format": "textile",
    "raw": "Lorem ipsum dolor sit amet.",
    "html": "<p>Lorem ipsum dolor sit amet.</p>"
  },
  "createdAt": "2014-05-21T08:51:20Z",
  "version": 31
}

Update activity
PATCH/api/v3/activities/{id}

Updates an activity’s comment and, on success, returns the updated activity.

Example URI

PATCH /api/v3/activities/1
URI Parameters
HideShow
id
integer (required) Example: 1

Activity id

Request
HideShow
Headers
Content-Type: application/json
Body
{
  "comment": {
    "raw": "The updated comment"
  }
}
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Activity::Comment",
  "_links": {
    "self": {
      "href": "/api/v3/activity/1",
      "title": "Priority changed from High to Low"
    },
    "workPackage": {
      "href": "/api/v3/work_packages/1",
      "title": "quis numquam qui voluptatum quia praesentium blanditiis nisi"
    },
    "user": {
      "href": "/api/v3/users/1",
      "title": "John Sheppard - admin"
    }
  },
  "id": 1,
  "details": [
    {
      "format": "textile",
      "raw": "Lorem ipsum dolor sit amet.",
      "html": "<p>Lorem ipsum dolor sit amet.</p>"
    }
  ],
  "comment": {
    "format": "textile",
    "raw": "Lorem ipsum dolor sit amet.",
    "html": "<p>Lorem ipsum dolor sit amet.</p>"
  },
  "createdAt": "2014-05-21T08:51:20Z",
  "version": 31
}
Response  400
HideShow

Occurs when the client did not send a valid JSON object in the request body.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
  "message": "The request body was not a single JSON object."
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: edit journals

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to edit the comment of this journal entry."
}
Response  422
HideShow

Returned if the client tries to modify a read-only property.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:PropertyIsReadOnly",
  "message": "The ID of an activity can't be changed."
}

Attachments

Attachments are files that were uploaded to OpenProject. Each attachment belongs to a single container (e.g. a work package or a board message).

Actions

Link Description Condition
delete Deletes this attachment Permission: edit on attachment container

Linked Properties

Link Description Type Constraints Supported operations
self This attachment Attachment not null READ
container The object (e.g. WorkPackage) housing the attachment Anything not null READ
author The user who uploaded the attachment User not null READ
downloadLocation Direct download link to the attachment - not null READ

Local Properties

Property Description Type Constraints Supported operations
id Attachment’s id Integer x > 0 READ
fileName The name of the uploaded file String not null READ
fileSize The size of the uploaded file in Bytes Integer x >= 0 READ
description A user provided description of the file Formattable not null READ
contentType The files MIME-Type as determined by the server String not null READ
digest A checksum for the files content Digest not null READ
createdAt Time of creation DateTime not null READ

Attachment

View attachment
GET/api/v3/attachments/{id}

Example URI

GET /api/v3/attachments/1
URI Parameters
HideShow
id
integer (required) Example: 1

Attachment id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_type": "Attachment",
    "_links": {
        "self": {
            "href": "/api/v3/attachments/1"
        },
        "container" {
            "href": "/api/v3/work_packages/1"
        },
        "author": {
            "href": "/api/v3/users/1"
        },
        "downloadLocation": {
            "href": "/attachments/1/download"
        }
    },
    "id": 1,
    "fileName": "cat.png",
    "filesize": 24,
    "description": {
        "format": "plain",
        "raw": "A picture of a cute cat",
        "html": "<p>A picture of a cute cat</p>"
    },
    "contentType": "image/png",
    "digest": {
        "algorithm": "md5",
        "64c26a8403cd796ea4cf913cda2ee4a9":
    },
    "createdAt": "2014-05-21T08:51:20Z"
}
Response  404
HideShow

Returned if the attachment does not exist or the client does not have sufficient permissions to see it.

Required permission: view permission for the container of the attachment

Note: A client without sufficient permissions shall not be able to test for the existence of an attachment. That’s why a 404 is returned here, even if a 403 might be more appropriate.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified attachment does not exist."
}

Delete attachment
DELETE/api/v3/attachments/{id}

Permanently deletes the specified attachment.

Example URI

DELETE /api/v3/attachments/1
URI Parameters
HideShow
id
integer (required) Example: 1

Attachment id

Response  204
HideShow

Returned if the attachment was deleted successfully.

Note that the response body is empty as of now. In future versions of the API a body might be returned along with an appropriate HTTP status.

Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: edit permission for the container of the attachment

Note that you will only receive this error, if you are at least allowed to see the attachment.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to delete this attachment."
}
Response  404
HideShow

Returned if the attachment does not exist or the client does not have sufficient permissions to see it.

Required permission: view permission for the container of the attachment

Note: A client without sufficient permissions shall not be able to test for the existence of an attachment. That’s why a 404 is returned here, even if a 403 might be more appropriate.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified attachment does not exist."
}

Attachments by work package

List attachments
GET/api/v3/work_packages/{id}/attachments

Example URI

GET /api/v3/work_packages/1/attachments
URI Parameters
HideShow
id
integer (required) Example: 1

ID of the work package whose attachments will be listed

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_links": {
        "self": { "href": "/api/v3/work_packages/1/attachments" }
    },
    "total": 2,
    "count": 2,
    "_type": "Collection",
    "_embedded":
    {
        "elements": [
            {
                "_type": "Attachment",
                "_links": {
                    "self": {
                        "href": "/api/v3/attachments/1"
                    },
                    "container" {
                        "href": "/api/v3/work_packages/1"
                    },
                    "author": {
                        "href": "/api/v3/users/1"
                    },
                    "downloadLocation": {
                        "href": "/attachments/1/download"
                    }
                },
                "id": 1,
                "fileName": "cat.png",
                "filesize": 24,
                "description": {
                    "format": "plain",
                    "raw": "A picture of a cute cat",
                    "html": "<p>A picture of a cute cat</p>"
                },
                "contentType": "image/png",
                "digest": {
                    "algorithm": "md5",
                    "64c26a8403cd796ea4cf913cda2ee4a9":
                },
                "createdAt": "2014-05-21T08:51:20Z"
            },
            {
                "_type": "Attachment",
                "_links": {
                    "self": {
                        "href": "/api/v3/attachments/2"
                    },
                    "container" {
                        "href": "/api/v3/work_packages/1"
                    },
                    "author": {
                        "href": "/api/v3/users/1"
                    },
                    "downloadLocation": {
                        "href": "/attachments/2/download"
                    }
                },
                "id": 2,
                "fileName": "cat2.png",
                "filesize": 24,
                "description": {
                    "format": "plain",
                    "raw": "A picture of another cute cat",
                    "html": "<p>A picture of another cute cat</p>"
                },
                "contentType": "image/png",
                "digest": {
                    "algorithm": "md5",
                    "46c26a8403cd769ea4c9f13cdae2e49a":
                },
                "createdAt": "2014-05-21T08:51:20Z"
            }
        ]
    }
}
Response  404
HideShow

Returned if the work package does not exist or the client does not have sufficient permissions to see it.

Required permission: view work package

Note: A client without sufficient permissions shall not be able to test for the existence of a work package. That’s why a 404 is returned here, even if a 403 might be more appropriate.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified work package does not exist."
}

Add attachment
POST/api/v3/work_packages/{id}/attachments

To add an attachment to a work package, a client needs to issue a request of type multipart/form-data with exactly two parts.

The first part must be called metadata. Its content type is expected to be application/json, the body must be a single JSON object, containing at least the fileName and optionally the attachments description.

The second part must be called file, its content type should match the mime type of the file. The body must be the raw content of the file. Note that a filename must be indicated in the Content-Disposition of this part, however it will be ignored. Instead the fileName inside the JSON of the metadata part will be used.

Example URI

POST /api/v3/work_packages/1/attachments
URI Parameters
HideShow
id
integer (required) Example: 1

ID of the work package to receive the attachment

Request
HideShow
Headers
Content-Type: multipart/form-data
Body
--boundary-delimiter
Content-Disposition: form-data; name="metadata"
Content-Type: application/json; charset=UTF-8

{
  "fileName": "cute-cat.png",
  "description": {
    "raw": "A cute kitty, cuddling with its friends!"
  }
}

--boundary-delimiter
Content-Disposition: form-data; name="file"; filename="attachment"
Content-Type: image/png

PNG file data
--boundary-delimiter--
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_type": "Attachment",
    "_links": {
        "self": {
            "href": "/api/v3/attachments/1"
        },
        "container" {
            "href": "/api/v3/work_packages/1"
        },
        "author": {
            "href": "/api/v3/users/1"
        },
        "downloadLocation": {
            "href": "/attachments/1/download"
        }
    },
    "id": 1,
    "fileName": "cat.png",
    "filesize": 24,
    "description": {
        "format": "plain",
        "raw": "A picture of a cute cat",
        "html": "<p>A picture of a cute cat</p>"
    },
    "contentType": "image/png",
    "digest": {
        "algorithm": "md5",
        "64c26a8403cd796ea4cf913cda2ee4a9":
    },
    "createdAt": "2014-05-21T08:51:20Z"
}
Response  400
HideShow

Returned if the client sends a not understandable request. Reasons include:

  • Omitting one of the required parts (metadata and file)

  • sending unparsable JSON in the metadata part

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
  "message": "The request could not be parsed as JSON."
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: edit work package or add work package

Note that you will only receive this error, if you are at least allowed to see the work package.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to delete this attachment."
}
Response  404
HideShow

Returned if the work package does not exist or the client does not have sufficient permissions to see it.

Required permission: view work package

Note: A client without sufficient permissions shall not be able to test for the existence of a work package. That’s why a 404 is returned here, even if a 403 might be more appropriate.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified work package does not exist."
}
Response  422
HideShow

Returned if the client tries to send an invalid attachment. Reasons are:

  • Omitting the file name (fileName property of metadata part)

  • Sending a file that is too large

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation",
  "message": "File is too large (maximum size is 5242880 Bytes)."
}

Categories

Linked Properties

Link Description Type Constraints Supported operations
self This category Category not null READ
project The project of this category Project not null READ
defaultAssignee Default assignee for work packages of this category User READ

Local Properties

Property Description Type Constraints Supported operations
id Category id Integer x > 0 READ
name Category name String READ

Categories by Project

List categories of a project
GET/api/v3/projects/{project_id}/categories

Example URI

GET /api/v3/projects/1/categories
URI Parameters
HideShow
project_id
integer (required) Example: 1

ID of the project whoose categories will be listed

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/projects/11/categories"
    }
  },
  "total": 2,
  "count": 2,
  "_type": "Collection",
  "_embedded": {
    "elements": [
      {
        "_links": {
          "self": {
            "href": "/api/v3/categories/10",
            "title": "Category with assignee"
          },
          "project": {
            "href": "/api/v3/projects/11",
            "title": "Example project"
          },
          "defaultAssignee": {
            "href": "/api/v3/users/42",
            "title": "John Sheppard"
          }
        },
        "_type": "Category",
        "id": 10,
        "name": "Foo"
      },
      {
        "_links": {
          "self": {
            "href": "/api/v3/categories/11"
          },
          "project": {
            "href": "/api/v3/projects/11"
          }
        },
        "_type": "Category",
        "id": 11,
        "name": "Bar"
      }
    ]
  }
}
Response  404
HideShow

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.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified project does not exist."
}

Category

View Category
GET/api/v3/categories/{id}

Example URI

GET /api/v3/categories/1
URI Parameters
HideShow
id
integer (required) Example: 1

category id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/categories/10",
      "title": "Category with assignee"
    },
    "project": {
      "href": "/api/v3/projects/11",
      "title": "Example project"
    },
    "defaultAssignee": {
      "href": "/api/v3/users/42",
      "title": "John Sheppard"
    }
  },
  "_type": "Category",
  "id": 10,
  "name": "Foo"
}
Response  404
HideShow

Returned if the category does not exist or the client does not have sufficient permissions to see it.

Required permission: view project (defining the category)

Note: A client without sufficient permissions shall not be able to test for the existence of a category. That’s why a 404 is returned here, even if a 403 might be more appropriate.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified category does not exist."
}

Configuration

The configuration endpoint allows to read certain configuration parameters of the OpenProject instance. Note that there is no 1:1 relationship between this endpoint and the settings you can find in your settings.yml.

For now this endpoint will only allow access to settings deemed useful for a client to know in general.

Link Description Type Nullable Supported operations
self The configuration Configuration READ

Local Properties

Property Description Type Condition Supported operations
maximumAttachmentFileSize The maximum allowed size of an attachment in Bytes Integer READ
perPageOptions Page size steps to be offered in paginated list UI Integer[] READ

Configuration

View configuration
GET/api/v3/configuration

Example URI

GET /api/v3/configuration
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Configuration",
  "_links": {
    "href": "/api/v3/configuration"
  },
  "maximumAttachmentFileSize": 5242880,
  "perPageOptions": [
    1,
    10,
    100
  ]
}

Custom Objects

Linked Properties

Link Description Type Constraints Supported operations
self This custom object CustomObject not null READ

Local Properties

Property Description Type Constraints Supported operations
id The identifier Integer READ
value The value defined for this custom object String READ

Custom objects are options of list custom fields.

Custom Object

View Custom Object
GET/api/v3/custom_objects/{id}

Example URI

GET /api/v3/custom_objects/1
URI Parameters
HideShow
id
integer (required) Example: 1

The custom object’s identifier

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/custom_objects/1"
    }
  },
  "_type": "CustomObject",
  "value": "Foo"
}
Response  404
HideShow

Returned if the custom object does not exist or the client does not have sufficient permissions to see it.

Required permission: view work package in any project the custom object’s custom field is active in.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified resource does not exist."
}

Forms

This API provides forms as a concept to aid in editing or creating resources. The goal of forms is to:

  • make writable properties of a resource discoverable

  • show to which values a property can be set

  • validate changes to a resource and indicate validation errors

These benefits aside, a client can freely choose to immediately edit a resource without prior validation by a form. In the case of an invalid request the edit will fail and return appropriate errors nevertheless.

A form is associated to a single resource and aids in performing changes on that resource. When posting to a form endpoint with an empty request body or an empty JSON object, you will receive an initial form for the associated resource. Subsequent calls to the form should contain a single JSON object as described by the form.

Actions

Link Description Condition
validate Validate changes, show errors and allowed values for changed resource
commit Actually perform changes to the resource form content is valid
previewMarkup Post markup (e.g. textile) here to receive an HTML-rendered response

Linked Properties

Link Description Type Nullable Supported operations
self This form Form READ

Embedded Properties:

Apart from the linked properties, forms contain always three other embedded properties:

  • payload

  • schema

  • validationErrors

Their purpose is explained below.

Payload

The payload contains an edited version of the resource that will be modified when commiting the form. This representation contains all writable properties of the resource and reflects all changes that the latest call to validate included, thereby acting as a preview for the changes.

In case the client tries to set the value to something invalid, the invalid change is also reflected here. However a validation error (see below) indicates that a commit of this payload would fail.

It might happen that setting one property affects the allowed values for another property. Thus by changing a property A the current value of another property B might become invalid. If the client did not yet touch the value of B, the payload will contain a default value for that property. Nevertheless the client will also receive an apropriate validation error for value B.

The content of this element can be used as a template for the request body of a call to validate or commit.

A call to validate and commit does not need to include all properties that were defined in the payload section. It is only necessary to include the properties that you want to change, as well as the lockVersion if one is present. However you may include all the properties sent in the payload section.

Schema

The schema embedded in a form is a normal schema describing the underlying resource. However, the embedded schema can change with each revalidation of the form. For example it might be possible, that changing the type of a work package affects its available properties, as well as possible values for certain properties. As this makes the embedded schema very dynamic, it is not included as a static link.

Validation Errors

Like a schema the validation errors build a dictionary where the key is a property name. Each value is an error object that indicates the error that occured validating the corresponding property. There are only key value pairs for properties that failed validation, the element is empty if all validations succeeded.

However note that even in the case of validation errors, the response you receive from the form endpoint will be an HTTP 200. That is because the main purpose of a form is helping the client to sort out validation errors.

Example Form

show or validate form
POST/api/v3/example/form

This is an example of how a form might look like. Note that this endpoint does not exist in the actual implementation.

Example URI

POST /api/v3/example/form
Request
HideShow
Headers
Content-Type: application/json
Body
{
  "lockVersion": 5,
  "_type": "Example",
  "subject": "An example title"
}
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/example/form"
    },
    "validate": {
      "href": "/api/v3/example/form",
      "method": "POST"
    },
    "previewMarkup": {
      "href": "/api/v3/render/textile",
      "method": "POST"
    },
    "commit": {
      "href": "/api/v3/example",
      "method": "PATCH"
    }
  },
  "_type": "Form",
  "_embedded": {
    "payload": {
      "_links": {
        "status": {
          "href": "/api/v3/statuses/1"
        }
      },
      "_type": "Example",
      "lockVersion": 5,
      "subject": "An example title"
    },
    "schema": {
      "_type": "Schema",
      "_links": {
        "self": {
          "href": "/api/v3/example/schema"
        }
      },
      "lockVersion": {
        "type": "Integer",
        "writable": false
      },
      "subject": {
        "type": "String",
        "minLength": 1,
        "maxLength": 255
      },
      "status": {
        "_links": {
          "allowedValues": [
            {
              "href": "/api/v3/statuses/1",
              "title": "New"
            },
            {
              "href": "/api/v3/statuses/2",
              "title": "Closed"
            }
          ]
        },
        "type": "Status",
        "_embedded": {
          "allowedValues": [
            {
              "_links": {
                "self": {
                  "href": "/api/v3/statuses/1"
                }
              },
              "_type": "Status",
              "id": 1,
              "name": "New",
              "position": 1,
              "isDefault": true,
              "isClosed": false,
              "defaultDoneRatio": 0,
              "createdAt": "2014-05-21T08:51:20Z",
              "updatedAt": "2014-05-21T09:12:00Z"
            },
            {
              "_links": {
                "self": {
                  "href": "/api/v3/statuses/2"
                }
              },
              "_type": "Status",
              "id": 2,
              "name": "Closed",
              "position": 2,
              "isDefault": false,
              "isClosed": true,
              "defaultDoneRatio": 100,
              "createdAt": "2014-05-21T08:51:20Z",
              "updatedAt": "2014-05-21T09:12:00Z"
            }
          ]
        }
      }
    },
    "validationErrors": {
      "subject": {
        "_type": "Error",
        "errorIdentifier": "urn:openproject-org:api:v3:errors:BadExampleError",
        "message": "For the purpose of this example we need a validation error. The remainder of the response pretends there were no errors."
      }
    }
  }
}
Response  400
HideShow

Occurs when the client did not send a valid JSON object in the request body and the request body was not empty.

Note that this error only occurs when the content is not at all a single JSON object. It does not occur for requests containing undefined properties or invalid property values.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
  "message": "The request body was neither empty, nor did it contain a single JSON object."
}
Response  403
HideShow

Returned if the client does not have sufficient permissions to modify the associated resource.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to edit example resources."
}
Response  409
HideShow

Returned if underlying resource was changed since the client requested the form. This is determined using the lockVersion property.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:UpdateConflict",
  "message": "The resource you are about to edit was changed in the meantime."
}

Help texts

Linked Properties

Link Description Type Constraints Supported operations
self This help text HelpText not null READ
editText Edit the help text entry text/htm Admin READ

Local Properties

Property Description Type Constraints Supported operations
id Help text id Integer x > 0 READ
attribute Attribute name String READ
attributeCaption Attribute caption String READ
helpText Help text content Formattable READ

Help texts

List all help texts
GET/api/v3/help_texts

Example URI

GET /api/v3/help_texts
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_links":
    {
        "self":
        {
            "href": "/api/v3/help_texts"
        }
    },
    "total": 2,
    "count": 2,
    "_type": "Collection",
    "_embedded":
    {
        "elements": [
            {
                "_type": "HelpText",
                "_links": {
                    "self": {
                        "href": "/api/v3/help_texts/1",
                    }
                },
                "id": 1,
                "attribute": 'id',
                "attributeCaption": 'ID',
                "scope": 'WorkPackage',
                "helpText": {
                    "format": "textile",
                    "raw": "Help text for id attribute.",
                    "html": "<p>Help text for id attribute.</p>"
                }
            },
            {
                "_type": "HelpText",
                "_links": {
                    "self": {
                        "href": "/api/v3/help_texts/2",
                    }
                },
                "id": 2,
                "attribute": 'status',
                "attributeCaption": 'Status',
                "scope": 'WorkPackage',
                "helpText": {
                    "format": "textile",
                    "raw": "Help text for status attribute.",
                    "html": "<p>Help text for status attribute.</p>"
                }
            }
        ]
    }
}

Help text

View help text
GET/api/v3/help_texts/{id}

Example URI

GET /api/v3/help_texts/1
URI Parameters
HideShow
id
integer (required) Example: 1

Help text id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_type": "HelpText",
    "_links": {
        "self": {
            "href": "/api/v3/help_texts/1",
        },
        "editText": {
            "type": "text/html",
            "href": "/admin/attribute_help_texts/1/edit",
        }
    },
    "id": 1,
    "attribute": 'id',
    "attributeCaption": 'ID',
    "scope": 'WorkPackage',
    "helpText": {
        "format": "textile",
        "raw": "Help text for id attribute.",
        "html": "<p>Help text for id attribute.</p>"
    }
}

Principals

Principals are the superclass of groups and users.

Currently, OpenProject represents groups the same way it represents users. This is subject to change.

Linked Properties

See user

Local Properties

See user

Principals

List principals
GET/api/v3/principals{?filters}

List all principals. The client can choose to filter the principals similar to how work packages are filtered. In addition to the provided filters, the server will reduce the result set to only contain principals who are members in projects the client is allowed to see.

Example URI

GET /api/v3/principals?filters=[{ "type": { "operator": "=", "values": ["User"] }" }]
URI Parameters
HideShow
filters
string (optional) Example: [{ "type": { "operator": "=", "values": ["User"] }" }]

JSON specifying filter conditions. Accepts the same format as returned by the queries endpoint. Currently supported filters are:

  • type: filters principals by their type (User, Group).

  • member: filters principals by the projects they are members in.

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Collection",
  "total": 3,
  "count": 3,
  "_embedded": {
    "elements": [
      {
        "_type": "User",
        "id": 4,
        "login": "Eliza92778",
        "admin": false,
        "subtype": "User",
        "firstName": "Danika",
        "lastName": "O'Keefe",
        "name": "Danika O'Keefe",
        "email": "jackie@dicki.org",
        "avatar": "http://gravatar.com/avatar/d15034e1c02bb32bb152637494860ce5?default=identicon&secure=false",
        "createdAt": "2015-03-20T12:57:02Z",
        "updatedAt": "2015-06-16T15:28:14Z",
        "status": "active",
        "identityUrl": null,
        "_links": {
          "self": {
            "href": "/api/v3/users/4",
            "title": "Danika O'Keefe"
          },
          "showUser": {
            "href": "/users/4",
            "type": "text/html"
          },
          "updateImmediately": {
            "href": "/api/v3/users/4",
            "title": "Update Eliza92778",
            "method": "patch"
          },
          "lock": {
            "href": "/api/v3/users/4/lock",
            "title": "Set lock on Eliza92778",
            "method": "post"
          },
          "delete": {
            "href": "/api/v3/users/4",
            "title": "Delete Eliza92778",
            "method": "delete"
          }
        }
      },
      {
        "_type": "User",
        "id": 2,
        "login": "Sebastian9686",
        "admin": false,
        "subtype": "User",
        "firstName": "Peggie",
        "lastName": "Feeney",
        "name": "Peggie Feeney",
        "email": null,
        "avatar": "http://gravatar.com/avatar/1d89e51dcf03b152b374b43510e2012a?default=identicon&secure=false",
        "createdAt": "2015-03-20T12:56:55Z",
        "updatedAt": "2015-03-20T12:56:55Z",
        "status": "active",
        "identityUrl": null,
        "_links": {
          "self": {
            "href": "/api/v3/users/2",
            "title": "Peggie Feeney"
          },
          "showUser": {
            "href": "/users/2",
            "type": "text/html"
          },
          "updateImmediately": {
            "href": "/api/v3/users/2",
            "title": "Update Sebastian9686",
            "method": "patch"
          },
          "lock": {
            "href": "/api/v3/users/2/lock",
            "title": "Set lock on Sebastian9686",
            "method": "post"
          },
          "delete": {
            "href": "/api/v3/users/2",
            "title": "Delete Sebastian9686",
            "method": "delete"
          }
        }
      },
      {
        "_type": "User",
        "id": 9,
        "login": "",
        "admin": false,
        "subtype": "Group",
        "firstName": "",
        "lastName": "Group 1",
        "name": "Group 1",
        "email": null,
        "avatar": "",
        "createdAt": "2015-09-23T11:06:36Z",
        "updatedAt": "2015-09-23T11:06:36Z",
        "status": "active",
        "_links": {
          "self": {
            "href": "/api/v3/users/9",
            "title": "Group 1"
          },
          "showUser": {
            "href": "/users/9",
            "type": "text/html"
          },
          "updateImmediately": {
            "href": "/api/v3/users/9",
            "title": "Update ",
            "method": "patch"
          },
          "delete": {
            "href": "/api/v3/users/9",
            "title": "Delete ",
            "method": "delete"
          }
        }
      }
    ]
  },
  "_links": {
    "self": {
      "href": "/api/v3/principals"
    }
  }
}

Priorities

Linked Properties

Link Description Type Constraints Supported operations
self This priority Priority not null READ

Local Properties

Property Description Type Constraints Supported operations
id Priority id Integer x > 0 READ
name Priority name String not empty READ
position Sort index of the priority Integer x > 0 READ
isDefault Indicates whether this is the default value Boolean READ
isActive Indicates whether the priority is available Boolean READ

Priorities

List all Priorities
GET/api/v3/priorities

Example URI

GET /api/v3/priorities
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/priorities"
    }
  },
  "_type": "Collection",
  "total": 4,
  "count": 4,
  "_embedded": {
    "elements": [
      {
        "_type": "Priority",
        "_links": {
          "self": {
            "href": "/api/v3/priorities/1",
            "title": "Low"
          }
        },
        "id": 1,
        "name": "Low",
        "position": 1,
        "isDefault": false,
        "isActive": true
      },
      {
        "_type": "Priority",
        "_links": {
          "self": {
            "href": "/api/v3/priorities/2",
            "title": "Normal"
          }
        },
        "id": 2,
        "name": "Normal",
        "position": 2,
        "isDefault": true,
        "isActive": true
      },
      {
        "_type": "Priority",
        "_links": {
          "self": {
            "href": "/api/v3/priorities/3",
            "title": "High"
          }
        },
        "id": 3,
        "name": "High",
        "position": 3,
        "isDefault": false,
        "isActive": true
      },
      {
        "_type": "Priority",
        "_links": {
          "self": {
            "href": "/api/v3/priorities/4",
            "title": "Immediate"
          }
        },
        "id": 4,
        "name": "Immediate",
        "position": 5,
        "isDefault": false,
        "isActive": true
      }
    ]
  }
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: view work package (on any project)

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to see the priorities."
}

Priority

View Priority
GET/api/v3/priorities/{id}

Example URI

GET /api/v3/priorities/1
URI Parameters
HideShow
id
integer (required) Example: 1

Priority id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Priority",
  "_links": {
    "self": {
      "href": "/api/v3/priorities/1",
      "title": "Low"
    }
  },
  "id": 1,
  "name": "Low",
  "position": 1,
  "isDefault": false,
  "isActive": true
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: view work package (on any project)

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to see this priority."
}

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
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
versions Versions available in this project Collection not null READ
workPackages Work Packages of this project Collection not null READ

Local Properties

Property Description Type Constraints Supported operations
id Projects’s id Integer x > 0 READ
identifier String READ
name String READ
description String READ
createdAt Time of creation DateTime READ
updatedAt Time of the most recent change to the project DateTime READ

Project

View project
GET/api/v3/projects/{id}

Example URI

GET /api/v3/projects/1
URI Parameters
HideShow
id
integer (required) Example: 1

Project id

Response  200
HideShow
Headers
Content-Type: application/hal+json
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"
    }
  },
  "id": 1,
  "identifier": "project_identifier",
  "name": "Project example",
  "description": "Lorem ipsum dolor sit amet",
  "createdAt": "2014-05-21T08:51:20Z",
  "updatedAt": "2014-05-21T08:51:20Z"
}
Response  404
HideShow

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.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified project does not exist."
}

Projects

List projects
GET/api/v3/projects{?filters}

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.

Example URI

GET /api/v3/projects?filters=[{ "ancestor": { "operator": "=", "values": ['1'] }" }]
URI Parameters
HideShow
filters
string (optional) Example: [{ "ancestor": { "operator": "=", "values": ['1'] }" }]

JSON specifying filter conditions. Accepts the same format as returned by the queries endpoint. Currently supported filters are:

  • ancestor: filters projects by their ancestor. A project is not considered to be it’s own ancestor.
Response  200
HideShow
Headers
Content-Type: application/hal+json
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",
        "description": "Eveniet molestias omnis quis aut qui eum adipisci.",
        "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",
        "description": "",
        "createdAt": "2016-02-29T12:50:20+00:00",
        "updatedAt": "2016-02-29T12:50:20+00:00",
        "type": null
      }]
    }
  }
}

Projects by version

List projects with version
GET/api/v3/versions/{id}/projects

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.

Example URI

GET /api/v3/versions/1/projects
URI Parameters
HideShow
id
integer (required) Example: 1

Version id

Response  200
HideShow
Headers
Content-Type: application/hal+json
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": "Lorem ipsum dolor sit amet",
        "createdAt": "2014-05-21T08:51:20Z",
        "updatedAt": "2014-05-21T08:51:20Z"
      }
    ]
  }
}
Response  404
HideShow

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.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified version does not exist."
}

Queries

A query defines how work packages can be filtered and displayed. Clients can define a query once, store it, and use it later on to load the same set of filters.

Actions

Link Description Condition
star Elevates the query to the status of ‘starred’ Permission: save queries for own queries, manage public queries for public queries; Only present if query is not yet starred
unstar Removes the ‘starred’ status Permission: save queries for own queries, manage public queries for public queries; Only present if query is starred
update Use the Form based process to verify the query before persisting Permission: view work packages
updateImmediately Persist the query without using a Form based process for guidance Permission: save queries for own queries, manage public queries for public queries;

Linked Properties

Property Description Type Constraints Supported operations
self This query Query not null READ
user The user that owns this query User not null READ
project The project on which this query operates Project READ
columns Ordered list of QueryColumns. The columns, when maped to WorkPackage properties determine which WorkPackage properties to display []QueryColumn READ
sortBy Ordered list of QuerySortBys. Indicates the WorkPackage property the results will be ordered by as well as the direction []QuerySortBy READ
groupBy The WorkPackage property results of this query are grouped by String READ
results The list of work packages returned by applying the filters, sorting and grouping defined in the query WorkPackageCollection READ
schema This query’s schema Schema READ

Please note, that all the properties listed above will also be embedded when individual queries are returned but will not be embedded when a list of queries is returned. Whether the properties are embedded or not may be subject to change in the future.

Local Properties

Property Description Type Constraints Supported operations
id Query id Integer x > 0 READ
name Query name String READ
filters A set of QueryFilters which will be applied to the work packages to determine the resulting work packages []QueryFilterInstance READ
sums Should sums (of supported properties) be shown? Boolean READ
timelineVisible Should the timeline mode be shown? Boolean READ
timelineLabels Which labels are shown in the timeline, empty when default QueryTimelineLabels READ
timelineZoomLevel Which zoom level should the timeline be rendered in? String days, weeks, months, quarters, years READ
showHierarchies Should the hierarchy mode be enabled? Boolean READ
public Can users besides the owner see the query? Boolean READ
starred Should the query be highlighted to the user? Boolean READ

A query that is not assigned to a project ("project": null) is called a global query. Global queries filter work packages regarless of the project they are assigned to. As such, a different set of filters exists for those queries.

Query Filter Instance

A QueryFilterInstance defines a filtering applied to the list of work packages. As such it contains:

  • the filter type (QueryFilter) used

  • the operator (QueryOperator) used

  • the list of values

The list of values can either consist of a list of links or of a list of strings. If the values are primitive (e.g. Integer, Boolean, Date) they will be displayed as strings and the QueryFilterInstance will have a values property.

{
    "_type": "DueDateQueryFilter",
    "name": "Due date",
    "values": [
      "1"
    ],
    "_links": {
      "filter": {
        "href": "/api/v3/queries/filters/dueDate",
        "title": "Due date"
      },
      "operator": {
        "href": "/api/v3/queries/operators/<t+",
        "title": "in less than"
      }
      "schema": {
        "href": "/api/v3/queries/filter_instance_schemas/dueDate"
      }
    }
  }

If the values are nonprimitive (e.g. User, Project), they will be listed as objects and the QueryFilterInstance will have a values link.

{
    "_type": "AssigneeQueryFilter",
    "name": "Assignee",
    "_links": {
      "filter": {
        "href": "/api/v3/queries/filters/assignee",
        "title": "Assignee"
      },
      "operator": {
        "href": "/api/v3/queries/operators/=",
        "title": "is"
      },
      "schema": {
        "href": "/api/v3/queries/filter_instance_schemas/assignee"
      },
      "values": [
        {
          "href": "/api/v3/users/1",
          "title": "OpenProject Admin"
        }
      ]
    }
  }

Query

View query
GET/api/v3/queries/{id}{?offset,pageSize,filters,sortBy,groupBy,showSums,timelineVisible,timelineLabels,showHierarchies}

Retreive an individual query as identified by the id parameter. Then end point accepts a number of parameters that can be used to override the resources’ persisted parameters.

Example URI

GET /api/v3/queries/1?offset=25&pageSize=25&filters=[{ "assignee": { "operator": "=", "values": ["1", "5"] }" }]&sortBy=[["status", "asc"]]&groupBy=status&showSums=true&timelineVisible=true&timelineLabels={}&showHierarchies=true
URI Parameters
HideShow
id
integer (required) Example: 1

Query id

filters
string (optional) Example: [{ "assignee": { "operator": "=", "values": ["1", "5"] }" }]

JSON specifying filter conditions. The filters provided as parameters are not applied to the query but are instead used to override the query’s persisted filters. All filters also accepted by the work packages endpoint are accepted.

offset
integer (optional) Default: 1 Example: 25

Page number inside the queries’ result collection of work packages.

pageSize
integer (optional) Example: 25

Number of elements to display per page for the queries’ result collection of work packages.

sortBy
string (optional) Example: [["status", "asc"]]

JSON specifying sort criteria. The sort criteria is applied to the querie’s result collection of work packages overriding the query’s persisted sort criteria.

groupBy
string (optional) Example: status

The column to group by. The grouping criteria is applied to the to the querie’s result collection of work packages overriding the query’s persisted group criteria.

showSums
boolean (optional) Default: false Example: true

Indicates whether properties should be summed up if they support it. The showSums parameter is applied to the to the querie’s result collection of work packages overriding the query’s persisted sums property.

timelineVisible
boolean (optional) Default: false Example: true

Indicates whether the timeline should be shown.

timelineLabels
object (optional) Default: {} Example: {}

Overridden labels in the timeline view

showHierarchies
boolean (optional) Default: true Example: true

Indicates whether the hierarchy mode should be enabled.

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Query",
  "id": 9,
  "name": "fdsfdsfdsf",
  "filters": [
    {
      "_type": "StatusQueryFilter",
      "name": "Status",
      "_links": {
        "filter": {
          "href": "/api/v3/queries/filters/status",
          "title": "Status"
        },
        "operator": {
          "href": "/api/v3/queries/operators/o",
          "title": "open"
        },
        "schema": {
          "href": "/api/v3/queries/filter_instance_schemas/status"
        },
        "values": []
      }
    },
    {
      "_type": "DueDateQueryFilter",
      "name": "Due date",
      "values": [
        "1"
      ],
      "_links": {
        "filter": {
          "href": "/api/v3/queries/filters/dueDate",
          "title": "Due date"
        },
        "operator": {
          "href": "/api/v3/queries/operators/<t+",
          "title": "in less than"
        },
        "schema": {
          "href": "/api/v3/queries/filter_instance_schemas/dueDate"
        }
      }
    }
  ],
  "public": false,
  "sums": false,
  "starred": false,
  "_embedded": {
    "results": {
      "_type": "WorkPackageCollection",
      "total": 234,
      "count": 30,
      "pageSize": 2,
      "offset": 1,
      "_embedded": {
        "elements": [
          "<--- shortened for brevity --->"
        ]
      },
      "_links": {
        "self": {
          "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D"
        },
        "jumpTo": {
          "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=%7Boffset%7D&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D",
          "templated": true
        },
        "changeSize": {
          "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=%7Bsize%7D&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D",
          "templated": true
        },
        "createWorkPackage": {
          "href": "/api/v3/work_packages/form",
          "method": "post"
        },
        "createWorkPackageImmediate": {
          "href": "/api/v3/work_packages",
          "method": "post"
        }
      }
    }
  },
  "_links": {
    "self": {
      "href": "/api/v3/queries/9",
      "title": "fdsfdsfdsf"
    },
    "results": {
      "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D"
    },
    "columns": [
      {
        "href": "/api/v3/queries/columns/id",
        "title": "ID"
      },
      {
        "href": "/api/v3/queries/columns/subject",
        "title": "Subject"
      },
      {
        "href": "/api/v3/queries/columns/type",
        "title": "Type"
      },
      {
        "href": "/api/v3/queries/columns/status",
        "title": "Status"
      },
      {
        "href": "/api/v3/queries/columns/priority",
        "title": "Priority"
      },
      {
        "href": "/api/v3/queries/columns/assignee",
        "title": "Assignee"
      },
      {
        "href": "/api/v3/queries/columns/updated_at",
        "title": "Updated on"
      }
    ],
    "groupBy": {
      "href": null,
      "title": null
    },
    "sortBy": [
      {
        "href": "/api/v3/queries/sort_bys/parent-desc",
        "title": "Parent (Descending)"
      }
    ],
    "user": {
      "href": "/api/v3/users/1",
      "title": "OpenProject Admin"
    },
    "project": {
      "href": "/api/v3/projects/3",
      "title": "copy"
    }
  }
}
Response  404
HideShow

Returned if the query does not exist or the client does not have sufficient permissions to see it.

Required condition: query belongs to user or query is public

Required permission: view work package in queries project

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified query does not exist."
}

Edit Query
PATCH/api/v3/queries/{id}

When calling this endpoint the client provides a single object, containing the properties and links that it wants to change, in the body. Note that it is only allowed to provide properties or links supporting the write operation.

Example URI

PATCH /api/v3/queries/1
URI Parameters
HideShow
id
integer (required) Example: 1

Query id

Request
HideShow
Headers
Content-Type: application/json
Body
{
  "name": "New query name"
}
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Query",
  "id": 9,
  "name": "fdsfdsfdsf",
  "filters": [
    {
      "_type": "StatusQueryFilter",
      "name": "Status",
      "_links": {
        "filter": {
          "href": "/api/v3/queries/filters/status",
          "title": "Status"
        },
        "operator": {
          "href": "/api/v3/queries/operators/o",
          "title": "open"
        },
        "schema": {
          "href": "/api/v3/queries/filter_instance_schemas/status"
        },
        "values": []
      }
    },
    {
      "_type": "DueDateQueryFilter",
      "name": "Due date",
      "values": [
        "1"
      ],
      "_links": {
        "filter": {
          "href": "/api/v3/queries/filters/dueDate",
          "title": "Due date"
        },
        "operator": {
          "href": "/api/v3/queries/operators/<t+",
          "title": "in less than"
        },
        "schema": {
          "href": "/api/v3/queries/filter_instance_schemas/dueDate"
        }
      }
    }
  ],
  "public": false,
  "sums": false,
  "starred": false,
  "_embedded": {
    "results": {
      "_type": "WorkPackageCollection",
      "total": 234,
      "count": 30,
      "pageSize": 2,
      "offset": 1,
      "_embedded": {
        "elements": [
          "<--- shortened for brevity --->"
        ]
      },
      "_links": {
        "self": {
          "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D"
        },
        "jumpTo": {
          "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=%7Boffset%7D&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D",
          "templated": true
        },
        "changeSize": {
          "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=%7Bsize%7D&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D",
          "templated": true
        },
        "createWorkPackage": {
          "href": "/api/v3/work_packages/form",
          "method": "post"
        },
        "createWorkPackageImmediate": {
          "href": "/api/v3/work_packages",
          "method": "post"
        }
      }
    }
  },
  "_links": {
    "self": {
      "href": "/api/v3/queries/9",
      "title": "fdsfdsfdsf"
    },
    "results": {
      "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D"
    },
    "columns": [
      {
        "href": "/api/v3/queries/columns/id",
        "title": "ID"
      },
      {
        "href": "/api/v3/queries/columns/subject",
        "title": "Subject"
      },
      {
        "href": "/api/v3/queries/columns/type",
        "title": "Type"
      },
      {
        "href": "/api/v3/queries/columns/status",
        "title": "Status"
      },
      {
        "href": "/api/v3/queries/columns/priority",
        "title": "Priority"
      },
      {
        "href": "/api/v3/queries/columns/assignee",
        "title": "Assignee"
      },
      {
        "href": "/api/v3/queries/columns/updated_at",
        "title": "Updated on"
      }
    ],
    "groupBy": {
      "href": null,
      "title": null
    },
    "sortBy": [
      {
        "href": "/api/v3/queries/sort_bys/parent-desc",
        "title": "Parent (Descending)"
      }
    ],
    "user": {
      "href": "/api/v3/users/1",
      "title": "OpenProject Admin"
    },
    "project": {
      "href": "/api/v3/projects/3",
      "title": "copy"
    }
  }
}
Response  400
HideShow

Occurs when the client did not send a valid JSON object in the request body.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
  "message": "The request body was not a single JSON object."
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: edit work package

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to edit the content of the work package."
}
Response  404
HideShow

Returned if the query does not exist or the client does not have sufficient permissions to see it.

Required permission: view work packages in the query’s project (unless global)

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified query does not exist."
}
Response  422
HideShow

Returned if:

  • the client tries to modify a read-only property (PropertyIsReadOnly)

  • a constraint for a property was violated (PropertyConstraintViolation)

  • the client provides a link to an invalid resource (ResourceTypeMismatch)

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation",
  "message": "The name might not be blank.",
  "_embedded": {
    "details": {
      "attribute": "name"
    }
  }
}

Delete query
DELETE/api/v3/queries/{id}

Delete the query identified by the id parameter

Example URI

DELETE /api/v3/queries/1
URI Parameters
HideShow
id
integer (required) Example: 1

Query id

Response  204
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: for own queries none; for public queries: manage public queries

Note that you will only receive this error, if you are at least allowed to see the corresponding query.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not authorized to access this resource."
}
Response  404
HideShow

Returned if the query does not exist or the client does not have sufficient permissions to see it.

Required condition: query belongs to user or query is public

Required permission: view work package in queries project

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The requested resource could not be found."
}

Default Query

View default query
GET/api/v3/queries/default{?offset,pageSize,filters,sortBy,groupBy,showSums,timelineVisible,timelineZoomLevel,showHierarchies}

Same as viewing an existing, persisted Query in its response, this resource returns an unpersisted query and by that allows to get the default query configuration. The client may also provide additional parameters which will modify the default query.

Example URI

GET /api/v3/queries/default?offset=25&pageSize=25&filters=[{ "assignee": { "operator": "=", "values": ["1", "5"] }" }]&sortBy=[["status", "asc"]]&groupBy=status&showSums=true&timelineVisible=true&timelineZoomLevel=days&showHierarchies=true
URI Parameters
HideShow
filters
string (optional) Example: [{ "assignee": { "operator": "=", "values": ["1", "5"] }" }]

JSON specifying filter conditions. The filters provided as parameters are not applied to the query but are instead used to override the query’s persisted filters. All filters also accepted by the work packages endpoint are accepted.

offset
integer (optional) Default: 1 Example: 25

Page number inside the queries’ result collection of work packages.

pageSize
integer (optional) Example: 25

Number of elements to display per page for the queries’ result collection of work packages.

sortBy
string (optional) Example: [["status", "asc"]]

JSON specifying sort criteria. The sort criteria is applied to the querie’s result collection of work packages overriding the query’s persisted sort criteria.

groupBy
string (optional) Example: status

The column to group by. The grouping criteria is applied to the to the querie’s result collection of work packages overriding the query’s persisted group criteria.

showSums
boolean (optional) Default: false Example: true

Indicates whether properties should be summed up if they support it. The showSums parameter is applied to the to the querie’s result collection of work packages overriding the query’s persisted sums property.

timelineVisible
boolean (optional) Default: false Example: true

Indicates whether the timeline should be shown.

timelineZoomLevel
string (optional) Default: days Example: days

Indicates in what zoom level the timeline should be shown. Valid values are days, weeks, months, quarters, and years.

showHierarchies
boolean (optional) Default: true Example: true

Indicates whether the hierarchy mode should be enabled.

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Query",
  "name": "default",
  "filters": [
    {
      "_type": "StatusQueryFilter",
      "name": "Status",
      "_links": {
        "filter": {
          "href": "/api/v3/queries/filters/status",
          "title": "Status"
        },
        "operator": {
          "href": "/api/v3/queries/operators/o",
          "title": "open"
        },
        "schema": {
          "href": "/api/v3/queries/filter_instance_schemas/status"
        },
        "values": []
      }
    }
  ],
  "public": false,
  "sums": false,
  "timelineVisible": false,
  "timelineZoomLevel": "days",
  "timelineLabels": {},
  "showHierarchies": true,
  "starred": false,
  "_embedded": {
    "results": {
      "_type": "WorkPackageCollection",
      "total": 234,
      "count": 30,
      "pageSize": 2,
      "offset": 1,
      "_embedded": {
        "elements": [
          "<--- shortened for brevity --->"
        ]
      },
      "_links": {
        "self": {
          "href": "/api/v3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D"
        },
        "jumpTo": {
          "href": "/api/v3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=%7Boffset%7D&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D",
          "templated": true
        },
        "changeSize": {
          "href": "/api/v3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=%7Bsize%7D&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D",
          "templated": true
        },
        "createWorkPackage": {
          "href": "/api/v3/work_packages/form",
          "method": "post"
        },
        "createWorkPackageImmediate": {
          "href": "/api/v3/work_packages",
          "method": "post"
        }
      }
    }
  },
  "_links": {
    "self": {
      "href": "/api/v3/queries/default",
      "title": "Default"
    },
    "results": {
      "href": "/api/v3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D"
    },
    "columns": [
      {
        "href": "/api/v3/queries/columns/id",
        "title": "ID"
      },
      {
        "href": "/api/v3/queries/columns/subject",
        "title": "Subject"
      },
      {
        "href": "/api/v3/queries/columns/type",
        "title": "Type"
      },
      {
        "href": "/api/v3/queries/columns/status",
        "title": "Status"
      },
      {
        "href": "/api/v3/queries/columns/priority",
        "title": "Priority"
      },
      {
        "href": "/api/v3/queries/columns/assignee",
        "title": "Assignee"
      },
      {
        "href": "/api/v3/queries/columns/updated_at",
        "title": "Updated on"
      }
    ],
    "groupBy": {
      "href": null,
      "title": null
    },
    "sortBy": [
      {
        "href": "/api/v3/queries/sort_bys/parent-desc",
        "title": "Parent (Descending)"
      }
    ],
    "user": {
      "href": "/api/v3/users/1",
      "title": "OpenProject Admin"
    },
    "project": {
      "href": null
    }
  }
}
Response  403
HideShow

Returned if the client does not have sufficient permissions to see the default query.

Required permission: view work packages in any project

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not authorized to access this resource."
}

Default Query for Project

View default query for project
GET/api/v3/projects/{id}/queries/default{?offset,pageSize,filters,sortBy,groupBy,showSums,timelineVisible,showHierarchies}

Same as viewing an existing, persisted Query in its response, this resource returns an unpersisted query and by that allows to get the default query configuration. The client may also provide additional parameters which will modify the default query. The query will already be scoped for the project.

Example URI

GET /api/v3/projects/1/queries/default?offset=25&pageSize=25&filters=[{ "assignee": { "operator": "=", "values": ["1", "5"] }" }]&sortBy=[["status", "asc"]]&groupBy=status&showSums=true&timelineVisible=true&showHierarchies=true
URI Parameters
HideShow
id
integer (required) Example: 1

Id of the project the default query is requested for

filters
string (optional) Example: [{ "assignee": { "operator": "=", "values": ["1", "5"] }" }]

JSON specifying filter conditions. The filters provided as parameters are not applied to the query but are instead used to override the query’s persisted filters. All filters also accepted by the work packages endpoint are accepted.

offset
integer (optional) Default: 1 Example: 25

Page number inside the queries’ result collection of work packages.

pageSize
integer (optional) Example: 25

Number of elements to display per page for the queries’ result collection of work packages.

sortBy
string (optional) Example: [["status", "asc"]]

JSON specifying sort criteria. The sort criteria is applied to the querie’s result collection of work packages overriding the query’s persisted sort criteria.

groupBy
string (optional) Example: status

The column to group by. The grouping criteria is applied to the to the querie’s result collection of work packages overriding the query’s persisted group criteria.

showSums
boolean (optional) Default: false Example: true

Indicates whether properties should be summed up if they support it. The showSums parameter is applied to the to the querie’s result collection of work packages overriding the query’s persisted sums property.

timelineVisible
boolean (optional) Default: false Example: true

Indicates whether the timeline should be shown.

showHierarchies
boolean (optional) Default: true Example: true

Indicates whether the hierarchy mode should be enabled.

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Query",
  "name": "default",
  "filters": [
    {
      "_type": "StatusQueryFilter",
      "name": "Status",
      "_links": {
        "filter": {
          "href": "/api/v3/queries/filters/status",
          "title": "Status"
        },
        "operator": {
          "href": "/api/v3/queries/operators/o",
          "title": "open"
        },
        "schema": {
          "href": "/api/v3/queries/filter_instance_schemas/status"
        },
        "values": []
      }
    }
  ],
  "public": false,
  "sums": false,
  "timelineVisible": false,
  "timelineZoomLevel": "days",
  "showHierarchies": true,
  "starred": false,
  "_embedded": {
    "results": {
      "_type": "WorkPackageCollection",
      "total": 234,
      "count": 30,
      "pageSize": 2,
      "offset": 1,
      "_embedded": {
        "elements": [
          "<--- shortened for brevity --->"
        ]
      },
      "_links": {
        "self": {
          "href": "/api/v3/projects/42/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D"
        },
        "jumpTo": {
          "href": "/api/v3/projects/42/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=%7Boffset%7D&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D",
          "templated": true
        },
        "changeSize": {
          "href": "/api/v3/projects/42/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=%7Bsize%7D&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D",
          "templated": true
        },
        "createWorkPackage": {
          "href": "/api/v3/work_packages/form",
          "method": "post"
        },
        "createWorkPackageImmediate": {
          "href": "/api/v3/work_packages",
          "method": "post"
        }
      }
    }
  },
  "_links": {
    "self": {
      "href": "/api/v3/projects/42/queries/default",
      "title": "Default"
    },
    "results": {
      "href": "/api/v3/projects/42/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D"
    },
    "columns": [
      {
        "href": "/api/v3/queries/columns/id",
        "title": "ID"
      },
      {
        "href": "/api/v3/queries/columns/subject",
        "title": "Subject"
      },
      {
        "href": "/api/v3/queries/columns/type",
        "title": "Type"
      },
      {
        "href": "/api/v3/queries/columns/status",
        "title": "Status"
      },
      {
        "href": "/api/v3/queries/columns/priority",
        "title": "Priority"
      },
      {
        "href": "/api/v3/queries/columns/assignee",
        "title": "Assignee"
      },
      {
        "href": "/api/v3/queries/columns/updated_at",
        "title": "Updated on"
      }
    ],
    "groupBy": {
      "href": null,
      "title": null
    },
    "sortBy": [
      {
        "href": "/api/v3/queries/sort_bys/parent-desc",
        "title": "Parent (Descending)"
      }
    ],
    "user": {
      "href": "/api/v3/users/1",
      "title": "OpenProject Admin"
    },
    "project": {
      "href": "/api/v3/projects/42",
      "title": "Lorem ipsum project"
    }
  }
}
Response  403
HideShow

Returned if the client does not have sufficient permissions to see the default query.

Required permission: view work packages in the project

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not authorized to access this resource."
}
Response  404
HideShow

Returned if the client does not have sufficient permissions to see the project.

Required permission: any permission in the project

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified resource does not exist."
}

Star Query

Star query
PATCH/api/v3/queries/{id}/star

Example URI

PATCH /api/v3/queries/1/star
URI Parameters
HideShow
id
integer (required) Example: 1

Query id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Query",
  "id": 9,
  "name": "fdsfdsfdsf",
  "filters": [
    {
      "_type": "StatusQueryFilter",
      "name": "Status",
      "_links": {
        "filter": {
          "href": "/api/v3/queries/filters/status",
          "title": "Status"
        },
        "operator": {
          "href": "/api/v3/queries/operators/o",
          "title": "open"
        },
        "schema": {
          "href": "/api/v3/queries/filter_instance_schemas/status"
        },
        "values": []
      }
    },
    {
      "_type": "DueDateQueryFilter",
      "name": "Due date",
      "values": [
        "1"
      ],
      "_links": {
        "filter": {
          "href": "/api/v3/queries/filters/dueDate",
          "title": "Due date"
        },
        "operator": {
          "href": "/api/v3/queries/operators/<t+",
          "title": "in less than"
        },
        "schema": {
          "href": "/api/v3/queries/filter_instance_schemas/dueDate"
        }
      }
    }
  ],
  "public": false,
  "sums": false,
  "starred": true,
  "_embedded": {
    "results": {
      "_type": "WorkPackageCollection",
      "total": 234,
      "count": 30,
      "pageSize": 2,
      "offset": 1,
      "_embedded": {
        "elements": [
          "<--- shortened for brevity --->"
        ]
      },
      "_links": {
        "self": {
          "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D"
        },
        "jumpTo": {
          "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=%7Boffset%7D&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D",
          "templated": true
        },
        "changeSize": {
          "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=%7Bsize%7D&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D",
          "templated": true
        },
        "createWorkPackage": {
          "href": "/api/v3/work_packages/form",
          "method": "post"
        },
        "createWorkPackageImmediate": {
          "href": "/api/v3/work_packages",
          "method": "post"
        }
      }
    }
  },
  "_links": {
    "self": {
      "href": "/api/v3/queries/9",
      "title": "fdsfdsfdsf"
    },
    "results": {
      "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D"
    },
    "columns": [
      {
        "href": "/api/v3/queries/columns/id",
        "title": "ID"
      },
      {
        "href": "/api/v3/queries/columns/subject",
        "title": "Subject"
      },
      {
        "href": "/api/v3/queries/columns/type",
        "title": "Type"
      },
      {
        "href": "/api/v3/queries/columns/status",
        "title": "Status"
      },
      {
        "href": "/api/v3/queries/columns/priority",
        "title": "Priority"
      },
      {
        "href": "/api/v3/queries/columns/assignee",
        "title": "Assignee"
      },
      {
        "href": "/api/v3/queries/columns/updated_at",
        "title": "Updated on"
      }
    ],
    "groupBy": {
      "href": null,
      "title": null
    },
    "sortBy": [
      {
        "href": "/api/v3/queries/sort_bys/parent-desc",
        "title": "Parent (Descending)"
      }
    ],
    "user": {
      "href": "/api/v3/users/1",
      "title": "OpenProject Admin"
    },
    "project": {
      "href": "/api/v3/projects/3",
      "title": "copy"
    }
  }
}
Response  400
HideShow

Occurs when the client did not send an empty request body.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
  "message": "The request body was not empty."
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: for own queries none; for public queries: manage public queries

Note that you will only receive this error, if you are at least allowed to see the corresponding query.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to star this query."
}
Response  404
HideShow

Returned if the query does not exist or the client does not have sufficient permissions to see it.

Required condition: query belongs to user or query is public

Required permission: view work package in queries project

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified query does not exist."
}

Unstar Query

Unstar query
PATCH/api/v3/queries/{id}/unstar

Example URI

PATCH /api/v3/queries/1/unstar
URI Parameters
HideShow
id
integer (required) Example: 1

Query id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Query",
  "id": 9,
  "name": "fdsfdsfdsf",
  "filters": [
    {
      "_type": "StatusQueryFilter",
      "name": "Status",
      "_links": {
        "filter": {
          "href": "/api/v3/queries/filters/status",
          "title": "Status"
        },
        "operator": {
          "href": "/api/v3/queries/operators/o",
          "title": "open"
        },
        "schema": {
          "href": "/api/v3/queries/filter_instance_schemas/status"
        },
        "values": []
      }
    },
    {
      "_type": "DueDateQueryFilter",
      "name": "Due date",
      "values": [
        "1"
      ],
      "_links": {
        "filter": {
          "href": "/api/v3/queries/filters/dueDate",
          "title": "Due date"
        },
        "operator": {
          "href": "/api/v3/queries/operators/<t+",
          "title": "in less than"
        },
        "schema": {
          "href": "/api/v3/queries/filter_instance_schemas/dueDate"
        }
      }
    }
  ],
  "public": false,
  "sums": false,
  "starred": false,
  "_embedded": {
    "results": {
      "_type": "WorkPackageCollection",
      "total": 234,
      "count": 30,
      "pageSize": 2,
      "offset": 1,
      "_embedded": {
        "elements": [
          "<--- shortened for brevity --->"
        ]
      },
      "_links": {
        "self": {
          "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D"
        },
        "jumpTo": {
          "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=%7Boffset%7D&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D",
          "templated": true
        },
        "changeSize": {
          "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=%7Bsize%7D&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D",
          "templated": true
        },
        "createWorkPackage": {
          "href": "/api/v3/work_packages/form",
          "method": "post"
        },
        "createWorkPackageImmediate": {
          "href": "/api/v3/work_packages",
          "method": "post"
        }
      }
    }
  },
  "_links": {
    "self": {
      "href": "/api/v3/queries/9",
      "title": "fdsfdsfdsf"
    },
    "results": {
      "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D"
    },
    "columns": [
      {
        "href": "/api/v3/queries/columns/id",
        "title": "ID"
      },
      {
        "href": "/api/v3/queries/columns/subject",
        "title": "Subject"
      },
      {
        "href": "/api/v3/queries/columns/type",
        "title": "Type"
      },
      {
        "href": "/api/v3/queries/columns/status",
        "title": "Status"
      },
      {
        "href": "/api/v3/queries/columns/priority",
        "title": "Priority"
      },
      {
        "href": "/api/v3/queries/columns/assignee",
        "title": "Assignee"
      },
      {
        "href": "/api/v3/queries/columns/updated_at",
        "title": "Updated on"
      }
    ],
    "groupBy": {
      "href": null,
      "title": null
    },
    "sortBy": [
      {
        "href": "/api/v3/queries/sort_bys/parent-desc",
        "title": "Parent (Descending)"
      }
    ],
    "user": {
      "href": "/api/v3/users/1",
      "title": "OpenProject Admin"
    },
    "project": {
      "href": "/api/v3/projects/3",
      "title": "copy"
    }
  }
}
Response  400
HideShow

Occurs when the client did not send an empty request body.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
  "message": "The request body was not empty."
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: for own queries none; for public queries: manage public queries

Note that you will only receive this error, if you are at least allowed to see the corresponding query.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to unstar this query."
}
Response  404
HideShow

Returned if the query does not exist or the client does not have sufficient permissions to see it.

Required condition: query belongs to user or query is public

Required permission: view work package in queries project

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified query does not exist."
}

Queries

List queries
GET/api/v3/queries{?filters}

Returns a collection of queries. The collection can be filtered via query parameters similar to how work packages are filtered. Please note however, that the filters are applied to the queries and not to the work packages the queries in turn might return.

Example URI

GET /api/v3/queries?filters=[{ "project_id": { "operator": "!*", "values": null }" }]
URI Parameters
HideShow
filters
string (optional) Example: [{ "project_id": { "operator": "!*", "values": null }" }]

JSON specifying filter conditions. Accepts the same format as returned by the queries endpoint. Currently supported filters are:

  • project: filters queries by the project they are assigned to. If the project filter is passed with the !* (not any) operator, global queries are returned.
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/queries"
    }
  },
  "total": 1,
  "count": 1,
  "_type": "Collection",
  "_embedded": {
    "elements": [
      {
        "_type": "Query",
        "id": 9,
        "name": "fdsfdsfdsf",
        "filters": [
          {
            "_type": "StatusQueryFilter",
            "name": "Status",
            "_links": {
              "filter": {
                "href": "/api/v3/queries/filters/status",
                "title": "Status"
              },
              "operator": {
                "href": "/api/v3/queries/operators/o",
                "title": "open"
              },
              "schema": {
                "href": "/api/v3/queries/filter_instance_schemas/status"
              },
              "values": []
            }
          },
          {
            "_type": "DueDateQueryFilter",
            "name": "Due date",
            "values": [
              "1"
            ],
            "_links": {
              "filter": {
                "href": "/api/v3/queries/filters/dueDate",
                "title": "Due date"
              },
              "operator": {
                "href": "/api/v3/queries/operators/<t+",
                "title": "in less than"
              },
              "schema": {
                "href": "/api/v3/queries/filter_instance_schemas/dueDate"
              }
            }
          }
        ],
        "public": false,
        "sums": false,
        "starred": true,
        "_embedded": {
          "results": {
            "_type": "WorkPackageCollection",
            "total": 234,
            "count": 30,
            "pageSize": 2,
            "offset": 1,
            "_embedded": {
              "elements": [
                "<--- shortened for brevity --->"
              ]
            },
            "_links": {
              "self": {
                "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D"
              },
              "jumpTo": {
                "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=%7Boffset%7D&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D",
                "templated": true
              },
              "changeSize": {
                "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=%7Bsize%7D&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D",
                "templated": true
              },
              "createWorkPackage": {
                "href": "/api/v3/work_packages/form",
                "method": "post"
              },
              "createWorkPackageImmediate": {
                "href": "/api/v3/work_packages",
                "method": "post"
              }
            }
          }
        },
        "_links": {
          "self": {
            "href": "/api/v3/queries/9",
            "title": "fdsfdsfdsf"
          },
          "results": {
            "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D"
          },
          "columns": [
            {
              "href": "/api/v3/queries/columns/id",
              "title": "ID"
            },
            {
              "href": "/api/v3/queries/columns/subject",
              "title": "Subject"
            },
            {
              "href": "/api/v3/queries/columns/type",
              "title": "Type"
            },
            {
              "href": "/api/v3/queries/columns/status",
              "title": "Status"
            },
            {
              "href": "/api/v3/queries/columns/priority",
              "title": "Priority"
            },
            {
              "href": "/api/v3/queries/columns/assignee",
              "title": "Assignee"
            },
            {
              "href": "/api/v3/queries/columns/updated_at",
              "title": "Updated on"
            }
          ],
          "groupBy": {
            "href": null,
            "title": null
          },
          "sortBy": [
            {
              "href": "/api/v3/queries/sort_bys/parent-desc",
              "title": "Parent (Descending)"
            }
          ],
          "user": {
            "href": "/api/v3/users/1",
            "title": "OpenProject Admin"
          },
          "project": {
            "href": "/api/v3/projects/3",
            "title": "copy"
          }
        }
      }
    ]
  }
}
Response  403
HideShow

Returned if the client does not have sufficient permissions to see queries.

Required permission: view work packages or manage public queries in any project

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to see the queries."
}

Create query
POST/api/v3/queries

When calling this endpoint the client provides a single object, containing at least the properties and links that are required, in the body. The required fields of a Query can be found in its schema, which is embedded in the respective form. Note that it is only allowed to provide properties or links supporting the write operation.

Example URI

POST /api/v3/queries
Response  201
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Query",
  "id": 9,
  "name": "fdsfdsfdsf",
  "filters": [
    {
      "_type": "StatusQueryFilter",
      "name": "Status",
      "_links": {
        "filter": {
          "href": "/api/v3/queries/filters/status",
          "title": "Status"
        },
        "operator": {
          "href": "/api/v3/queries/operators/o",
          "title": "open"
        },
        "schema": {
          "href": "/api/v3/queries/filter_instance_schemas/status"
        },
        "values": []
      }
    },
    {
      "_type": "DueDateQueryFilter",
      "name": "Due date",
      "values": [
        "1"
      ],
      "_links": {
        "filter": {
          "href": "/api/v3/queries/filters/dueDate",
          "title": "Due date"
        },
        "operator": {
          "href": "/api/v3/queries/operators/<t+",
          "title": "in less than"
        },
        "schema": {
          "href": "/api/v3/queries/filter_instance_schemas/dueDate"
        }
      }
    }
  ],
  "public": false,
  "sums": false,
  "starred": false,
  "_embedded": {
    "results": {
      "_type": "WorkPackageCollection",
      "total": 234,
      "count": 30,
      "pageSize": 2,
      "offset": 1,
      "_embedded": {
        "elements": [
          "<--- shortened for brevity --->"
        ]
      },
      "_links": {
        "self": {
          "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D"
        },
        "jumpTo": {
          "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=%7Boffset%7D&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D",
          "templated": true
        },
        "changeSize": {
          "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=%7Bsize%7D&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D",
          "templated": true
        },
        "createWorkPackage": {
          "href": "/api/v3/work_packages/form",
          "method": "post"
        },
        "createWorkPackageImmediate": {
          "href": "/api/v3/work_packages",
          "method": "post"
        }
      }
    }
  },
  "_links": {
    "self": {
      "href": "/api/v3/queries/9",
      "title": "fdsfdsfdsf"
    },
    "results": {
      "href": "/api/v3/projects/3/work_packages?filters=%5B%7B%22status%22%3A%7B%22operator%22%3A%22o%22%2C%22values%22%3A%5B%5D%7D%7D%2C%7B%22dueDate%22%3A%7B%22operator%22%3A%22%3Ct%2B%22%2C%22values%22%3A%5B%221%22%5D%7D%7D%5D&offset=1&pageSize=2&sortBy=%5B%5B%22parent%22%2C%22desc%22%5D%5D"
    },
    "columns": [
      {
        "href": "/api/v3/queries/columns/id",
        "title": "ID"
      },
      {
        "href": "/api/v3/queries/columns/subject",
        "title": "Subject"
      },
      {
        "href": "/api/v3/queries/columns/type",
        "title": "Type"
      },
      {
        "href": "/api/v3/queries/columns/status",
        "title": "Status"
      },
      {
        "href": "/api/v3/queries/columns/priority",
        "title": "Priority"
      },
      {
        "href": "/api/v3/queries/columns/assignee",
        "title": "Assignee"
      },
      {
        "href": "/api/v3/queries/columns/updated_at",
        "title": "Updated on"
      }
    ],
    "groupBy": {
      "href": null,
      "title": null
    },
    "sortBy": [
      {
        "href": "/api/v3/queries/sort_bys/parent-desc",
        "title": "Parent (Descending)"
      }
    ],
    "user": {
      "href": "/api/v3/users/1",
      "title": "OpenProject Admin"
    },
    "project": {
      "href": "/api/v3/projects/3",
      "title": "copy"
    }
  }
}
Response  400
HideShow

Occurs when the client did not send a valid JSON object in the request body.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
  "message": "The request body was not a single JSON object."
}
Response  422
HideShow

Returned if:

  • the client tries to modify a read-only property (PropertyIsReadOnly)

  • a constraint for a property was violated (PropertyConstraintViolation)

  • the client provides a link to an invalid resource (ResourceTypeMismatch), e.g. a user, project or operator not found

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation",
  "message": "Project not found",
  "_embedded": {
    "details": {
      "attribute": "project"
    }
  }
}

Query Create Form

This endpoint returns a form to allow a guided creation of a new query. The returned form will be pre-filled with default values for every property, if available.

For more details and all possible responses see the general specification of Forms.

Query Create Form
POST/api/v3/queries/form

Example URI

POST /api/v3/queries/form
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/example/form"
    },
    "validate": {
      "href": "/api/v3/example/form",
      "method": "POST"
    },
    "previewMarkup": {
      "href": "/api/v3/render/textile",
      "method": "POST"
    },
    "commit": {
      "href": "/api/v3/example",
      "method": "PATCH"
    }
  },
  "_type": "Form",
  "_embedded": {
    "payload": {
      "_links": {
        "status": {
          "href": "/api/v3/statuses/1"
        }
      },
      "_type": "Example",
      "lockVersion": 5,
      "subject": "An example title"
    },
    "schema": {
      "_type": "Schema",
      "_links": {
        "self": {
          "href": "/api/v3/example/schema"
        }
      },
      "lockVersion": {
        "type": "Integer",
        "writable": false
      },
      "subject": {
        "type": "String",
        "minLength": 1,
        "maxLength": 255
      },
      "status": {
        "_links": {
          "allowedValues": [
            {
              "href": "/api/v3/statuses/1",
              "title": "New"
            },
            {
              "href": "/api/v3/statuses/2",
              "title": "Closed"
            }
          ]
        },
        "type": "Status",
        "_embedded": {
          "allowedValues": [
            {
              "_links": {
                "self": {
                  "href": "/api/v3/statuses/1"
                }
              },
              "_type": "Status",
              "id": 1,
              "name": "New",
              "position": 1,
              "isDefault": true,
              "isClosed": false,
              "defaultDoneRatio": 0,
              "createdAt": "2014-05-21T08:51:20Z",
              "updatedAt": "2014-05-21T09:12:00Z"
            },
            {
              "_links": {
                "self": {
                  "href": "/api/v3/statuses/2"
                }
              },
              "_type": "Status",
              "id": 2,
              "name": "Closed",
              "position": 2,
              "isDefault": false,
              "isClosed": true,
              "defaultDoneRatio": 100,
              "createdAt": "2014-05-21T08:51:20Z",
              "updatedAt": "2014-05-21T09:12:00Z"
            }
          ]
        }
      }
    },
    "validationErrors": {
      "subject": {
        "_type": "Error",
        "errorIdentifier": "urn:openproject-org:api:v3:errors:BadExampleError",
        "message": "For the purpose of this example we need a validation error. The remainder of the response pretends there were no errors."
      }
    }
  }
}

Schema For Global Queries

View schema for global queries
GET/api/v3/queries/schema

Retrieve the schema for global queries, those, that are not assigned to a project.

Example URI

GET /api/v3/queries/schema
Response  200
HideShow
Headers
Content-Type: application/hal+json
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
  },
  "user": {
    "type": "User",
    "name": "User",
    "required": true,
    "hasDefault": true,
    "writable": false
  },
  "project": {
    "type": "Project",
    "name": "Project",
    "required": false,
    "hasDefault": false,
    "writable": true,
    "_links": {}
  },
  "public": {
    "type": "Boolean",
    "name": "Public",
    "required": false,
    "hasDefault": true,
    "writable": true
  },
  "sums": {
    "type": "Boolean",
    "name": "Sums",
    "required": false,
    "hasDefault": true,
    "writable": true
  },
  "timelineVisible": {
    "type": "Boolean",
    "name": "Timeline visible",
    "required": false,
    "hasDefault": true,
    "writable": true
  },
  "timelineZoomLevel": {
    "type": "String",
    "name": "Timeline zoom level",
    "required": false,
    "hasDefault": true,
    "writable": true
  },
  "timelineLabels": {
    "type": "QueryTimelineLabels",
    "name": "Timeline labels",
    "required": false,
    "hasDefault": true,
    "writable": true
  },
  "showHierarchies": {
    "type": "Boolean",
    "name": "Show hierarchies",
    "required": false,
    "hasDefault": true,
    "writable": true
  },
  "starred": {
    "type": "Boolean",
    "name": "Starred",
    "required": false,
    "hasDefault": true,
    "writable": true
  },
  "columns": {
    "type": "[]QueryColumn",
    "name": "Columns",
    "required": false,
    "hasDefault": true,
    "writable": true,
    "_links": {}
  },
  "filters": {
    "type": "[]QueryFilterInstance",
    "name": "Filters",
    "required": false,
    "writable": true,
    "hasDefault": true,
    "_links": {
      "allowedValuesSchemas": {
        "href": "/api/v3/queries/filter_instance_schemas"
      }
    }
  },
  "groupBy": {
    "type": "[]QueryGroupBy",
    "name": "Group results by",
    "required": false,
    "hasDefault": false,
    "writable": true,
    "_links": {}
  },
  "sortBy": {
    "type": "[]QuerySortBy",
    "name": "Sort by",
    "required": false,
    "hasDefault": true,
    "writable": true,
    "_links": {}
  },
  "results": {
    "type": "WorkPackageCollection",
    "name": "Results",
    "required": false,
    "hasDefault": false,
    "writable": false
  },
  "_embedded": {
    "filtersSchemas": {
      "_type": "Collection",
      "total": 20,
      "count": 20,
      "_embedded": {
        "elements": [
          {
            "_type": "QueryFilterInstanceSchema",
            "_dependencies": [
              {
                "_type": "SchemaDependency",
                "on": "operator",
                "dependencies": {
                  "/api/v3/queries/operators/=": {
                    "values": {
                      "type": "[]User",
                      "name": "Values",
                      "required": true,
                      "hasDefault": false,
                      "writable": true,
                      "_links": {}
                    }
                  },
                  "/api/v3/queries/operators/!": {
                    "values": {
                      "type": "[]User",
                      "name": "Values",
                      "required": true,
                      "hasDefault": false,
                      "writable": true,
                      "_links": {}
                    }
                  },
                  "/api/v3/queries/operators/!*": {},
                  "/api/v3/queries/operators/*": {}
                }
              }
            ],
            "name": {
              "type": "String",
              "name": "Name",
              "required": true,
              "hasDefault": true,
              "writable": false
            },
            "filter": {
              "type": "QueryFilter",
              "name": "Filter",
              "required": true,
              "hasDefault": false,
              "writable": true,
              "_links": {}
            },
            "_links": {
              "self": {
                "href": "/api/v3/queries/filter_instance_schemas/assignee"
              },
              "filter": {
                "href": "/api/v3/queries/filters/assignee",
                "title": "Assignee"
              }
            }
          },
          {
            "_type": "QueryFilterInstanceSchema",
            "_dependencies": [
              {
                "_type": "SchemaDependency",
                "on": "operator",
                "dependencies": {
                  "/api/v3/queries/operators/=": {
                    "values": {
                      "type": "[]User",
                      "name": "Values",
                      "required": true,
                      "hasDefault": false,
                      "writable": true,
                      "_links": {}
                    }
                  },
                  "/api/v3/queries/operators/!": {
                    "values": {
                      "type": "[]User",
                      "name": "Values",
                      "required": true,
                      "hasDefault": false,
                      "writable": true,
                      "_links": {}
                    }
                  }
                }
              }
            ],
            "name": {
              "type": "String",
              "name": "Name",
              "required": true,
              "hasDefault": true,
              "writable": false
            },
            "filter": {
              "type": "QueryFilter",
              "name": "Filter",
              "required": true,
              "hasDefault": false,
              "writable": true,
              "_links": {}
            },
            "_links": {
              "self": {
                "href": "/api/v3/queries/filter_instance_schemas/author"
              },
              "filter": {
                "href": "/api/v3/queries/filters/author",
                "title": "Author"
              }
            }
          }
        ]
      },
      "_links": {
        "self": {
          "href": "/api/v3/queries/filter_instance_schemas"
        }
      }
    }
  },
  "_links": {
    "self": {
      "href": "/api/v3/queries/schema"
    }
  }
}
Response  403
HideShow

Required permission: view work package in any project

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not authorized to access this resource."
}

Schema For Project Queries

View schema for project queries
GET/api/v3/projects/queries/schema

Retrieve the schema for project queries.

Example URI

GET /api/v3/projects/queries/schema
Response  200
HideShow
Headers
Content-Type: application/hal+json
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
  },
  "user": {
    "type": "User",
    "name": "User",
    "required": true,
    "hasDefault": true,
    "writable": false
  },
  "project": {
    "type": "Project",
    "name": "Project",
    "required": false,
    "hasDefault": false,
    "writable": true,
    "_links": {}
  },
  "public": {
    "type": "Boolean",
    "name": "Public",
    "required": false,
    "hasDefault": true,
    "writable": true
  },
  "sums": {
    "type": "Boolean",
    "name": "Sums",
    "required": false,
    "hasDefault": true,
    "writable": true
  },
  "timelineVisible": {
    "type": "Boolean",
    "name": "Timeline visible",
    "required": false,
    "hasDefault": true,
    "writable": true
  },
  "timelineZoomLevel": {
    "type": "String",
    "name": "Timeline zoom level",
    "required": false,
    "hasDefault": true,
    "writable": true
  },
  "showHierarchies": {
    "type": "Boolean",
    "name": "Show hierarchies",
    "required": false,
    "hasDefault": true,
    "writable": true
  },
  "starred": {
    "type": "Boolean",
    "name": "Starred",
    "required": false,
    "hasDefault": true,
    "writable": true
  },
  "columns": {
    "type": "[]QueryColumn",
    "name": "Columns",
    "required": false,
    "hasDefault": true,
    "writable": true,
    "_links": {}
  },
  "filters": {
    "type": "[]QueryFilterInstance",
    "name": "Filters",
    "required": false,
    "writable": true,
    "hasDefault": true,
    "_links": {
      "allowedValuesSchemas": {
        "href": "/api/v3/projects/42/queries/filter_instance_schemas"
      }
    }
  },
  "groupBy": {
    "type": "[]QueryGroupBy",
    "name": "Group results by",
    "required": false,
    "hasDefault": false,
    "writable": true,
    "_links": {}
  },
  "sortBy": {
    "type": "[]QuerySortBy",
    "name": "Sort by",
    "required": false,
    "hasDefault": true,
    "writable": true,
    "_links": {}
  },
  "results": {
    "type": "WorkPackageCollection",
    "name": "Results",
    "required": false,
    "hasDefault": false,
    "writable": false
  },
  "_embedded": {
    "filtersSchemas": {
      "_type": "Collection",
      "total": 20,
      "count": 20,
      "_embedded": {
        "elements": [
          {
            "_type": "QueryFilterInstanceSchema",
            "_dependencies": [
              {
                "_type": "SchemaDependency",
                "on": "operator",
                "dependencies": {
                  "/api/v3/queries/operators/=": {
                    "values": {
                      "type": "[]User",
                      "name": "Values",
                      "required": true,
                      "hasDefault": false,
                      "writable": true,
                      "_links": {}
                    }
                  },
                  "/api/v3/queries/operators/!": {
                    "values": {
                      "type": "[]User",
                      "name": "Values",
                      "required": true,
                      "hasDefault": false,
                      "writable": true,
                      "_links": {}
                    }
                  },
                  "/api/v3/queries/operators/!*": {},
                  "/api/v3/queries/operators/*": {}
                }
              }
            ],
            "name": {
              "type": "String",
              "name": "Name",
              "required": true,
              "hasDefault": true,
              "writable": false
            },
            "filter": {
              "type": "QueryFilter",
              "name": "Filter",
              "required": true,
              "hasDefault": false,
              "writable": true,
              "_links": {}
            },
            "_links": {
              "self": {
                "href": "/api/v3/queries/filter_instance_schemas/assignee"
              },
              "filter": {
                "href": "/api/v3/queries/filters/assignee",
                "title": "Assignee"
              }
            }
          },
          {
            "_type": "QueryFilterInstanceSchema",
            "_dependencies": [
              {
                "_type": "SchemaDependency",
                "on": "operator",
                "dependencies": {
                  "/api/v3/queries/operators/=": {
                    "values": {
                      "type": "[]User",
                      "name": "Values",
                      "required": true,
                      "hasDefault": false,
                      "writable": true,
                      "_links": {}
                    }
                  },
                  "/api/v3/queries/operators/!": {
                    "values": {
                      "type": "[]User",
                      "name": "Values",
                      "required": true,
                      "hasDefault": false,
                      "writable": true,
                      "_links": {}
                    }
                  }
                }
              }
            ],
            "name": {
              "type": "String",
              "name": "Name",
              "required": true,
              "hasDefault": true,
              "writable": false
            },
            "filter": {
              "type": "QueryFilter",
              "name": "Filter",
              "required": true,
              "hasDefault": false,
              "writable": true,
              "_links": {}
            },
            "_links": {
              "self": {
                "href": "/api/v3/queries/filter_instance_schemas/author"
              },
              "filter": {
                "href": "/api/v3/queries/filters/author",
                "title": "Author"
              }
            }
          }
        ]
      },
      "_links": {
        "self": {
          "href": "/api/v3/projects/42/queries/filter_instance_schemas"
        }
      }
    }
  },
  "_links": {
    "self": {
      "href": "/api/v3/projects/42/queries/schema"
    }
  }
}
Response  403
HideShow

Required permission: view work package in the project

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not authorized to access this resource."
}

Query Available Projects

Available projects
GET/api/v3/queries/available_projects

Gets a list of projects that are available as projects a query can be assigned to.

Example URI

GET /api/v3/queries/available_projects
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/queries/available_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",
        "description": "Eveniet molestias omnis quis aut qui eum adipisci.",
        "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",
        "description": "",
        "createdAt": "2016-02-29T12:50:20+00:00",
        "updatedAt": "2016-02-29T12:50:20+00:00",
        "type": null
      }]
    }
  }
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: view work packages

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not authorized to access this resource."
}

Query Columns

A QueryColumn can be referenced by a Query to denote the work package properties the client should display for the work packages returned as query results. The columns maps to the WorkPackage by the id property. QueryColumns exist in three types: QueryColumn::Property, QueryColumn::RelationToType and QueryColumn::RelationOfType.

Actions

Link Description Condition

As of now, no actions are defined.

Linked Properties

Property Description Type Constraints Supported operations
self This query column QueryColumn::Property, QueryColumn::RelationToType or QueryColumn::RelationOfType not null READ
type The type relations point to Type not null, exists only on QueryColumn::Relation READ

Local Properties

Property Description Type Constraints Supported operations
id Query column id String not null READ
name Query column name String not null READ

Query Column

View Query Column
GET/api/v3/queries/columns/{id}

Retreive an individual QueryColumn as identified by the id parameter.

Example URI

GET /api/v3/queries/columns/priority
URI Parameters
HideShow
id
string (required) Example: priority

QueryColumn id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "QueryColumn::Property",
  "id": "priority",
  "name": "Priority",
  "_links": {
    "self": {
      "href": "/api/v3/queries/columns/priority",
      "title": "Priority"
    }
  }
}
Response  403
HideShow

Returned if the client does not have sufficient permissions to see it.

Required permission: view work package in any project

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:Unauthenticated",
  "message": "You are not authorized to access this resource."
}
Response  404
HideShow

Returned if the QueryColumn does not exist.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified query does not exist."
}

Query Filters

A QueryFilter can be referenced by a filter instance defined for a Query to denote the filtering applied to the query’s work package results. This resource is not an instance of an applicable filter but rather the type an applicable filter can have.

Actions

Link Description Condition

As of now, no actions are defined.

Linked Properties

Property Description Type Constraints Supported operations
self This query filter QueryFilter not null READ

Local Properties

Property Description Type Constraints Supported operations
id QueryFilter id String not null READ

Query Filter

View Query Filter
GET/api/v3/queries/filters/{id}

Retreive an individual QueryFilter as identified by the id parameter.

Example URI

GET /api/v3/queries/filters/status
URI Parameters
HideShow
id
string (required) Example: status

QueryFilter identifier.

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "QueryFilter",
  "id": "status",
  "_links": {
    "self": {
      "href": "/api/v3/queries/filters/status",
      "title": "Status"
    }
  }
}
Response  403
HideShow

Returned if the client does not have sufficient permissions to see it.

Required permission: view work package in any project

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:Unauthenticated",
  "message": "You are not authorized to access this resource."
}
Response  404
HideShow

Returned if the QueryFilter does not exist.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified query does not exist."
}

Query Operators

A QueryOperator can be referenced by a QueryFilter to denote the operator to be applied to the filter relation.

Actions

Link Description Condition

As of now, no actions are defined.

Linked Properties

Property Description Type Constraints Supported operations
self This query operator QueryOperator not null READ

Local Properties

Property Description Type Constraints Supported operations
id Query oprator id String not null READ
name Query operator name String not null READ

Query Operator

View Query Operator
GET/api/v3/queries/operators/{id}

Retreive an individual QueryOperator as identified by the id parameter.

Example URI

GET /api/v3/queries/operators/!
URI Parameters
HideShow
id
string (required) Example: !

QueryOperator id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "QueryOperator",
  "id": "!",
  "name": "is not",
  "_links": {
    "self": {
      "href": "/api/v3/queries/operators/!",
      "title": "is not"
    }
  }
}
Response  403
HideShow

Returned if the client does not have sufficient permissions to see it.

Required permission: view work package in any project

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:Unauthenticated",
  "message": "You are not authorized to access this resource."
}
Response  404
HideShow

Returned if the QueryOperator does not exist.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified query does not exist."
}

Query Sort Bys

A QuerySortBy can be referenced by a Query to denote the sorting applied to the query’s work package results. It consists of the columns to sort by as well as the direction (ascending/descending)

Actions

Link Description Condition

As of now, no actions are defined.

Linked Properties

Property Description Type Constraints Supported operations
self This query sort by QuerySortBy not null READ
column The QueryColumn to sort on. QueryColumn not null READ
direction The direction the QueryColumn is to be sorted in. This property is identified by a URI (urn:openproject-org:api:v3:queries:directions:asc or urn:openproject-org:api:v3:queries:directions:desc) instead of by a URL. not null READ

Local Properties

Property Description Type Constraints Supported operations
id QuerySortBy id String not null READ
name QuerySortBy name String not null READ

Query Sort By

View Query Sort By
GET/api/v3/queries/sort_bys/{id}

Retreive an individual QuerySortBy as identified by the id parameter.

Example URI

GET /api/v3/queries/sort_bys/status-asc
URI Parameters
HideShow
id
string (required) Example: status-asc

QuerySortBy identifier. The identifier is a combination of the column identifier and the direction.

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "QuerySortBy",
  "id": "status-asc",
  "name": "Status (Ascending)",
  "_links": {
    "self": {
      "href": "/api/v3/queries/sort_bys/status-asc",
      "title": "Status (Ascending)"
    },
    "column": {
      "href": "/api/v3/queries/columns/status",
      "title": "Status"
    },
    "direction": {
      "href": "urn:openproject-org:api:v3:queries:directions:asc",
      "title": "Ascending"
    }
  }
}
Response  403
HideShow

Returned if the client does not have sufficient permissions to see it.

Required permission: view work package in any project

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:Unauthenticated",
  "message": "You are not authorized to access this resource."
}
Response  404
HideShow

Returned if the QuerySortBy does not exist.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified query does not exist."
}

Query Filter Instance Schema

A QueryFilterInstanceSchema is a Schema specifically for describing QueryFilterInstances. Because the behaviour of FilterInstances, with regards to the values property, differs from one another depending on the choosen Filter, the QueryFilterInstanceSchema explicitly lists the dependencies in its _dependencies property. As the property causing the difference is the selected Filter, that property is linked. Apart from that, a QueryFilterInstanceSchema has the same structure a Schema does.

Linked Properties

Link Description Type Constraints Supported operations
self This QueryFilterInstanceSchema (same as for schema) QueryFilterInstanceSchema not null READ
filter The filter for which this schema is specific Filter not null READ

Local Properties

Property Description Type Constraints Supported operations
name Describes the name attribute Field schema not null READ
filter QuerySortBy name Field schema not null READ

Query Filter Instance Schema

View Query Filter Instance Schema
GET/api/v3/queries/filter_instance_schemas/{identifier}

Retreive an individual QueryFilterInstanceSchema as identified by the id parameter.

Example URI

GET /api/v3/queries/filter_instance_schemas/author
URI Parameters
HideShow
identifier
string (required) Example: author

QueryFilterInstanceSchema identifier. The identifier is the filter identifier.

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "QueryFilterInstanceSchema",
  "_dependencies": [
    {
      "_type": "SchemaDependency",
      "on": "operator",
      "dependencies": {
        "/api/v3/queries/operators/=": {
          "values": {
            "type": "[]User",
            "name": "Values",
            "required": true,
            "hasDefault": false,
            "writable": true,
            "_links": {}
          }
        },
        "/api/v3/queries/operators/!": {
          "values": {
            "type": "[]User",
            "name": "Values",
            "required": true,
            "hasDefault": false,
            "writable": true,
            "_links": {}
          }
        }
      }
    }
  ],
  "name": {
    "type": "String",
    "name": "Name",
    "required": true,
    "hasDefault": true,
    "writable": false
  },
  "filter": {
    "type": "QueryFilter",
    "name": "Filter",
    "required": true,
    "hasDefault": false,
    "writable": true,
    "_links": {}
  },
  "_links": {
    "self": {
      "href": "/api/v3/queries/filter_instance_schemas/author"
    },
    "filter": {
      "href": "/api/v3/queries/filters/author",
      "title": "Author"
    }
  }
}
Response  403
HideShow

Returned if the client does not have sufficient permissions to see it.

Required permission: view work package in any project

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:Unauthenticated",
  "message": "You are not authorized to access this resource."
}
Response  404
HideShow

Returned if the QueryFilterInstanceSchema does not exist.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified query does not exist."
}

Query Filter Instance Schemas

List Query Filter Instance Schemas
GET/api/v3/queries/filter_instance_schemas

Returns the list of QueryFilterInstanceSchemas defined for a global query. That is a query not assigned to a project.

Example URI

GET /api/v3/queries/filter_instance_schemas
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Collection",
  "total": 2,
  "count": 2,
  "_embedded": {
    "elements": [
      {
        "_type": "QueryFilterInstanceSchema",
        "_dependencies": [
          {
            "_type": "SchemaDependency",
            "on": "operator",
            "dependencies": {
              "/api/v3/queries/operators/=": {
                "values": {
                  "type": "[]User",
                  "name": "Values",
                  "required": true,
                  "hasDefault": false,
                  "writable": true,
                  "_links": {}
                }
              },
              "/api/v3/queries/operators/!": {
                "values": {
                  "type": "[]User",
                  "name": "Values",
                  "required": true,
                  "hasDefault": false,
                  "writable": true,
                  "_links": {}
                }
              },
              "/api/v3/queries/operators/!*": {},
              "/api/v3/queries/operators/*": {}
            }
          }
        ],
        "name": {
          "type": "String",
          "name": "Name",
          "required": true,
          "hasDefault": true,
          "writable": false
        },
        "filter": {
          "type": "QueryFilter",
          "name": "Filter",
          "required": true,
          "hasDefault": false,
          "writable": true,
          "_links": {}
        },
        "_links": {
          "self": {
            "href": "/api/v3/queries/filter_instance_schemas/assignee"
          },
          "filter": {
            "href": "/api/v3/queries/filters/assignee",
            "title": "Assignee"
          }
        }
      },
      {
        "_type": "QueryFilterInstanceSchema",
        "_dependencies": [
          {
            "_type": "SchemaDependency",
            "on": "operator",
            "dependencies": {
              "/api/v3/queries/operators/=": {
                "values": {
                  "type": "[]User",
                  "name": "Values",
                  "required": true,
                  "hasDefault": false,
                  "writable": true,
                  "_links": {}
                }
              },
              "/api/v3/queries/operators/!": {
                "values": {
                  "type": "[]User",
                  "name": "Values",
                  "required": true,
                  "hasDefault": false,
                  "writable": true,
                  "_links": {}
                }
              }
            }
          }
        ],
        "name": {
          "type": "String",
          "name": "Name",
          "required": true,
          "hasDefault": true,
          "writable": false
        },
        "filter": {
          "type": "QueryFilter",
          "name": "Filter",
          "required": true,
          "hasDefault": false,
          "writable": true,
          "_links": {}
        },
        "_links": {
          "self": {
            "href": "/api/v3/queries/filter_instance_schemas/author"
          },
          "filter": {
            "href": "/api/v3/queries/filters/author",
            "title": "Author"
          }
        }
      }
    ]
  },
  "_links": {
    "self": {
      "href": "/api/v3/queries/filter_instance_schemas"
    }
  }
}
Response  403
HideShow

Returned if the client does not have sufficient permissions to see it.

Required permission: view work package in any project

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:Unauthenticated",
  "message": "You are not authorized to access this resource."
}

Query Filter Instance Schemas For Project

List Query Filter Instance Schemas for Project
GET/api/v3/projects/{id}/queries/filter_instance_schemas

Returns the list of QueryFilterInstanceSchemas defined for a query of the specified project.

Example URI

GET /api/v3/projects/1/queries/filter_instance_schemas
URI Parameters
HideShow
id
integer (required) Example: 1

Id of the project.

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Collection",
  "total": 2,
  "count": 2,
  "_embedded": {
    "elements": [
      {
        "_type": "QueryFilterInstanceSchema",
        "_dependencies": [
          {
            "_type": "SchemaDependency",
            "on": "operator",
            "dependencies": {
              "/api/v3/queries/operators/=": {
                "values": {
                  "type": "[]User",
                  "name": "Values",
                  "required": true,
                  "hasDefault": false,
                  "writable": true,
                  "_links": {}
                }
              },
              "/api/v3/queries/operators/!": {
                "values": {
                  "type": "[]User",
                  "name": "Values",
                  "required": true,
                  "hasDefault": false,
                  "writable": true,
                  "_links": {}
                }
              },
              "/api/v3/queries/operators/!*": {},
              "/api/v3/queries/operators/*": {}
            }
          }
        ],
        "name": {
          "type": "String",
          "name": "Name",
          "required": true,
          "hasDefault": true,
          "writable": false
        },
        "filter": {
          "type": "QueryFilter",
          "name": "Filter",
          "required": true,
          "hasDefault": false,
          "writable": true,
          "_links": {}
        },
        "_links": {
          "self": {
            "href": "/api/v3/queries/filter_instance_schemas/assignee"
          },
          "filter": {
            "href": "/api/v3/queries/filters/assignee",
            "title": "Assignee"
          }
        }
      },
      {
        "_type": "QueryFilterInstanceSchema",
        "_dependencies": [
          {
            "_type": "SchemaDependency",
            "on": "operator",
            "dependencies": {
              "/api/v3/queries/operators/=": {
                "values": {
                  "type": "[]User",
                  "name": "Values",
                  "required": true,
                  "hasDefault": false,
                  "writable": true,
                  "_links": {}
                }
              },
              "/api/v3/queries/operators/!": {
                "values": {
                  "type": "[]User",
                  "name": "Values",
                  "required": true,
                  "hasDefault": false,
                  "writable": true,
                  "_links": {}
                }
              }
            }
          }
        ],
        "name": {
          "type": "String",
          "name": "Name",
          "required": true,
          "hasDefault": true,
          "writable": false
        },
        "filter": {
          "type": "QueryFilter",
          "name": "Filter",
          "required": true,
          "hasDefault": false,
          "writable": true,
          "_links": {}
        },
        "_links": {
          "self": {
            "href": "/api/v3/queries/filter_instance_schemas/author"
          },
          "filter": {
            "href": "/api/v3/queries/filters/author",
            "title": "Author"
          }
        }
      }
    ]
  },
  "_links": {
    "self": {
      "href": "/api/v3/projects/42/queries/filter_instance_schemas"
    }
  }
}
Response  403
HideShow

Returned if the client does not have sufficient permissions to see it.

Required permission: view work package in any project

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:Unauthenticated",
  "message": "You are not authorized to access this resource."
}

Relations

Work packages may be related to each other in different ways.

+--------------+                            +--------------+
|              | 1                        1 |              |
| Work package +-------------+--------------+ Work package |
|              | from        |           to |              |
+--------------+             |              +--------------+
                      +------+-------+
                      |   Relation   |
                      +--------------+
                      | type         |
                      | reverseType  |
                      | description  |
                      | delay        |
                      +--------------+

Actions

Link Description Condition
update Updates the relation between two work packages via a form Permission: manage work package relations
updateImmediately Updates the relation between two work packages Permission: manage work package relations
delete Destroys the relation between the two work packages Permission: manage work package relations

Linked Properties

Link Description Type Constraints Supported operations Condition
self This relation Relation not null READ Permission: view work packages
schema The schema of this relation Schema not null READ
from The emanating work package WorkPackage not null READ Permission: view work packages
to The work package the relation ends in WorkPackage not null READ Permission: view work packages

Local Properties

Property Description Type Constraints Supported operations
id Relation ID Integer x > 0 READ
name The internationalized name of this kind of relation String READ
type Which kind of relation (blocks, precedes, etc.) String in: relates, duplicates, duplicated, blocks, blocked, precedes, follows, includes, partof, requires, required READ / WRITE
reverseType The kind of relation from the other WP’s perspective String in: relates, duplicates, duplicated, blocks, blocked, precedes, follows, includes, partof, requires, required READ
description Short text further describing the relation String READ / WRITE
delay* The delay in days between closing of from and start of to Integer x >= 0 READ / WRITE

* Only applicable for some relation types such as “follows”. You can check using the relation by schema endpoint at /api/v3/relations/schema/{type}.

Relation

View Relation
GET/api/v3/relations/{id}

Example URI

GET /api/v3/relations/1
URI Parameters
HideShow
id
integer (required) Example: 1

Relation id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/relations/1"
    },
    "update": {
      "href": "/api/v3/relations/1/form",
      "method": "POST"
    },
    "updateImmediately": {
      "href": "/api/v3/relations/1",
      "method": "PATCH"
    },
    "delete": {
      "href": "/api/v3/relations/1",
      "method": "DELETE"
    },
    "from": {
      "href": "/api/v3/work_packages/42",
      "title": "Steel Delivery"
    },
    "to": {
      "href": "/api/v3/work_packages/84",
      "title": "Bending the steel"
    }
  },
  "_type": "Relation",
  "id": 1,
  "name": "precedes",
  "type": "precedes",
  "reverseType": "follows",
  "description": "We can't bend the steel before it's been delivered!",
  "delay": 0
}
Response  404
HideShow

Returned if the relation does not exist or the client does not have sufficient permissions to see it.

Required permission: view work packages for the involved work packages

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified relation does not exist."
}

Edit Relation
PATCH/api/v3/relations/{id}

When calling this endpoint the client provides a single object, containing the properties and links that it wants to change, in the body. It is only allowed to provide properties or links supporting the write operation.

Note that changing the type of a relation invariably also changes the respective reverseType as well as the “name” of it. The returned Relation object will reflect that change. For instance if you change a Relation’s type to “follows” then the reverseType will be changed to precedes.

Example URI

PATCH /api/v3/relations/1
URI Parameters
HideShow
id
integer (required) Example: 1

Relation ID

Request  Update Relation
HideShow
Headers
Content-Type: application/json
Body
{
    "type": "blocks",
    "description": "Actually the supplier has to bend the steel before they can deliver it."
    "delay": 3
}
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/relations/1"
    },
    "update": {
      "href": "/api/v3/relations/1/form",
      "method": "POST"
    },
    "updateImmediately": {
      "href": "/api/v3/relations/1",
      "method": "PATCH"
    },
    "delete": {
      "href": "/api/v3/relations/1",
      "method": "DELETE"
    },
    "from": {
      "href": "/api/v3/work_packages/42",
      "title": "Steel Delivery"
    },
    "to": {
      "href": "/api/v3/work_packages/84",
      "title": "Bending the steel"
    }
  },
  "_type": "Relation",
  "id": 1,
  "name": "precedes",
  "type": "precedes",
  "reverseType": "follows",
  "description": "We can't bend the steel before it's been delivered!",
  "delay": 0
}
Response  400
HideShow

Occurs when the client did not send a valid JSON object in the request body.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
  "message": "The request body was not a single JSON object."
}
Response  404
HideShow

Returned if the relation does not exist or the client does not have sufficient permissions to see it.

Required permission: manage work package relations

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified relation does not exist."
}
Response  422
HideShow

Returned if:

  • the client tries to modify a read-only property (PropertyIsReadOnly)

  • a constraint for a property was violated (PropertyConstraintViolation)

  • the client provides a link to an invalid resource (ResourceTypeMismatch) or a work package that does not exist or for which the client does not have sufficient permissions to see it (required permissions: view work packages for the involved work packages).

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation",
  "message": "Delay must be a number greater than or equal to 0",
  "_embedded": {
    "details": {
      "attribute": "delay"
    }
  }
}

Delete Relation
DELETE/api/v3/relations/{id}

Deletes the relation.

Example URI

DELETE /api/v3/relations/1
URI Parameters
HideShow
id
integer (required) Example: 1

Relation ID

Response  204
HideShow

Returned if the relation was deleted successfully. The response body is empty.

Headers
Content-Type: application/hal+json
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: manage work package relations

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to delete this relation."
}
Response  404
HideShow

Returned if the relation does not exist or the client does not have sufficient permissions to see it.

Required permission: manage work package relations

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified relation does not exist."
}

Relation schema

View relation schema
GET/api/v3/relations/schema

Example URI

GET /api/v3/relations/schema
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Schema",
  "_links": {
    "self": {
      "href": "/api/v3/relations/schema"
    }
  },
  "id": {
    "name": "ID",
    "type": "Integer",
    "writable": false
  },
  "type": {
    "name": "Type",
    "type": "String",
    "writable": true
  },
  "reverseType": {
    "name": "Reverse Type",
    "type": "String",
    "writable": false
  },
  "description": {
    "name": "Description",
    "type": "String",
    "writable": true
  },
  "from": {
    "name": "From work package",
    "type": "WorkPackage",
    "writable": false
  },
  "to": {
    "name": "To work package",
    "type": "WorkPackage",
    "writable": false
  },
  "delay": {
    "name": "Delay",
    "type": "Integer",
    "writable": true
  }
}

Relation schema for type

The exact schema for a relation may depend on it’s type. For instance the “follows” relation has an additional “delay” field which is not applicable for the other relations.

View relation schema for type
GET/api/v3/relations/schema/{type}

Example URI

GET /api/v3/relations/schema/follows
URI Parameters
HideShow
type
string (required) Example: follows

Type of the schema

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Schema",
  "_links": {
    "self": {
      "href": "/api/v3/relations/schema"
    }
  },
  "id": {
    "name": "ID",
    "type": "Integer",
    "writable": false
  },
  "type": {
    "name": "Type",
    "type": "String",
    "writable": true
  },
  "reverseType": {
    "name": "Reverse Type",
    "type": "String",
    "writable": false
  },
  "description": {
    "name": "Description",
    "type": "String",
    "writable": true
  },
  "from": {
    "name": "From work package",
    "type": "WorkPackage",
    "writable": false
  },
  "to": {
    "name": "To work package",
    "type": "WorkPackage",
    "writable": false
  },
  "delay": {
    "name": "Delay",
    "type": "Integer",
    "writable": true
  }
}
Response  404
HideShow

Returned if the relation type does not exist or the client does not have sufficient permissions to see it.

Required permission: manage work package relations

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified relation type does not exist."
}

Relations

List Relations
GET/api/v3/relations{?filters,sortBy}

Lists all relations according to the given (optional, logically conjunctive) filters and ordered by ID. The response only includes relations between work packages which the user is allowed to see.

Example URI

GET /api/v3/relations?filters=[{ "from": { "operator": "=", "values": 42 }" }]&sortBy=[["type", "asc"]]
URI Parameters
HideShow
filters
string (optional) Example: [{ "from": { "operator": "=", "values": 42 }" }]

JSON specifying filter conditions. Accepts the same format as returned by the queries endpoint. Valid fields to filter by are:

  • id - ID of relation

  • from - ID of work package from which the filtered relations emanates.

  • to - ID of work package to which this related points.

  • involved - ID of either the from or the to work package.

  • type - The type of relation to filter by, e.g. “follows”.

sortBy
string (optional) Example: [["type", "asc"]]

JSON specifying sort criteria. Accepts the same format as returned by the queries endpoint.

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/relations"
    }
  },
  "total": 3,
  "count": 1,
  "_type": "Collection",
  "_embedded": {
    "elements": [
      {
        "_links": {
          "self": {
            "href": "/api/v3/relations/1"
          },
          "update": {
            "href": "/api/v3/relations/1/form",
            "method": "POST"
          },
          "updateImmediately": {
            "href": "/api/v3/relations/1",
            "method": "PATCH"
          },
          "delete": {
            "href": "/api/v3/relations/1",
            "method": "DELETE"
          },
          "from": {
            "href": "/api/v3/work_packages/42",
            "title": "Steel Delivery"
          },
          "to": {
            "href": "/api/v3/work_packages/84",
            "title": "Bending the steel"
          }
        },
        "_type": "Relation",
        "id": 1,
        "name": "precedes",
        "type": "precedes",
        "reverseType": "follows",
        "description": "We can't bend the steel before it's been delivered!",
        "delay": 0
      }
    ]
  }
}

Relation edit form

This endpoint returns a form to allow a guided creation of a new work package relation. The returned form will be pre-filled with default values for every property, if available.

For more details and all possible responses see the general specification of Forms.

Relation edit form
POST/api/v3/relations/{id}/form

Example URI

POST /api/v3/relations/1/form
URI Parameters
HideShow
id
integer (required) Example: 1

ID of the relation being modified

Request
HideShow
Body
{
  "_type": "Relation",
  "type": "follows",
  "description": "let it rest for 3 days",
  "delay": 3
}
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/relations/form"
    },
    "validate": {
      "href": "/api/v3/relations/form",
      "method": "POST"
    },
    "commit": {
      "href": "/api/v3/relations",
      "method": "PATCH"
    }
  },
  "_type": "Form",
  "_embedded": {
    "payload": {
      "_links": {
        "from": {
          "href": "/api/v3/work_packages/4534"
        },
        "to": {
          "href": "/api/v3/work_packages/3857"
        }
      },
      "_type": "WorkPackage",
      "type": "follows",
      "delay": 3,
      "description": "let it rest for 3 days"
    },
    "schema": {
      "_type": "Schema",
      "_links": {
        "self": {
          "href": "/api/v3/relations/schema"
        }
      },
      "id": {
        "name": "ID",
        "type": "Integer",
        "writable": false
      },
      "type": {
        "name": "Type",
        "type": "String",
        "writable": true,
        "allowedValues": [
          "relates",
          "duplicates",
          "duplicated",
          "blocks",
          "blocked",
          "precedes",
          "follows",
          "includes",
          "partof",
          "requires",
          "required"
        ]
      },
      "reverseType": {
        "name": "Reverse Type",
        "type": "String",
        "writable": false
      },
      "description": {
        "name": "Description",
        "type": "String",
        "writable": true
      },
      "from": {
        "name": "From work package",
        "type": "WorkPackage",
        "writeable": false
      },
      "to": {
        "name": "To work package",
        "type": "WorkPackage",
        "writable": false
      },
      "delay": {
        "name": "Delay",
        "type": "Integer",
        "writable": true
      }
    },
    "validationErrors": {
      "from": {
        "_type": "Error",
        "errorIdentifier": "urn:openproject-org:api:v3:errors:BadExampleError",
        "message": "For the purpose of this example we need a validation error. The remainder of the response pretends there were no errors."
      }
    }
  }
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: manage work package relations

Note that you will only receive this error, if you are at least allowed to see the involved work packages.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to edit the specified relation."
}
Response  404
HideShow

Returned if the relation does not exist or the client does not have sufficient permissions to see it.

Required permission: view (involved) work package(s), manage work package relations

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified relation does not exist."
}

Previewing

Throughout OpenProject user input for many properties can be formatted (e.g. using Textile). Using the appropriate rendering endpoint it is possible to render custom formatted inputs into HTML and thus receive a preview of the rendered text.

The request to a rendering endpoint must always have a MIME-Type of text/plain. The request body is the actual string that shall be rendered as HTML string.

Textile

Preview Textile document
POST/api/v3/render/textile{?context}

Example URI

POST /api/v3/render/textile?context=/api/v3/work_packages/42
URI Parameters
HideShow
context
string (optional) Example: /api/v3/work_packages/42

API-Link to the context in which the rendering occurs, for example a specific work package.

If left out only context-agnostic rendering takes place. Please note that OpenProject features textile-extensions that can only work given a context (e.g. display attached images).

Supported contexts:

  • /api/v3/work_packages/{id} - an existing work package
Request
HideShow
Headers
Content-Type: text/plain
Body
Hello world! "This":http://example.com *is* textile!
Response  200
HideShow
Headers
Content-Type: text/html
Body
<p>Hello world! <a href="http://example.com">This</a> <strong>is</strong> textile!</p>
Response  400
HideShow

Returned if the context passed by the client is not valid (e.g. unknown).

Note that this response will also occur when the requesting user is not allowed to see the context resource (e.g. limited work package visibility).

Headers
Content-Type: application/json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRenderContext",
  "message": "Could not render textile string in the given context."
}
Response  415
HideShow

Returned if the Content-Type indicated in the request is not text/plain.

Headers
Content-Type: application/json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:TypeNotSupported",
  "message": "Expected Content-Type to be 'text/plain' but got 'application/json'."
}

Plain Text

Preview plain document
POST/api/v3/render/plain

Example URI

POST /api/v3/render/plain
Request
HideShow
Headers
Content-Type: text/plain
Body
Hello world! This *is* plain text!
Response  200
HideShow
Headers
Content-Type: text/html
Body
<p>Hello world! This *is* plain text!</p>
Response  415
HideShow

Returned if the Content-Type indicated in the request is not text/plain.

Headers
Content-Type: application/json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:TypeNotSupported",
  "message": "Expected Content-Type to be 'text/plain' but got 'application/json'."
}

Revisions

Revisions are sets of updates to files in the context of repositories linked in OpenProject.

Linked Properties

Link Description Type Constraints Supported operations
self This revision Revision not null READ
project The project to which the revision belongs Project not null READ
author The user that added this revision, if the authorName was mapped to a user in OpenProject User READ
showRevision A URL to the repository view (outside APIv3) showing this revision - not null READ

Local Properties

Property Description Type Constraints Supported operations
id Revision’s id, assigned by OpenProject Integer x > 0 READ
identifier The raw SCM identifier of the revision (e.g. full SHA hash) String not null READ
formattedIdentifier The SCM identifier of the revision, formatted (e.g. shortened unambiguous SHA hash). May be identical to identifier in many cases String not null READ
authorName The name of the author that committed this revision. Note that this name is retrieved from the repository and does not identify a user in OpenProject. String not null READ
message The commit message of the revision Formattable not null READ
createdAt The time this revision was committed to the repository DateTime not null READ

Revision

View revision
GET/api/v3/revisions/{id}

Example URI

GET /api/v3/revisions/1
URI Parameters
HideShow
id
integer (required) Example: 1

Revision id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_type": "Revision",
    "_links": {
        "self": {
            "href": "/api/v3/revisions/1"
        },
        "project" {
            "href": "/api/v3/projects/1"
        },
        "author": {
            "href": "/api/v3/users/1"
        },
        "showRevision": {
            "href": "/projects/identifier/repository/revision/11f4b07"
        }
    },
    "id": 1,
    "identifier": "11f4b07dff4f4ce9548a52b7d002daca7cd63ec6",
    "formattedIdentifier": "11f4b07",
    "authorName": "Some Developer",
    "message": {
        "format": "plain",
        "raw": "This revision provides new features\n\nAn elaborate description",
        "html": "<p>This revision provides new features<br/><br/>An elaborate description</p>"
    },
    "createdAt": "2015-07-21T13:36:59Z"
}
Response  404
HideShow

Returned if the revision does not exist or the client does not have sufficient permissions to see it.

Required permission: view changesets for the project the repository is created in.

Note: A client without sufficient permissions shall not be able to test for the existence of a revision. That’s why a 404 is returned here, even if a 403 might be more appropriate.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified revision does not exist."
}

Roles

When principals (groups or users) are assigned to a project, they are receive roles in that project. Roles regulate access to specific resources by having permissions configured for them.

Currently, this is only a stub.

Linked Properties

Link Description Type Constraints Supported operations
self This role Role not null READ

Local Properties

Property Description Type Constraints Supported operations
id Role id Integer x > 0 READ
name Role name String not null READ

Role

View role
GET/api/v3/roles/{id}

Fetch an individual role.

Example URI

GET /api/v3/roles/1
URI Parameters
HideShow
id
integer (required) Example: 1

role id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Role",
  "id": 3,
  "name": "Manager",
  "_links": {
    "self": {
      "href": "/api/v3/roles/3",
      "title": "Manager"
    }
  }
}

Roles

List roles
GET/api/v3/roles

List all defined roles. This includes built in roles like ‘Anonymous’ and ‘Non member’.

Example URI

GET /api/v3/roles
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Collection",
  "total": 5,
  "count": 5,
  "_embedded": {
    "elements": [
      {
        "_type": "Role",
        "id": 3,
        "name": "Manager",
        "_links": {
          "self": {
            "href": "/api/v3/roles/3",
            "title": "Manager"
          }
        }
      },
      {
        "_type": "Role",
        "id": 2,
        "name": "Anonymous",
        "_links": {
          "self": {
            "href": "/api/v3/roles/2",
            "title": "Anonymous"
          }
        }
      },
      {
        "_type": "Role",
        "id": 5,
        "name": "Reader",
        "_links": {
          "self": {
            "href": "/api/v3/roles/5",
            "title": "Reader"
          }
        }
      },
      {
        "_type": "Role",
        "id": 4,
        "name": "Member",
        "_links": {
          "self": {
            "href": "/api/v3/roles/4",
            "title": "Member"
          }
        }
      },
      {
        "_type": "Role",
        "id": 1,
        "name": "Non member",
        "_links": {
          "self": {
            "href": "/api/v3/roles/1",
            "title": "Non member"
          }
        }
      }
    ]
  },
  "_links": {
    "self": {
      "href": "/api/v3/roles"
    }
  }
}

Root

The root resource contains links to available resources in the API. By following these links a client should be able to discover further resources in the API.

Note: Currently there is no list action for projects available. A client will therefore have to know links to projects and can’t (yet) discover them.

Link Description Type Nullable Supported operations Condition
configuration The configuration of this OpenProject instance Configuration READ
user The user currently logged-in User READ logged in
userPreferences The preferences of the logged-in user UserPreference READ logged in
priorities List of available priorities Collection READ Permission View work packages in any project
statuses List of available work package statuses Collection READ Permission View work packages in any project
types List of available work package types Collection READ Permission View work packages in any project
workPackages List of all work packages Collection READ Permission View work packages in any project
users List of all users Collection READ Permission Administrator

Local Properties

Property Description Type Condition Supported operations
instanceName The name of the OpenProject instance String READ
coreVersion The OpenProject core version number for the instance String READ

Root

View root
GET/api/v3

Example URI

GET /api/v3
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_links" : {
        "configuration" : {
            "href" : "/api/v3/configuration"
        },
        "user": {
            "href": "/api/v3/users/1",
            "title": "John Sheppard"
        };
        "userPreferences" : {
            "href" : "/api/v3/my_preferences"
        },
        "priorities" : {
            "href" : "/api/v3/priorities"
        },
        "relations" : {
            "href" : "/api/v3/relations"
        },
        "statuses" : {
            "href" : "/api/v3/statuses"
        },
        "types" : {
            "href" : "/api/v3/types"
        },
        "workPackages" : {
            "href" : "/api/v3/work_packages"
        },
        "users": {
            "href" : "/api/v3/users"
        }
    },
    "instanceName" : "My own OpenProject",
    "coreVersion" : "6.1.0"
}

Schemas

The schema provides more detailed information about the properties of a resource. The schema is represented by a dictionary containing names of resource properties as keys and objects describing the corresponding property as values. These objects are called field schema and form the core of the schema representation, each of them can contain its own _links and _embedded section.

Linked Properties

Link Description Type Nullable Supported operations
self This schema Schema READ

Local Properties

Property Description Type
_dependencies A list of dependencies between one propertie’s value and another property SchemaDependency

The _dependencies property contains the list of dependencies that exist between the value selected for one of the properites of the described resource and the resoure’s structure. Depending on the value, additional properties might exist or properties might have other values allowed to be assigned. See SchemaDependency for more information.

Field schema

Linked Properties

Property Description Conditions
allowedValues List of resources that are assignable by the current user. Will not exist if allowedValuesSchemas is present.
allowedValuesSchemas Link to schemas furhter describing the property. Will not exist if allowedValues is present.

The allowedValues can either contain a list of canonical links or just a single link to a collection resource. This is an optimization to allow efficient handling of both small resource lists (that can be enumerated inline) and large resource lists (requiring one or more separate requests).

The allowedValuesSchemas will on rare occasions (e.g. for a Query) replace allowedValues. This is done when there is no fixed set of allowed values. Instead, the allowed values will have to follow a schema, or one of a list of schemas, in its own right.

Only one of the links (allowedValues, allowedValuesSchemas) will exist for any given property.

Local Properties

Property Description Type Default
name Human readable name of the property as it could be displayed in a UI String
type The data type of the properties values MetaType
minLength The value of the property must at least contain the specified amount of characters Integer 0
maxLength The value of the property must at most contain the specified amount of characters Integer
regularExpression The value of the property must match the given regular expression (if not null) String null
required If true this property is not nullable Boolean true
writable If false it is not allowed to change the properties value Boolean true

All of the above properties that do not have a default value must be present in the schema. For properties that have a default value, the client can assume the default value, if the property is missing.

Note that regular expressions used in the API follow the rules of Ruby Regular Expressions.

Schema Dependencies

A SchemaDependency describes the dependencies between a value chosen for a resource’s property and the resource’s structure. By that, additional properties or changes in a property are described. A SchemaDependency will never describe a property to disappear, only to appear. As such it always provides additional information. For a property that is depending on another propertie’s value, this can result in not being listed in the resource’s schema itself at all. This will be the case if the existence of the a property as a whole will be dependent. If only one of the aspects (e.g. writable) of the property changes with the selected value, the property itself will already be listed in the schema, but it will lack the dependent aspect.

Given that SchemaDependencies will only add information, and the content type of JSON, a client should be able to join the two objects, the schema and the dependency, into one object easily.

SchemaDependencies are always embedded inside a Schema’s _dependencies attribute. As such, they are not independently existing resources. Consequently, they do not have a self reference.

Linked Properties

Link Description Type Nullable Supported operations

A SchemaDependency does not have any links.

Local Properties

Property Description Type
on The name of the property on which the dependency exists string
dependencies The additions to a schema grouped by the value of the depending property object

The following excerpt examplifies the objects that can be found as a value of the dependencies property:

{
  "_type": "SchemaDependency",
  "on": "someProperty",
  "dependencies": {
    "1": {
      "loremIpsum": {
        "type": "User",
        "name": "Lorem ipsum",
        "required": true,
        "hasDefault": false,
        "writable": true,
        "_links": {
          "allowedValues": {
            "href": "/api/v3/some/path/to/users"
          }
        }
      }
    },
    "2": {
      "loremIpsum": {
        "type": "User",
        "name": "Lorem ipsum",
        "required": true,
        "hasDefault": false,
        "writable": true,
        "_links": {
          "allowedValues": {
            "href": "/api/v3/a/totally/different/path/to/other/users"
          }
        }
      }
    },
    "3": {
      "loremIpsum": {
        "type": "User",
        "name": "Lorem ipsum",
        "required": true,
        "hasDefault": false,
        "writable": false
      }
    },
    "4": {}
  }
}

Given the example above, the client has to add the property loremIpsum to the schema if the depending property is 1, 2 or 3. If it is 4 the property does not exist. The property will not be writable if the value is 3. The values allowed to be set differ between having 1 or 2 selected for the depending property.

Because of the limitation of JSON objects, all keys will be strings, even when the depending value is actually someting different (e.g. Integer, Date). This is also true for resources in which case the url of the resource is used as the key.

Example Schema

view the schema
GET/api/v3/example/schema

This is an example of how a schema might look like. Note that this endpoint does not exist in the actual implementation.

Example URI

GET /api/v3/example/schema
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Schema",
  "_dependencies": [],
  "_links": {
    "self": {
      "href": "/api/v3/example/schema"
    }
  },
  "lockVersion": {
    "name": "Resource Version",
    "type": "Integer",
    "writable": false
  },
  "subject": {
    "name": "Subject",
    "type": "String",
    "minLength": 1,
    "maxLength": 255
  },
  "status": {
    "_links": {
      "allowedValues": [
        {
          "href": "/api/v3/statuses/1",
          "title": "New"
        },
        {
          "href": "/api/v3/statuses/2",
          "title": "Closed"
        }
      ]
    },
    "name": "Status",
    "type": "Status",
    "_embedded": {
      "allowedValues": [
        {
          "_links": {
            "self": {
              "href": "/api/v3/statuses/1"
            }
          },
          "_type": "Status",
          "id": 1,
          "name": "New",
          "position": 1,
          "isDefault": true,
          "isClosed": false,
          "defaultDoneRatio": 0,
          "createdAt": "2014-05-21T08:51:20Z",
          "updatedAt": "2014-05-21T09:12:00Z"
        },
        {
          "_links": {
            "self": {
              "href": "/api/v3/statuses/2"
            }
          },
          "_type": "Status",
          "id": 2,
          "name": "Closed",
          "position": 2,
          "isDefault": false,
          "isClosed": true,
          "defaultDoneRatio": 100,
          "createdAt": "2014-05-21T08:51:20Z",
          "updatedAt": "2014-05-21T09:12:00Z"
        }
      ]
    }
  }
}

Statuses

Linked Properties

Link Description Type Constraints Supported operations
self This status Status not null READ

Local Properties

Property Description Type Constraints Supported operations
id Status id Integer x > 0 READ
name Status name String READ
position Sort index of the status Integer READ
isDefault Boolean READ
isClosed are tickets of this status considered closed? Boolean READ
defaultDoneRatio The percentageDone being applied when changing to this status Integer 0 <= x <= 100 READ

Statuses

List all Statuses
GET/api/v3/statuses

Example URI

GET /api/v3/statuses
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/statuses"
    }
  },
  "total": 6,
  "count": 6,
  "_type": "Collection",
  "_embedded": {
    "elements": [
      {
        "_links": {
          "self": {
            "href": "/api/v3/statuses/1"
          }
        },
        "_type": "Status",
        "id": 1,
        "name": "New",
        "position": 1,
        "isDefault": true,
        "isClosed": false,
        "defaultDoneRatio": 0
      },
      {
        "_links": {
          "self": {
            "href": "/api/v3/statuses/3"
          }
        },
        "_type": "Status",
        "id": 3,
        "name": "Resolved",
        "position": 3,
        "isDefault": false,
        "isClosed": false,
        "defaultDoneRatio": 75
      },
      {
        "_links": {
          "self": {
            "href": "/api/v3/statuses/4"
          }
        },
        "_type": "Status",
        "id": 4,
        "name": "Feedback",
        "position": 4,
        "isDefault": false,
        "isClosed": false,
        "defaultDoneRatio": 25
      },
      {
        "_links": {
          "self": {
            "href": "/api/v3/statuses/5"
          }
        },
        "_type": "Status",
        "id": 5,
        "name": "Closed",
        "position": 5,
        "isDefault": false,
        "isClosed": true,
        "defaultDoneRatio": 100
      },
      {
        "_links": {
          "self": {
            "href": "/api/v3/statuses/6"
          }
        },
        "_type": "Status",
        "id": 6,
        "name": "Rejected",
        "position": 6,
        "isDefault": false,
        "isClosed": true,
        "defaultDoneRatio": 100
      },
      {
        "_links": {
          "self": {
            "href": "/api/v3/statuses/2"
          }
        },
        "_type": "Status",
        "id": 2,
        "name": "In Progress",
        "position": 3,
        "isDefault": false,
        "isClosed": false,
        "defaultDoneRatio": 50
      }
    ]
  }
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: view work package (on any project)

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to see the statuses."
}

Status

View Status
GET/api/v3/statuses/{id}

Example URI

GET /api/v3/statuses/1
URI Parameters
HideShow
id
integer (required) Example: 1

status id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/statuses/1"
    }
  },
  "_type": "Status",
  "id": 1,
  "name": "New",
  "position": 1,
  "isDefault": true,
  "isClosed": false,
  "defaultDoneRatio": 0
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: view work package (on any project)

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to see this status."
}

String Objects

Linked Properties

Link Description Type Constraints Supported operations
self This string object StringObject not null READ

Local Properties

Property Description Type Constraints Supported operations
value The value of the string String READ

String objects are a linkable representation of strings. They merely serve the purpose of making links to strings possible, e.g. to be able to provide allowedValues for a string typed property.

String Object

View String Object
GET/api/v3/string_objects?value={value}

Example URI

GET /api/v3/string_objects?value=Foo
URI Parameters
HideShow
value
string (required) Example: Foo

The string value being resolved

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/string_objects?value=Foo"
    }
  },
  "_type": "StringObject",
  "value": "Foo"
}

Time Entries

Actions

Link Description Condition

None yet

Linked Properties

Link Description Type Constraints Supported operations Condition
self This time entry TimeEntry not null READ
project The project the time entry is bundled in. The project might be different from the work package’s project once the workPackage is moved. Project not null READ / WRITE
workPackage The work package the time entry is created on WorkPackage not null READ
user The user the time entry tracks expenditures for User not null READ
activity The time entry activity the time entry is categorized as TimeEntriesActivity not null READ

Depending on custom fields defined for time entries, additional properties might exist.

Local Properties

Property Description Type Constraints Supported operations Condition
id Time entries’ id Integer x > 0 READ
comment A text provided by the user detailing the time entry String max 255 characters READ
spentOn The date the expenditure is booked for Date READ
hours The time quantifiying the expenditure Time READ
createdAt The time the time entry was created DateTime READ
updatedAT The time the time entry was last updated DateTime READ

Depending on custom fields defined for time entries, additional properties might exist.

Time entry

View time entry
GET/api/v3/time_entries/{id}

Example URI

GET /api/v3/time_entries/1
URI Parameters
HideShow
id
integer (required) Example: 1

time entry id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_type": "TimeEntry",
    "id": 1,
    "comment": "Some text explaing why the time entry was created",
    "spentOn": "2015-03-20",
    "hours": "PT5H",
    "createdAt": "2015-03-20T12:56:56Z",
    "updatedAt": "2015-03-20T12:56:56Z",
    "customField12": 5,
    "_embedded": {
        "project": {
          ...
        },
        "workPackage": {
          ...
        },
        "user": {
          ...
        },
        "activity": {
          ...
        }
    },
    "_links": {
        "self": {
            "href": "/api/v3/time_entries/1"
        },
        "project": {
            "href": "/api/v3/projects/1",
            "title": "Some project"
        },
        "workPackage": {
            "href": "/api/v3/work_packages/1",
            "title": "Some work package"
        },
        "user": {
            "href": "/api/v3/users/2",
            "title": "Some user"
        },
        "activity": {
            "href": "/api/v3/time_entries/activities/18",
            "title": "Some time entry activity"
        },
        "customField4": {
            "href": "/api/v3/users/5",
            "title" "Some other user"
    }
}
Response  404
HideShow

Returned if the time entry does not exist or if the user does not have permission to view them.

Required permission view time entries in the project the time entry is assigned to

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The requested resource could not be found."
}

Time entries

List Time entries
GET/api/v3/time_entries{?offset,pageSize,filters}

Lists time entries. The time entries returned depend on the filters provided and also on the permission of the requesting user.

Example URI

GET /api/v3/time_entries?offset=25&pageSize=25&filters=[{ "work_package": { "operator": "=", "values": ["1", "2"] } }, { "project": { "operator": "=", "values": ["1"] } }]
URI Parameters
HideShow
offset
integer (optional) Default: 1 Example: 25

Page number inside the requested collection.

pageSize
integer (optional) Example: 25

Number of elements to display per page.

filters
string (optional) Example: [{ "work_package": { "operator": "=", "values": ["1", "2"] } }, { "project": { "operator": "=", "values": ["1"] } }]

JSON specifying filter conditions. Accepts the same format as returned by the queries endpoint. Currently supported filters are:

  • work_package: Filter time entries by work package

  • project: Filter time entries by project

  • user: Filter time entries by users

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Collection",
  "total": 39,
  "count": 2,
  "pageSize": 2,
  "offset": 1,
  "_embedded": {
    "elements": [
      {
        "_type": "TimeEntry",
        "id": 5,
        "comment": "Some comment",
        "spentOn": "2015-03-20",
        "hours": "PT5H",
        "createdAt": "2015-03-20T12:56:56Z",
        "updatedAt": "2015-03-20T12:56:56Z",
        "_links": {
          "self": {
            "href": "/api/v3/time_entries/1"
          },
          "project": {
            "href": "/api/v3/projects/1",
            "title": "Some project"
          },
          "workPackage": {
            "href": "/api/v3/work_packages/1",
            "title": "Some work package"
          },
          "user": {
            "href": "/api/v3/users/2",
            "title": "Some user"
          },
          "activity": {
            "href": "/api/v3/time_entries/activities/18",
            "title": "Some time entry activity"
          }
        }
      },
      {
        "_type": "TimeEntry",
        "id": 10,
        "comment": "Another comment",
        "spentOn": "2015-03-21",
        "hours": "PT7H",
        "createdAt": "2015-03-20T12:56:56Z",
        "updatedAt": "2015-03-20T12:56:56Z",
        "_links": {
          "self": {
            "href": "/api/v3/time_entries/2"
          },
          "project": {
            "href": "/api/v3/projects/42",
            "title": "Some other project"
          },
          "workPackage": {
            "href": "/api/v3/work_packages/541",
            "title": "Some other work package"
          },
          "user": {
            "href": "/api/v3/users/6",
            "title": "Some other project"
          },
          "activity": {
            "href": "/api/v3/time_entries/activities/14",
            "title": "some other time entry activity"
          }
        }
      }
    ]
  },
  "_links": {
    "self": {
      "href": "/api/v3/time_entries?offset=1&pageSize=2"
    },
    "jumpTo": {
      "href": "/api/v3/time_entries?offset=%7Boffset%7D&pageSize=2",
      "templated": true
    },
    "changeSize": {
      "href": "/api/v3/time_entries?offset=1&pageSize=%7Bsize%7D",
      "templated": true
    },
    "nextByOffset": {
      "href": "/api/v3/time_entries?offset=2&pageSize=2"
    }
  }
}
Response  400
HideShow

Returned if the client sends invalid request parameters e.g. filters

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidQuery",
  "message": [
    "Filters Invalid filter does not exist."
  ]
}
Response  403
HideShow

Returned if the client is not logged in and login is required.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not authorized to view this resource."
}

Time Entry Activities

Time entries are classified by an activity which is one item of a set of user defined activities (e.g. Design, Specification, Development).

Actions

None

Linked Properties

Link Description Type Constraints Supported operations Condition
self This time entry activity TimeEntriesActivity not null READ
projects List of projects the time entry is active in []Project not null READ / WRITE

Local Properties

Property Description Type Constraints Supported operations Condition
id Time entries’ id Integer x > 0 READ
name The human readable name chosen for this activity String max 30 characters READ
position The rank the activity has in a list of activities Date READ
default Flag to signal whether this activity is the default activity Boolean READ

Time entries activity

View time entries activity
GET/api/v3/time_entries/activity/{id}

Example URI

GET /api/v3/time_entries/activity/1
URI Parameters
HideShow
id
integer (required) Example: 1

time entries activity id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_type": "TimeEntriesActivity",
    "id": 18,
    "name": "a autem",
    "position": 10,
    "default": false,
    "_embedded": {
        "projects": [
          ...
        ]
    },
    "_links": {
        "self": {
            "href": "/api/v3/time_entries/activities/18",
            "title": "a autem"
        },
        "projects": [
            {
                "href": "/api/v3/projects/seeded_project",
                "title": "Seeded Project"
            },
            {
                "href": "/api/v3/projects/working-project",
                "title": "Working Project"
            }
        ]
    }
}
Response  404
HideShow

Returned if the activity does not exist or if the user does not have permission to view them.

Required permission view time entries, log time, edit time entries, edit own time entries or manage project activities in any project

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The requested resource could not be found."
}

Types

Linked Properties

Link Description Type Constraints Supported operations
self This type Type not null READ

Local Properties

Property Description Type Constraints Supported operations
id Type id Integer x > 0 READ
name Type name String READ
color The color used to represent this type Color READ
position Sort index of the type Integer READ
isDefault Boolean READ
isMilestone Do tickets of this type represent a milestone? Boolean READ
createdAt Time of creation DateTime READ
updatedAt Time of the most recent change to the user DateTime READ

Types

List all Types
GET/api/v3/types

Example URI

GET /api/v3/types
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/types"
    }
  },
  "total": 2,
  "count": 2,
  "_type": "Collection",
  "_embedded": {
    "elements": [
      {
        "_links": {
          "self": {
            "href": "/api/v3/types/1"
          }
        },
        "_type": "Type",
        "id": 1,
        "name": "Bug",
        "color": "#ff0000",
        "position": 1,
        "isDefault": true,
        "isMilestone": false,
        "createdAt": "2014-05-21T08:51:20Z",
        "updatedAt": "2014-05-21T08:51:20Z"
      },
      {
        "_links": {
          "self": {
            "href": "/api/v3/types/2"
          }
        },
        "_type": "Type",
        "id": 2,
        "name": "Feature",
        "color": "#888",
        "position": 2,
        "isDefault": false,
        "isMilestone": false,
        "createdAt": "2014-05-21T08:51:20Z",
        "updatedAt": "2014-05-21T08:51:20Z"
      }
    ]
  }
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: view work package or manage types (on any project)

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to see the types."
}

Types by Project

List types available in a project
GET/api/v3/projects/{project_id}/types

This endpoint lists the types that are available in a given project.

Example URI

GET /api/v3/projects/1/types
URI Parameters
HideShow
project_id
integer (required) Example: 1

ID of the project whoose types will be listed

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/projects/11/types"
    }
  },
  "total": 2,
  "count": 2,
  "_type": "Collection",
  "_embedded": {
    "elements": [
      {
        "_links": {
          "self": {
            "href": "/api/v3/types/1"
          }
        },
        "_type": "Type",
        "id": 1,
        "name": "Bug",
        "color": "#ff0000",
        "position": 1,
        "isDefault": true,
        "isMilestone": false,
        "createdAt": "2014-05-21T08:51:20Z",
        "updatedAt": "2014-05-21T08:51:20Z"
      },
      {
        "_links": {
          "self": {
            "href": "/api/v3/types/2"
          }
        },
        "_type": "Type",
        "id": 2,
        "name": "Feature",
        "color": "#888",
        "position": 2,
        "isDefault": false,
        "isMilestone": false,
        "createdAt": "2014-05-21T08:51:20Z",
        "updatedAt": "2014-05-21T08:51:20Z"
      }
    ]
  }
}
Response  404
HideShow

Returned if the project does not exist or the client does not have sufficient permissions to see it.

Required permission: view work packages or manage types (on given 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.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified project does not exist."
}

Type

View Type
GET/api/v3/types/{id}

Example URI

GET /api/v3/types/1
URI Parameters
HideShow
id
integer (required) Example: 1

type id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/types/1"
    }
  },
  "_type": "Type",
  "id": 1,
  "name": "Bug",
  "color": "#ff0000",
  "position": 1,
  "isDefault": true,
  "isMilestone": false,
  "createdAt": "2014-05-21T08:51:20Z",
  "updatedAt": "2014-05-21T08:51:20Z"
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: view work package or manage types (on any project)

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to see this type."
}

UserPreferences

Linked Properties

Link Description Type Constraints Supported operations
self This UserPreferences UserPreferences not null READ
user The user that this preference belongs to User not null READ

Local Properties

Property Description Type Constraints Supported operations
hideMail Hide mail address from other users Boolean READ / WRITE
timeZone Current selected time zone String READ / WRITE
commentSortDescending Sort comments in descending order Boolean READ / WRITE
warnOnLeavingUnsaved Issue warning when leaving a page with unsaved text Boolean READ / WRITE
accessibilityMode Enable accessibility mode Boolean READ / WRITE

UserPreferences

Show my preferences
GET/api/v3/my_preferences

Example URI

GET /api/v3/my_preferences
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_type" : "UserPreferences",
    "_links" : {
        "self" : {
            "href" : "/api/v3/my_preferences",
        },
        "user": {
            "href": "/api/v3/users/1",
            "title": "John Sheppard"
        }
    },
    "hideMail" : false,
    "timeZone" : "Europe/Berlin",
    "commentSortDescending" : true,
    "warnOnLeavingUnsaved" : true,
    "accessibilityMode" : false
}
Response  401
HideShow

Returned if no user is currently authenticated

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:Unauthenticated",
  "message": "You need to be authenticated to access this resource."
}

Update UserPreferences
PATCH/api/v3/my_preferences

When calling this endpoint the client provides a single object, containing the properties that it wants to change, in the body.

Example URI

PATCH /api/v3/my_preferences
Request
HideShow
Headers
Content-Type: application/json
Body
{
  "accessibilityMode": true,
  "timeZone": "Europe/Paris"
}
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_type" : "UserPreferences",
    "_links" : {
        "self" : {
            "href" : "/api/v3/my_preferences",
        },
        "user": {
            "href": "/api/v3/users/1",
            "title": "John Sheppard"
        }
    },
    "hideMail" : false,
    "timeZone" : "Europe/Berlin",
    "commentSortDescending" : true,
    "warnOnLeavingUnsaved" : true,
    "accessibilityMode" : false
}
Response  400
HideShow

Occurs when the client did not send a valid JSON object in the request body.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
  "message": "The request body was not a single JSON object."
}
Response  401
HideShow

Returned if no user is currently authenticated

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:Unauthenticated",
  "message": "You need to be authenticated to access this resource."
}
Response  422
HideShow

Returned if the update contains invalid properties. Reasons are:

  • Specifying an invalid type

  • Using an unknown time zone

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation",
  "message": "Time zone is not set to one of the allowed values."
}

Users

Actions

Link Description Condition
lock Restrict the user from logging in and performing any actions not locked; Permission: Administrator
show Link to the OpenProject user page (HTML)
unlock Allow a locked user to login and act again locked; Permission: Administrator
updateImmediately Updates the user’s attributes. Permission: Administrator
delete Permanently remove a user from the instance Permission: Administrator, self-delete

Linked Properties

Link Description Type Constraints Supported operations Condition
self This user User not null READ
auth_source Link to the user’s auth source (endpoint not yet implemented) AuthSource READ / WRITE Permission: Administrator

Local Properties

Property Description Type Constraints Supported operations Condition
id User’s id Integer x > 0 READ
login User’s login name String unique, 256 max length READ / WRITE Permission: Administrator
firstName User’s first name String 30 max length READ / WRITE Permission: Administrator
lastName User’s last name String 30 max length READ / WRITE Permission: Administrator
name User’s full name, formatting depends on instance settings String READ
email User’s E-Mail address String unique, 60 max length READ / WRITE E-Mail address not hidden, Permission: Administrator
admin Flag indicating whether or not the user is an admin Boolean in: [true, false] READ / WRITE Permission: Administrator
avatar URL to user’s avatar Url READ
status The current activation status of the user (see below) String in: [“active”, “registered”, “locked”, “invited”] READ
language User’s language String ISO 639-1 READ / WRITE Permission: Administrator
password User’s password for the default password authentication String WRITE Permission: Administrator
identity_url User’s identity_url for OmniAuth authentication String READ / WRITE Permission: Administrator
createdAt Time of creation DateTime READ
updatedAt Time of the most recent change to the user DateTime READ

The status of a user can be one of:

  • active - the user can log in with the account right aways

  • invited - the user is invited and is pending registration

If the user’s status is set to active during creation a means of authentication has to be provided which is one of the following:

  • password - The password with which the user logs in.

  • auth_source - Link to an LDAP auth source.

  • identity_url - The identity URL of an OmniAuth authentication provider.

If all of these are missing the creation will fail with an “missing password” error.

The language is limited to those activated in the system.

Due to data privacy, the user’s properties are limited to reveal as little about the user as possible. Thus login, firstName, lastName, language, createdAt and updatedAt are hidden for all users except for admins or the user themselves.

Please note that custom fields are not yet supported by the api although the backend supports them.

User

View user
GET/api/v3/users/{id}

Example URI

GET /api/v3/users/1
URI Parameters
HideShow
id
string (required) Example: 1

User id. Use me to reference current user, if any.

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_type": "User",
    "_links": {
        "self": {
            "href": "/api/v3/users/1",
            "title": "j.sheppard"
        },
        "show": {
            "href": "/users/1",
            "type": 'text/html'
        },
        "lock": {
            "href": "/api/v3/users/1/lock",
            "method": "POST"
        },
        "updateImmediately": {
            "href": "/api/v3/users/1",
            "method": "PATCH"
        },
        "delete": {
            "href": "/api/v3/users/1",
            "method": "DELETE"
        },
    },
    "id": 1,
    "login": "j.sheppard",
    "firstName": "John",
    "lastName": "Sheppard",
    "email": "shep@mail.com",
    "admin": true,
    "avatar": "https://gravatar/avatar",
    "status": "active",
    "language": "en",
    "createdAt": "2014-05-21T08:51:20Z",
    "updatedAt": "2014-05-21T08:51:20Z"
}
Response  404
HideShow

Returned if the user does not exist or if the API user does not have permission to view them.

Required permission The user needs to be locked in if the installation is configured to pervent anonymous access

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified user does not exist or you do not have permission to view them."
}

Update user
PATCH/api/v3/users/{id}

Updates the user’s writable attributes. When calling this endpoint the client provides a single object, containing at least the properties and links that are required, in the body.

Example URI

PATCH /api/v3/users/1
URI Parameters
HideShow
id
integer (required) Example: 1

User id

Request  Update User
HideShow
Headers
Content-Type: application/json
Body
{
  "login": "h.wurst",
  "email": "h.wurst@openproject.com",
  "firstName": "Hans",
  "lastName": "Wurst",
  "admin": true,
  "language": "en"
}
Response  200
HideShow
Body
{
    "_type": "User",
    "_links": {
        "self": {
            "href": "/api/v3/users/1",
            "title": "j.sheppard"
        },
        "show": {
            "href": "/users/1",
            "type": 'text/html'
        },
        "lock": {
            "href": "/api/v3/users/1/lock",
            "method": "POST"
        },
        "updateImmediately": {
            "href": "/api/v3/users/1",
            "method": "PATCH"
        },
        "delete": {
            "href": "/api/v3/users/1",
            "method": "DELETE"
        },
    },
    "id": 1,
    "login": "j.sheppard",
    "firstName": "John",
    "lastName": "Sheppard",
    "email": "shep@mail.com",
    "admin": true,
    "avatar": "https://gravatar/avatar",
    "status": "active",
    "language": "en",
    "createdAt": "2014-05-21T08:51:20Z",
    "updatedAt": "2014-05-21T08:51:20Z"
}
Response  400
HideShow

Occurs when the client did not send a valid JSON object in the request body.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
  "message": "The request body was not a single JSON object."
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: Administrators only

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to update the account of this user."
}
Response  404
HideShow

Returned if the user does not exist or if the API user does not have the necessary permissions to update it.

Required permission: Administrators only (exception: users may update their own accounts)

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified user does not exist or you do not have permission to view them."
}
Response  422
HideShow

Returned if:

  • the client tries to modify a read-only property (PropertyIsReadOnly)

  • a constraint for a property was violated (PropertyConstraintViolation)

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation",
  "message": "The email address is already taken.",
  "_embedded": {
    "details": {
      "attribute": "email"
    }
  }
}

Delete user
DELETE/api/v3/users/{id}

Permanently deletes the specified user account.

Example URI

DELETE /api/v3/users/1
URI Parameters
HideShow
id
integer (required) Example: 1

User id

Response  202
HideShow

Returned if the account was deleted successfully.

Note that the response body is empty as of now. In future versions of the API a body might be returned, indicating the progress of deletion.

Response  403
HideShow

Returned if the client does not have sufficient permissions or if deletion of users was disabled in the instance wide settings.

Required permission: Administrators only (exception: users might be able to delete their own accounts)

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to delete the account of this user."
}
Response  404
HideShow

Returned if the user does not exist.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified user does not exist."
}

User Account Locking

Set Lock
POST/api/v3/users/{id}/lock

Example URI

POST /api/v3/users/1/lock
URI Parameters
HideShow
id
integer (required) Example: 1

User id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_type": "User",
    "_links": {
        "self": {
            "href": "/api/v3/users/1",
            "title": "j.sheppard"
        },
        "show": {
            "href": "/users/1",
            "type": 'text/html'
        },
        "lock": {
            "href": "/api/v3/users/1/lock",
            "method": "POST"
        },
        "updateImmediately": {
            "href": "/api/v3/users/1",
            "method": "PATCH"
        },
        "delete": {
            "href": "/api/v3/users/1",
            "method": "DELETE"
        },
    },
    "id": 1,
    "login": "j.sheppard",
    "firstName": "John",
    "lastName": "Sheppard",
    "email": "shep@mail.com",
    "admin": true,
    "avatar": "https://gravatar/avatar",
    "status": "active",
    "language": "en",
    "createdAt": "2014-05-21T08:51:20Z",
    "updatedAt": "2014-05-21T08:51:20Z"
}
Response  400
HideShow

Returned if the client tries to lock a user account whose current status does not allow this transition.

Required permission: Administrators only

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidUserStatusTransition",
  "message": "The current user account status does not allow this operation."
}
Response  403
HideShow

Returned if the client does not have sufficient permissions for locking a user.

Required permission: Administrators only

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to lock the account of this user."
}
Response  404
HideShow

Returned if the user does not exist.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified user does not exist."
}

Remove Lock
DELETE/api/v3/users/{id}/lock

Example URI

DELETE /api/v3/users/1/lock
URI Parameters
HideShow
id
integer (required) Example: 1

User id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_type": "User",
    "_links": {
        "self": {
            "href": "/api/v3/users/1",
            "title": "j.sheppard"
        },
        "show": {
            "href": "/users/1",
            "type": 'text/html'
        },
        "lock": {
            "href": "/api/v3/users/1/lock",
            "method": "POST"
        },
        "updateImmediately": {
            "href": "/api/v3/users/1",
            "method": "PATCH"
        },
        "delete": {
            "href": "/api/v3/users/1",
            "method": "DELETE"
        },
    },
    "id": 1,
    "login": "j.sheppard",
    "firstName": "John",
    "lastName": "Sheppard",
    "email": "shep@mail.com",
    "admin": true,
    "avatar": "https://gravatar/avatar",
    "status": "active",
    "language": "en",
    "createdAt": "2014-05-21T08:51:20Z",
    "updatedAt": "2014-05-21T08:51:20Z"
}
Response  400
HideShow

Returned if the client tries to unlock a user account whose current status does not allow this transition.

Required permission: Administrators only

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidUserStatusTransition",
  "message": "The current user account status does not allow this operation."
}
Response  403
HideShow

Returned if the client does not have sufficient permissions for unlocking a user.

Required permission: Administrators only

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to unlock the account of this user."
}
Response  404
HideShow

Returned if the user does not exist.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified user does not exist."
}

Users

List Users
GET/api/v3/users{?offset,pageSize,filters,sortBy}

Lists users. Only administrators have permission to do this.

Example URI

GET /api/v3/users?offset=25&pageSize=25&filters=[{ "status": { "operator": "=", "values": ["invited"] } }, { "group": { "operator": "=", "values": ["1"] } }, { "name": { "operator": "=", "values": ["h.wurst@openproject.com"] } }]&sortBy=[["status", "asc"]]
URI Parameters
HideShow
offset
integer (optional) Default: 1 Example: 25

Page number inside the requested collection.

pageSize
integer (optional) Example: 25

Number of elements to display per page.

filters
string (optional) Example: [{ "status": { "operator": "=", "values": ["invited"] } }, { "group": { "operator": "=", "values": ["1"] } }, { "name": { "operator": "=", "values": ["h.wurst@openproject.com"] } }]

JSON specifying filter conditions. Accepts the same format as returned by the queries endpoint. Currently supported filters are:

  • status: Status the user has

  • group: Name of the group in which to-be-listed users are members.

  • name: Filter users in whose first or last names, or email addresses the given string occurs.

  • login: User’s login

sortBy
string (optional) Example: [["status", "asc"]]

JSON specifying sort criteria. Accepts the same format as returned by the queries endpoint.

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_links": {
        "self": { "href": "/api/v3/users" }
    },
    "total": 2,
    "count": 1,
    "_type": "Collection",
    "_embedded": {
        "elements": [
            {
                "_type": "User",
                "_links": {
                    "self": {
                        "href": "/api/v3/users/1",
                        "title": "John Sheppard - j.sheppard"
                    },
                    "showUser": {
                        "href": "/users/1",
                        "type": 'text/html'
                    },
                    "lock": {
                        "href": "/api/v3/users/1/lock",
                        "title": "Set lock on j.sheppard"
                        "method": "POST"
                    },
                    "update": {
                        "href": "/api/v3/users/1",
                        "title": "Update j.sheppard"
                        "method": "PATCH"
                    },
                    "delete": {
                        "href": "/api/v3/users/1",
                        "title": "Delete j.sheppard"
                        "method": "DELETE"
                    }
                },
                "id": 1,
                "login": "j.sheppard",
                "firstName": "John",
                "lastName": "Sheppard",
                "email": "shep@mail.com",
                "admin": true,
                "avatar": "https://gravatar/avatar",
                "status": "active",
                "language": "en",
                "createdAt": "2014-05-21T08:51:20Z",
                "updatedAt": "2014-05-21T08:51:20Z"
            }
        ]
    }
}
Response  400
HideShow

Returned if the client sends an unknown sort column.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidQuery",
  "message": "Unknown sort column."
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: Administrator

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to list users."
}

Create User
POST/api/v3/users

Creates a new user. Only administrators have permission to do so. When calling this endpoint the client provides a single object, containing at least the properties and links that are required, in the body.

Valid values for status:

  1. “active” - In this case a password has to be provided in addition to the other attributes.
  2. “invited” - In this case nothing but the email address is required. The rest is optional. An invitation will be sent to the user.

Example URI

POST /api/v3/users
Request  Create User
HideShow
Headers
Content-Type: application/json
Body
{
  "login": "h.wurst",
  "email": "h.wurst@openproject.com",
  "firstName": "Hans",
  "lastName": "Wurst",
  "admin": false,
  "language": "de",
  "status": "active",
  "password": "hunter5"
}
Request  Invite User
HideShow
Headers
Content-Type: application/json
Body
{
  "email": "h.wurst@openproject.com",
  "firstName": "Hanz",
  "status": "invited"
}
Response  201
HideShow
Body
{
    "_type": "User",
    "_links": {
        "self": {
            "href": "/api/v3/users/1",
            "title": "j.sheppard"
        },
        "show": {
            "href": "/users/1",
            "type": 'text/html'
        },
        "lock": {
            "href": "/api/v3/users/1/lock",
            "method": "POST"
        },
        "updateImmediately": {
            "href": "/api/v3/users/1",
            "method": "PATCH"
        },
        "delete": {
            "href": "/api/v3/users/1",
            "method": "DELETE"
        },
    },
    "id": 1,
    "login": "j.sheppard",
    "firstName": "John",
    "lastName": "Sheppard",
    "email": "shep@mail.com",
    "admin": true,
    "avatar": "https://gravatar/avatar",
    "status": "active",
    "language": "en",
    "createdAt": "2014-05-21T08:51:20Z",
    "updatedAt": "2014-05-21T08:51:20Z"
}
Response  400
HideShow

Occurs when the client did not send a valid JSON object in the request body.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
  "message": "The request body was not a single JSON object."
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: Administrator

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to create new users."
}
Response  422
HideShow

Returned if:

  • a constraint for a property was violated (PropertyConstraintViolation)
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation",
  "message": "The email address is already taken.",
  "_embedded": {
    "details": {
      "attribute": "email"
    }
  }
}

Versions

Work Packages can be assigned to a version. As such, versions serve to group Work Packages into logical units where each group comprises all the work packages that needs to be finished in order for the version to be finished.

Linked Properties

Link Description Type Constraints Supported operations
self This version Version not null READ
definingProject The project to which the version belongs Project only present if the project is visible for the current user READ
availableInProjects Projects where this version can be used Projects not null READ

Local Properties

Property Description Type Constraints Supported operations
id Version id Integer x > 0 READ
name Version name String not null READ
description Formattable not null READ
startDate Date READ
endDate Date READ
status The current status of the version String not null READ
createdAt Time of creation DateTime not null READ
updatedAt Time of the most recent change to the version DateTime not null READ

Version

View version
GET/api/v3/versions/{id}

Example URI

GET /api/v3/versions/1
URI Parameters
HideShow
id
integer (required) Example: 1

version id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/versions/11"
    },
    "definingProject": {
      "href": "/api/v3/projects/11"
    },
    "availableInProjects": {
      "href": "/api/v3/versions/11/projects"
    }
  },
  "_type": "Version",
  "id": 11,
  "name": "v3.0 Alpha",
  "description": {
    "format": "plain",
    "raw": "This version has a description",
    "html": "This version has a description"
  },
  "startDate": "2014-11-20",
  "endDate": null,
  "status": "Open"
}
Response  404
HideShow

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 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.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified version does not exist."
}

Versions

List versions
GET/api/v3/versions{?filters}

Returns a collection of versions. The client can choose to filter the versions similar to how work packages are filtered. In addition to the provided filters, the server will reduce the result set to only contain versions, for which the requesting client has sufficient permissions (view_work_packages).

Example URI

GET /api/v3/versions?filters=[{ "sharing": { "operator": "*", "values": ["system"] }" }]
URI Parameters
HideShow
filters
string (optional) Example: [{ "sharing": { "operator": "*", "values": ["system"] }" }]

JSON specifying filter conditions. Accepts the same format as returned by the queries endpoint. Currently supported filters are:

  • sharing: filters versions by how they are shared within the server (none, descendants, hierarchy, tree, system).
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/versions"
    }
  },
  "total": 3,
  "count": 3,
  "_type": "Collection",
  "_embedded": {
    "elements": [
      {
        "_links": {
          "self": {
            "href": "/api/v3/versions/11"
          },
          "definingProject": {
            "href": "/api/v3/projects/12"
          },
          "availableInProjects": {
            "href": "/api/v3/versions/11/projects"
          }
        },
        "_type": "Version",
        "id": 11,
        "name": "v3.0 Alpha",
        "description": {
          "format": "plain",
          "raw": "This version has a description",
          "html": "This version has a description"
        },
        "startDate": "2014-11-20",
        "endDate": null,
        "status": "Open"
      },
      {
        "_links": {
          "self": {
            "href": "/api/v3/versions/12"
          },
          "definingProject": {
            "href": "/api/v3/projects/11"
          },
          "availableInProjects": {
            "href": "/api/v3/versions/12/projects"
          }
        },
        "_type": "Version",
        "id": 12,
        "name": "v2.0",
        "description": {
          "format": "plain",
          "raw": "",
          "html": ""
        },
        "startDate": null,
        "endDate": null,
        "status": "Closed"
      },
      {
        "_links": {
          "self": {
            "href": "/api/v3/versions/10"
          },
          "definingProject": {
            "href": "/api/v3/projects/13"
          },
          "availableInProjects": {
            "href": "/api/v3/versions/13/projects"
          }
        },
        "_type": "Version",
        "id": 10,
        "name": "v1.0",
        "description": {
          "format": "plain",
          "raw": "",
          "html": ""
        },
        "startDate": null,
        "endDate": null,
        "status": "Open"
      }
    ]
  }
}

Versions by Project

List versions available in a project
GET/api/v3/projects/{project_id}/versions

This endpoint lists the versions that are available in a given project. Note that due to sharing this might be more than the versions defined by that project.

Example URI

GET /api/v3/projects/1/versions
URI Parameters
HideShow
project_id
integer (required) Example: 1

ID of the project whoose versions will be listed

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/projects/11/versions"
    }
  },
  "total": 3,
  "count": 3,
  "_type": "Collection",
  "_embedded": {
    "elements": [
      {
        "_links": {
          "self": {
            "href": "/api/v3/versions/11"
          },
          "definingProject": {
            "href": "/api/v3/projects/11"
          },
          "availableInProjects": {
            "href": "/api/v3/versions/11/projects"
          }
        },
        "_type": "Version",
        "id": 11,
        "name": "v3.0 Alpha",
        "description": {
          "format": "plain",
          "raw": "This version has a description",
          "html": "This version has a description"
        },
        "startDate": "2014-11-20",
        "endDate": null,
        "status": "Open"
      },
      {
        "_links": {
          "self": {
            "href": "/api/v3/versions/12"
          },
          "definingProject": {
            "href": "/api/v3/projects/11"
          },
          "availableInProjects": {
            "href": "/api/v3/versions/12/projects"
          }
        },
        "_type": "Version",
        "id": 12,
        "name": "v2.0",
        "description": {
          "format": "plain",
          "raw": "",
          "html": ""
        },
        "startDate": null,
        "endDate": null,
        "status": "Closed"
      },
      {
        "_links": {
          "self": {
            "href": "/api/v3/versions/10"
          },
          "definingProject": {
            "href": "/api/v3/projects/11"
          },
          "availableInProjects": {
            "href": "/api/v3/versions/10/projects"
          }
        },
        "_type": "Version",
        "id": 10,
        "name": "v1.0",
        "description": {
          "format": "plain",
          "raw": "",
          "html": ""
        },
        "startDate": null,
        "endDate": null,
        "status": "Open"
      }
    ]
  }
}
Response  404
HideShow

Returned if the project does not exist or the client does not have sufficient permissions to see it.

Required permission: view work packages or manage versions (on given 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.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified project does not exist."
}

Work Packages

Actions

Link Description Condition
update Form endpoint that aids in preparing and performing edits on a WP Permission: edit work package
updateImmediately Directly perform edits on a work package Permission: edit work package
watch Add current user to WP watchers logged in; not watching
unwatch Remove current user from WP watchers logged in; watching
addRelation Adds a relation to this work package. Permission: manage wp relations
addWatcher Add any user to WP watchers Permission: add watcher
previewMarkup Post markup (e.g. textile) here to receive an HTML-rendered response
addComment Post comment to WP Permission: add work package notes
removeWatcher Remove any user from WP watchers Permission: delete watcher
addAttachment Attach a file to the WP Permission: edit work package

Linked Properties

Link Description Type Constraints Supported operations Condition
self This work package WorkPackage not null READ
schema The schema of this work package Schema not null READ
ancestors Array of all visible ancestors of the work package, with the root node being the first element Collection not null READ Permission view work packages
attachments The files attached to this work package Collection not null READ
author The person that created the work package User not null READ
assignee The person that is intended to work on the work package User READ / WRITE
availableWatchers All users that can be added to the work package as watchers. User READ Permission add work package watchers
category The category of the work package Category READ / WRITE
children Array of all visible children of the work package Collection not null READ Permission view work packages
parent Parent work package WorkPackage Needs to be visible (to the current user) READ / WRITE
priority The priority of the work package Priority not null READ / WRITE
project The project to which the work package belongs Project not null READ / WRITE
responsible The person that is responsible for the overall outcome User READ / WRITE
relations Relations this work package is involved in Relation READ Permission view work packages
revisions Revisions that are referencing the work package Revision READ Permission view changesets
status The current status of the work package Status not null READ / WRITE
timeEntries All time entries logged on the work package. Please note that this is a link to an HTML resource for now and as such, the link is subject to change. N/A READ Permission view time entries
type The type of the work package Type not null READ / WRITE
version The version associated to the work package Version READ / WRITE
watchers All users that are currently watching this work package Collection READ Permission view work package watchers

Local Properties

Property Description Type Constraints Supported operations Condition
id Work package id Integer x > 0 READ
lockVersion The version of the item as used for optimistic locking Integer READ
subject Work package subject String not null; 1 <= length <= 255 READ / WRITE
type Name of the work package’s type String not null READ
description The work package description Formattable READ / WRITE
startDate Scheduled beginning of a work package Date Cannot be set for parent work packages; must be equal or greater than the earliest possible start date; Exists only on work packages of a non milestone type READ / WRITE
dueDate Scheduled end of a work package Date Cannot be set for parent work packages; must be greater than or equal to the start date; Exists only on work packages of a non milestone type READ / WRITE
date Date on which a milestone is achieved Date Exists only on work packages of a milestone type
estimatedTime Time a work package likely needs to be completed Duration Cannot be set for parent work packages READ / WRITE
spentTime Duration READ Permission view time entries
percentageDone Amount of total completion for a work package Integer 0 <= x <= 100; Cannot be set for parent work packages READ / WRITE
createdAt Time of creation DateTime READ
updatedAt Time of the most recent change to the work package DateTime READ

Note that the properties listed here only cover the built-in properties of the OpenProject Core. Using plug-ins and custom fields a work package might contain various additional properties. A client can consult the schema information to which the work package links. The schema will contain information about all properties of the linking work package, including properties added by plug-ins and custom fields.

Custom fields are identified by a key in the form of customFieldN, where N is an integer. Depending on their type, they can occur as properties or as linked properties. A client has to consult the schema to resolve the human readable name of custom fields.

Properties that cannot be set directly on parent work packages are inferred from their children instead:

  • startDate is the earliest start date from its children

  • dueDate is the latest due date from its children

  • estimatedTime is the sum of estimated times from its children

  • percentageDone is the weighted average of the sum of its children percentages done. The weight is given by the average of its children estimatedHours. However, if the percentage done is given by a work package’s status, then only the status matters and no value is inferred.

Start date can also not be earlier than a due date of any predecessor.

Work Package

View Work Package
GET/api/v3/work_packages/{id}

Example URI

GET /api/v3/work_packages/1
URI Parameters
HideShow
id
integer (required) Example: 1

Work package id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "WorkPackage",
  "_links": {
    "self": {
      "href": "/api/v3/work_packages/1528",
      "title": "Develop API"
    },
    "schema": {
      "href": "/api/v3/work_packages/schemas/1-1-2"
    },
    "update": {
      "href": "/api/v3/work_packages/1528",
      "method": "patch",
      "title": "Update Develop API"
    },
    "delete": {
      "href": "/work_packages/bulk?ids=1528",
      "method": "delete",
      "title": "Delete Develop API"
    },
    "log_time": {
      "href": "/work_packages/1528/time_entries/new",
      "type": "text/html",
      "title": "Log time on Develop API"
    },
    "move": {
      "href": "/work_packages/1528/move/new",
      "type": "text/html",
      "title": "Move Develop API"
    },
    "attachments": {
      "href": "/api/v3/work_packages/1528/attachments"
    },
    "addAttachment": {
      "href": "/api/v3/work_packages/1528/attachments",
      "method": "post"
    },
    "author": {
      "href": "/api/v3/users/1",
      "title": "OpenProject Admin - admin"
    },
    "responsible": {
      "href": "/api/v3/users/23",
      "title": "Laron Leuschke - Alaina5788"
    },
    "relations": {
      "href": "/api/v3/work_packages/1528/relations",
      "title": "Show relations"
    },
    "revisions": {
      "href": "/api/v3/work_packages/1528/revisions"
    },
    "assignee": {
      "href": "/api/v3/users/11",
      "title": "Emmie Okuneva - Adele5450"
    },
    "priority": {
      "href": "/api/v3/priorities/2",
      "title": "Normal"
    },
    "project": {
      "href": "/api/v3/projects/1",
      "title": "A Test Project"
    },
    "status": {
      "href": "/api/v3/statuses/1",
      "title": "New"
    },
    "type": {
      "href": "/api/v3/types/1",
      "title": "New"
    },
    "version": {
      "href": "/api/v3/versions/1",
      "title": "Version 1"
    },
    "availableWatchers": {
      "href": "/api/v3/work_packages/1528/available_watchers"
    },
    "watch": {
      "href": "/api/v3/work_packages/1528/watchers",
      "method": "post",
      "payload": {
        "user": {
          "href": "/api/v3/users/1"
        }
      }
    },
    "addWatcher": {
      "href": "/api/v3/work_packages/1528/watchers",
      "method": "post",
      "payload": {
        "user": {
          "href": "/api/v3/users/{user_id}"
        }
      },
      "templated": true
    },
    "removeWatcher": {
      "href": "/api/v3/work_packages/1528/watchers/{user_id}",
      "method": "delete",
      "templated": true
    },
    "addRelation": {
      "href": "/api/v3/relations",
      "method": "post",
      "title": "Add relation"
    },
    "changeParent": {
      "href": "/api/v3/work_packages/694",
      "method": "patch",
      "title": "Change parent of Bug in OpenProject"
    },
    "addComment": {
      "href": "/api/v3/work_packages/1528/activities",
      "method": "post",
      "title": "Add comment"
    },
    "parent": {
      "href": "/api/v3/work_packages/1298",
      "title": "nisi eligendi officiis eos delectus quis voluptas dolores"
    },
    "category": {
      "href": "/api/v3/categories/1298",
      "title": "eligend isi"
    },
    "children": [
      {
        "href": "/api/v3/work_packages/1529",
        "title": "Write API documentation"
      }
    ],
    "ancestors": [
      {
        "href": "/api/v3/work_packages/1290",
        "title": "Root node of hierarchy"
      },
      {
        "href": "/api/v3/work_packages/1291",
        "title": "Intermediate node of hierarchy"
      },
      {
        "href": "/api/v3/work_packages/1298",
        "title": "nisi eligendi officiis eos delectus quis voluptas dolores"
      }
    ],
    "timeEntries": {
      "href": "/work_packages/1528/time_entries",
      "type": "text/html",
      "title": "Time entries"
    },
    "watchers": {
      "href": "/api/v3/work_packages/1528/watchers"
    },
    "customField3": {
      "href": "api/v3/users/14"
    }
  },
  "id": 1528,
  "subject": "Develop API",
  "description": {
    "format": "textile",
    "raw": "Develop super cool OpenProject API.",
    "html": "<p>Develop super cool OpenProject API.</p>"
  },
  "startDate": null,
  "dueDate": null,
  "estimatedTime": "PT2H",
  "percentageDone": 0,
  "customField1": "Foo",
  "customField2": 42,
  "createdAt": "2014-08-29T12:40:53Z",
  "updatedAt": "2014-08-29T12:44:41Z"
}
Response  404
HideShow

Returned if the work package does not exist or the client does not have sufficient permissions to see it.

Required permission: view work package

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified work package does not exist."
}

Edit Work Package
PATCH/api/v3/work_packages/{id}{?notify}

When calling this endpoint the client provides a single object, containing the properties and links that it wants to change, in the body. Note that it is only allowed to provide properties or links supporting the write operation.

Additionally to the fields the client wants to change, it is mandatory to provide the value of lockVersion which was received by the GET request this change originates from.

The value of lockVersion is used to implement optimistic locking.

Example URI

PATCH /api/v3/work_packages/1?notify=false
URI Parameters
HideShow
id
integer (required) Example: 1

Work package id

notify
boolean (optional) Default: true Example: false

Indicates whether change notifications (e.g. via E-Mail) should be sent. Note that this controls notifications for all users interested in changes to the work package (e.g. watchers, author and assignee), not just the current user.

Request
HideShow
Headers
Content-Type: application/json
Body
{
  "lockVersion": 13,
  "subject": "Lorem",
  "_links": {
    "parent": {
      "href": "/api/v3/work_packages/42"
    }
  }
}
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "WorkPackage",
  "_links": {
    "self": {
      "href": "/api/v3/work_packages/1528",
      "title": "Develop API"
    },
    "schema": {
      "href": "/api/v3/work_packages/schemas/1-1-2"
    },
    "update": {
      "href": "/api/v3/work_packages/1528",
      "method": "patch",
      "title": "Update Develop API"
    },
    "delete": {
      "href": "/work_packages/bulk?ids=1528",
      "method": "delete",
      "title": "Delete Develop API"
    },
    "log_time": {
      "href": "/work_packages/1528/time_entries/new",
      "type": "text/html",
      "title": "Log time on Develop API"
    },
    "move": {
      "href": "/work_packages/1528/move/new",
      "type": "text/html",
      "title": "Move Develop API"
    },
    "attachments": {
      "href": "/api/v3/work_packages/1528/attachments"
    },
    "addAttachment": {
      "href": "/api/v3/work_packages/1528/attachments",
      "method": "post"
    },
    "author": {
      "href": "/api/v3/users/1",
      "title": "OpenProject Admin - admin"
    },
    "responsible": {
      "href": "/api/v3/users/23",
      "title": "Laron Leuschke - Alaina5788"
    },
    "relations": {
      "href": "/api/v3/work_packages/1528/relations",
      "title": "Show relations"
    },
    "revisions": {
      "href": "/api/v3/work_packages/1528/revisions"
    },
    "assignee": {
      "href": "/api/v3/users/11",
      "title": "Emmie Okuneva - Adele5450"
    },
    "priority": {
      "href": "/api/v3/priorities/2",
      "title": "Normal"
    },
    "project": {
      "href": "/api/v3/projects/1",
      "title": "A Test Project"
    },
    "status": {
      "href": "/api/v3/statuses/1",
      "title": "New"
    },
    "type": {
      "href": "/api/v3/types/1",
      "title": "New"
    },
    "version": {
      "href": "/api/v3/versions/1",
      "title": "Version 1"
    },
    "availableWatchers": {
      "href": "/api/v3/work_packages/1528/available_watchers"
    },
    "watch": {
      "href": "/api/v3/work_packages/1528/watchers",
      "method": "post",
      "payload": {
        "user": {
          "href": "/api/v3/users/1"
        }
      }
    },
    "addWatcher": {
      "href": "/api/v3/work_packages/1528/watchers",
      "method": "post",
      "payload": {
        "user": {
          "href": "/api/v3/users/{user_id}"
        }
      },
      "templated": true
    },
    "removeWatcher": {
      "href": "/api/v3/work_packages/1528/watchers/{user_id}",
      "method": "delete",
      "templated": true
    },
    "addRelation": {
      "href": "/api/v3/relations",
      "method": "post",
      "title": "Add relation"
    },
    "changeParent": {
      "href": "/api/v3/work_packages/694",
      "method": "patch",
      "title": "Change parent of Bug in OpenProject"
    },
    "addComment": {
      "href": "/api/v3/work_packages/1528/activities",
      "method": "post",
      "title": "Add comment"
    },
    "parent": {
      "href": "/api/v3/work_packages/1298",
      "title": "nisi eligendi officiis eos delectus quis voluptas dolores"
    },
    "category": {
      "href": "/api/v3/categories/1298",
      "title": "eligend isi"
    },
    "children": [
      {
        "href": "/api/v3/work_packages/1529",
        "title": "Write API documentation"
      }
    ],
    "ancestors": [
      {
        "href": "/api/v3/work_packages/1290",
        "title": "Root node of hierarchy"
      },
      {
        "href": "/api/v3/work_packages/1291",
        "title": "Intermediate node of hierarchy"
      },
      {
        "href": "/api/v3/work_packages/1298",
        "title": "nisi eligendi officiis eos delectus quis voluptas dolores"
      }
    ],
    "timeEntries": {
      "href": "/work_packages/1528/time_entries",
      "type": "text/html",
      "title": "Time entries"
    },
    "watchers": {
      "href": "/api/v3/work_packages/1528/watchers"
    },
    "customField3": {
      "href": "api/v3/users/14"
    }
  },
  "id": 1528,
  "subject": "Develop API",
  "description": {
    "format": "textile",
    "raw": "Develop super cool OpenProject API.",
    "html": "<p>Develop super cool OpenProject API.</p>"
  },
  "startDate": null,
  "dueDate": null,
  "estimatedTime": "PT2H",
  "percentageDone": 0,
  "customField1": "Foo",
  "customField2": 42,
  "createdAt": "2014-08-29T12:40:53Z",
  "updatedAt": "2014-08-29T12:44:41Z"
}
Response  400
HideShow

Occurs when the client did not send a valid JSON object in the request body.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
  "message": "The request body was not a single JSON object."
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: edit work package

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to edit the content of the work package."
}
Response  404
HideShow

Returned if the work package does not exist or the client does not have sufficient permissions to see it.

Required permission: view work package

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified work package does not exist."
}
Response  409
HideShow

Returned if the resource was changed since the client requested it. This is determined using the lockVersion property.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:UpdateConflict",
  "message": "Your changes could not be saved, because the work package was changed since you've seen it the last time."
}
Response  422
HideShow

Returned if:

  • the client tries to modify a read-only property (PropertyIsReadOnly)

  • a constraint for a property was violated (PropertyConstraintViolation)

  • the client provides a link to an invalid resource (ResourceTypeMismatch)

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation",
  "message": "The subject might not be blank.",
  "_embedded": {
    "details": {
      "attribute": "Subject"
    }
  }
}

Delete Work Package
DELETE/api/v3/work_packages/{id}

Deletes the work package, as well as:

  • all associated time entries

  • its hierarchy of child work packages

Example URI

DELETE /api/v3/work_packages/1
URI Parameters
HideShow
id
integer (required) Example: 1

Work package id

Response  204
HideShow

Returned if the work package was deleted successfully.

Note that the response body is empty as of now. In future versions of the API a body might be returned along with an appropriate HTTP status.

Headers
Content-Type: application/hal+json
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: delete work package

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to delete this work package."
}
Response  404
HideShow

Returned if the work package does not exist or the client does not have sufficient permissions to see it.

Required permission: view work package

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified work package does not exist."
}

Work Package Schema

View Work Package Schema
GET/api/v3/work_packages/schemas/{identifier}

Example URI

GET /api/v3/work_packages/schemas/12-13
URI Parameters
HideShow
identifier
string (required) Example: 12-13

Identifier of the schema

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "Schema",
  "_dependencies": [],
  "_links": {
    "self": {
      "href": "/api/v3/example/schema"
    }
  },
  "lockVersion": {
    "name": "Resource Version",
    "type": "Integer",
    "writable": false
  },
  "subject": {
    "name": "Subject",
    "type": "String",
    "minLength": 1,
    "maxLength": 255
  },
  "status": {
    "_links": {
      "allowedValues": [
        {
          "href": "/api/v3/statuses/1",
          "title": "New"
        },
        {
          "href": "/api/v3/statuses/2",
          "title": "Closed"
        }
      ]
    },
    "name": "Status",
    "type": "Status",
    "_embedded": {
      "allowedValues": [
        {
          "_links": {
            "self": {
              "href": "/api/v3/statuses/1"
            }
          },
          "_type": "Status",
          "id": 1,
          "name": "New",
          "position": 1,
          "isDefault": true,
          "isClosed": false,
          "defaultDoneRatio": 0,
          "createdAt": "2014-05-21T08:51:20Z",
          "updatedAt": "2014-05-21T09:12:00Z"
        },
        {
          "_links": {
            "self": {
              "href": "/api/v3/statuses/2"
            }
          },
          "_type": "Status",
          "id": 2,
          "name": "Closed",
          "position": 2,
          "isDefault": false,
          "isClosed": true,
          "defaultDoneRatio": 100,
          "createdAt": "2014-05-21T08:51:20Z",
          "updatedAt": "2014-05-21T09:12:00Z"
        }
      ]
    }
  }
}
Response  404
HideShow

Returned if the schema does not exist or the client does not have sufficient permissions to see it.

Required permission: view work packages (on the project where this schema is used)

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.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified schema does not exist."
}

Work Package Schemas

List Work Package Schemas
GET/api/v3/work_packages/schemas/{?filters}

List work package schemas.

Example URI

GET /api/v3/work_packages/schemas/?filters=[{ "id": { "operator": "=", "values": ["12-1", "14-2"] } }]
URI Parameters
HideShow
filters
string (required) Example: [{ "id": { "operator": "=", "values": ["12-1", "14-2"] } }]

JSON specifying filter conditions. Accepts the same format as returned by the queries endpoint. Currently supported filters are:

  • id: The schema’s id
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_links": {
        "self": { "href": "/api/v3/work_packages/schemas" }
    },
    "total": 5,
    "count": 2,
    "_type": "Collection",
    "_embedded": {
        "elements": [
            {
                "_type": "Schema",
                "_links": {
                    "self": { "href": "/api/v3/work_packages/schemas/13-1" }
                }

                <snip>

            },
            {
                "_type": "Schema",
                "_links": {
                    "self": { "href": "/api/v3/work_packages/schemas/7-6" }
                }

                <snip>

            }
        ]
    }
}
Response  400
HideShow

Returned if the client sends invalid request.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidQuery",
  "message": "Unknown filter."
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: View work packages in any project.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to list schemas."
}

Work Package Edit Form

This endpoint returns a form to allow a guided modification of an existing work package.

For more details and all possible responses see the general specification of Forms.

Work Package Edit Form
POST/api/v3/work_packages/{id}/form

Example URI

POST /api/v3/work_packages/1/form
URI Parameters
HideShow
id
integer (required) Example: 1

ID of the work package being modified

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/example/form"
    },
    "validate": {
      "href": "/api/v3/example/form",
      "method": "POST"
    },
    "previewMarkup": {
      "href": "/api/v3/render/textile",
      "method": "POST"
    },
    "commit": {
      "href": "/api/v3/example",
      "method": "PATCH"
    }
  },
  "_type": "Form",
  "_embedded": {
    "payload": {
      "_links": {
        "status": {
          "href": "/api/v3/statuses/1"
        }
      },
      "_type": "Example",
      "lockVersion": 5,
      "subject": "An example title"
    },
    "schema": {
      "_type": "Schema",
      "_links": {
        "self": {
          "href": "/api/v3/example/schema"
        }
      },
      "lockVersion": {
        "type": "Integer",
        "writable": false
      },
      "subject": {
        "type": "String",
        "minLength": 1,
        "maxLength": 255
      },
      "status": {
        "_links": {
          "allowedValues": [
            {
              "href": "/api/v3/statuses/1",
              "title": "New"
            },
            {
              "href": "/api/v3/statuses/2",
              "title": "Closed"
            }
          ]
        },
        "type": "Status",
        "_embedded": {
          "allowedValues": [
            {
              "_links": {
                "self": {
                  "href": "/api/v3/statuses/1"
                }
              },
              "_type": "Status",
              "id": 1,
              "name": "New",
              "position": 1,
              "isDefault": true,
              "isClosed": false,
              "defaultDoneRatio": 0,
              "createdAt": "2014-05-21T08:51:20Z",
              "updatedAt": "2014-05-21T09:12:00Z"
            },
            {
              "_links": {
                "self": {
                  "href": "/api/v3/statuses/2"
                }
              },
              "_type": "Status",
              "id": 2,
              "name": "Closed",
              "position": 2,
              "isDefault": false,
              "isClosed": true,
              "defaultDoneRatio": 100,
              "createdAt": "2014-05-21T08:51:20Z",
              "updatedAt": "2014-05-21T09:12:00Z"
            }
          ]
        }
      }
    },
    "validationErrors": {
      "subject": {
        "_type": "Error",
        "errorIdentifier": "urn:openproject-org:api:v3:errors:BadExampleError",
        "message": "For the purpose of this example we need a validation error. The remainder of the response pretends there were no errors."
      }
    }
  }
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: edit work package

Note that you will only receive this error, if you are at least allowed to see the corresponding work package.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to edit the specified work package."
}
Response  404
HideShow

Returned if the work package does not exist or the client does not have sufficient permissions to see it.

Required permission: view work package

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified work package does not exist."
}

Work Packages

List Work Packages
GET/api/v3/work_packages{?offset,pageSize,filters,sortBy,groupBy,showSums}

Example URI

GET /api/v3/work_packages?offset=25&pageSize=25&filters=[{ "status_id": { "operator": "o", "values": null }" }]&sortBy=[["status", "asc"]]&groupBy=status&showSums=true
URI Parameters
HideShow
offset
integer (optional) Default: 1 Example: 25

Page number inside the requested collection.

pageSize
integer (optional) Example: 25

Number of elements to display per page.

filters
string (optional) Example: [{ "status_id": { "operator": "o", "values": null }" }]

JSON specifying filter conditions. Accepts the same format as returned by the queries endpoint.

sortBy
string (optional) Example: [["status", "asc"]]

JSON specifying sort criteria. Accepts the same format as returned by the queries endpoint.

groupBy
string (optional) Example: status

The column to group by.

showSums
boolean (optional) Default: false Example: true

Indicates whether properties should be summed up if they support it.

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/work_packages"
    }
  },
  "total": 2,
  "count": 2,
  "_type": "Collection",
  "_embedded": {
    "elements": [
      {
        "_type": "WorkPackage",
        "_links": {
          "self": {
            "href": "/api/v3/work_packages/1"
          }
        },
        "id": 1,
        "subject": "Skipped other properties for brevity"
      },
      {
        "_type": "WorkPackage",
        "_links": {
          "self": {
            "href": "/api/v3/work_packages/2"
          }
        },
        "id": 2,
        "subject": "Skipped other properties for brevity"
      }
    ]
  }
}
Response  400
HideShow

Returned if the client sends a query parameter, that the server knows, but does not understand. E.g. by providing a syntactically incorrect filters parameter.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidQuery",
  "message": "Operator can't be blank."
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: view work packages (globally or in any project)

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to see work packages."
}

Create Work Package
POST/api/v3/work_packages{?notify}

When calling this endpoint the client provides a single object, containing at least the properties and links that are required, in the body. The required fields of a WorkPackage can be found in its schema, which is embedded in the respective form. Note that it is only allowed to provide properties or links supporting the write operation.

A project link must be set when creating work packages through this route.

Example URI

POST /api/v3/work_packages?notify=false
URI Parameters
HideShow
notify
boolean (optional) Default: true Example: false

Indicates whether change notifications (e.g. via E-Mail) should be sent. Note that this controls notifications for all users interested in changes to the work package (e.g. watchers, author and assignee), not just the current user.

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "WorkPackage",
  "_links": {
    "self": {
      "href": "/api/v3/work_packages/1528",
      "title": "Develop API"
    },
    "schema": {
      "href": "/api/v3/work_packages/schemas/1-1-2"
    },
    "update": {
      "href": "/api/v3/work_packages/1528",
      "method": "patch",
      "title": "Update Develop API"
    },
    "delete": {
      "href": "/work_packages/bulk?ids=1528",
      "method": "delete",
      "title": "Delete Develop API"
    },
    "log_time": {
      "href": "/work_packages/1528/time_entries/new",
      "type": "text/html",
      "title": "Log time on Develop API"
    },
    "move": {
      "href": "/work_packages/1528/move/new",
      "type": "text/html",
      "title": "Move Develop API"
    },
    "attachments": {
      "href": "/api/v3/work_packages/1528/attachments"
    },
    "addAttachment": {
      "href": "/api/v3/work_packages/1528/attachments",
      "method": "post"
    },
    "author": {
      "href": "/api/v3/users/1",
      "title": "OpenProject Admin - admin"
    },
    "responsible": {
      "href": "/api/v3/users/23",
      "title": "Laron Leuschke - Alaina5788"
    },
    "relations": {
      "href": "/api/v3/work_packages/1528/relations",
      "title": "Show relations"
    },
    "revisions": {
      "href": "/api/v3/work_packages/1528/revisions"
    },
    "assignee": {
      "href": "/api/v3/users/11",
      "title": "Emmie Okuneva - Adele5450"
    },
    "priority": {
      "href": "/api/v3/priorities/2",
      "title": "Normal"
    },
    "project": {
      "href": "/api/v3/projects/1",
      "title": "A Test Project"
    },
    "status": {
      "href": "/api/v3/statuses/1",
      "title": "New"
    },
    "type": {
      "href": "/api/v3/types/1",
      "title": "New"
    },
    "version": {
      "href": "/api/v3/versions/1",
      "title": "Version 1"
    },
    "availableWatchers": {
      "href": "/api/v3/work_packages/1528/available_watchers"
    },
    "watch": {
      "href": "/api/v3/work_packages/1528/watchers",
      "method": "post",
      "payload": {
        "user": {
          "href": "/api/v3/users/1"
        }
      }
    },
    "addWatcher": {
      "href": "/api/v3/work_packages/1528/watchers",
      "method": "post",
      "payload": {
        "user": {
          "href": "/api/v3/users/{user_id}"
        }
      },
      "templated": true
    },
    "removeWatcher": {
      "href": "/api/v3/work_packages/1528/watchers/{user_id}",
      "method": "delete",
      "templated": true
    },
    "addRelation": {
      "href": "/api/v3/relations",
      "method": "post",
      "title": "Add relation"
    },
    "changeParent": {
      "href": "/api/v3/work_packages/694",
      "method": "patch",
      "title": "Change parent of Bug in OpenProject"
    },
    "addComment": {
      "href": "/api/v3/work_packages/1528/activities",
      "method": "post",
      "title": "Add comment"
    },
    "parent": {
      "href": "/api/v3/work_packages/1298",
      "title": "nisi eligendi officiis eos delectus quis voluptas dolores"
    },
    "category": {
      "href": "/api/v3/categories/1298",
      "title": "eligend isi"
    },
    "children": [
      {
        "href": "/api/v3/work_packages/1529",
        "title": "Write API documentation"
      }
    ],
    "ancestors": [
      {
        "href": "/api/v3/work_packages/1290",
        "title": "Root node of hierarchy"
      },
      {
        "href": "/api/v3/work_packages/1291",
        "title": "Intermediate node of hierarchy"
      },
      {
        "href": "/api/v3/work_packages/1298",
        "title": "nisi eligendi officiis eos delectus quis voluptas dolores"
      }
    ],
    "timeEntries": {
      "href": "/work_packages/1528/time_entries",
      "type": "text/html",
      "title": "Time entries"
    },
    "watchers": {
      "href": "/api/v3/work_packages/1528/watchers"
    },
    "customField3": {
      "href": "api/v3/users/14"
    }
  },
  "id": 1528,
  "subject": "Develop API",
  "description": {
    "format": "textile",
    "raw": "Develop super cool OpenProject API.",
    "html": "<p>Develop super cool OpenProject API.</p>"
  },
  "startDate": null,
  "dueDate": null,
  "estimatedTime": "PT2H",
  "percentageDone": 0,
  "customField1": "Foo",
  "customField2": 42,
  "createdAt": "2014-08-29T12:40:53Z",
  "updatedAt": "2014-08-29T12:44:41Z"
}
Response  400
HideShow

Occurs when the client did not send a valid JSON object in the request body.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
  "message": "The request body was not a single JSON object."
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: add work packages

Note that you will only receive this error, if you are at least allowed to see the corresponding project.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to add work packages to this project."
}
Response  404
HideShow

Returned if the project does not exist or the client does not have sufficient permissions to see it.

Required permissions: 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.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified project does not exist."
}
Response  422
HideShow

Returned if:

  • the client tries to write a read-only property

  • a constraint for a property was violated

  • a property was provided in an unreadable format

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation",
  "message": "The subject might not be blank.",
  "_embedded": {
    "details": {
      "attribute": "Subject"
    }
  }
}

Work Package Create Form

This endpoint returns a form to allow a guided creation of a new work package. The returned form will be pre-filled with default values for every property, if available.

For more details and all possible responses see the general specification of Forms. A project link must be set when creating work packages through this route.

Work Package Create Form
POST/api/v3/work_packages/form

Example URI

POST /api/v3/work_packages/form
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/example/form"
    },
    "validate": {
      "href": "/api/v3/example/form",
      "method": "POST"
    },
    "previewMarkup": {
      "href": "/api/v3/render/textile",
      "method": "POST"
    },
    "commit": {
      "href": "/api/v3/example",
      "method": "PATCH"
    }
  },
  "_type": "Form",
  "_embedded": {
    "payload": {
      "_links": {
        "status": {
          "href": "/api/v3/statuses/1"
        }
      },
      "_type": "Example",
      "lockVersion": 5,
      "subject": "An example title"
    },
    "schema": {
      "_type": "Schema",
      "_links": {
        "self": {
          "href": "/api/v3/example/schema"
        }
      },
      "lockVersion": {
        "type": "Integer",
        "writable": false
      },
      "subject": {
        "type": "String",
        "minLength": 1,
        "maxLength": 255
      },
      "status": {
        "_links": {
          "allowedValues": [
            {
              "href": "/api/v3/statuses/1",
              "title": "New"
            },
            {
              "href": "/api/v3/statuses/2",
              "title": "Closed"
            }
          ]
        },
        "type": "Status",
        "_embedded": {
          "allowedValues": [
            {
              "_links": {
                "self": {
                  "href": "/api/v3/statuses/1"
                }
              },
              "_type": "Status",
              "id": 1,
              "name": "New",
              "position": 1,
              "isDefault": true,
              "isClosed": false,
              "defaultDoneRatio": 0,
              "createdAt": "2014-05-21T08:51:20Z",
              "updatedAt": "2014-05-21T09:12:00Z"
            },
            {
              "_links": {
                "self": {
                  "href": "/api/v3/statuses/2"
                }
              },
              "_type": "Status",
              "id": 2,
              "name": "Closed",
              "position": 2,
              "isDefault": false,
              "isClosed": true,
              "defaultDoneRatio": 100,
              "createdAt": "2014-05-21T08:51:20Z",
              "updatedAt": "2014-05-21T09:12:00Z"
            }
          ]
        }
      }
    },
    "validationErrors": {
      "subject": {
        "_type": "Error",
        "errorIdentifier": "urn:openproject-org:api:v3:errors:BadExampleError",
        "message": "For the purpose of this example we need a validation error. The remainder of the response pretends there were no errors."
      }
    }
  }
}

Work Packages by Project

List Work Packages
GET/api/v3/projects/{id}/work_packages{?offset,pageSize,filters,sortBy,groupBy,showSums}

Example URI

GET /api/v3/projects/1/work_packages?offset=25&pageSize=25&filters=[{ "status_id": { "operator": "o", "values": null }" }]&sortBy=[["status", "asc"]]&groupBy=status&showSums=true
URI Parameters
HideShow
id
integer (required) Example: 1

Project id

offset
integer (optional) Default: 1 Example: 25

Page number inside the requested collection.

pageSize
integer (optional) Example: 25

Number of elements to display per page.

filters
string (optional) Example: [{ "status_id": { "operator": "o", "values": null }" }]

JSON specifying filter conditions. Accepts the same format as returned by the queries endpoint.

sortBy
string (optional) Example: [["status", "asc"]]

JSON specifying sort criteria. Accepts the same format as returned by the queries endpoint.

groupBy
string (optional) Example: status

The column to group by.

showSums
boolean (optional) Default: false Example: true

Indicates whether properties should be summed up if they support it.

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/projects/14/work_packages"
    }
  },
  "total": 2,
  "count": 2,
  "_type": "Collection",
  "_embedded": {
    "elements": [
      {
        "_type": "WorkPackage",
        "_links": {
          "self": {
            "href": "/api/v3/work_packages/1"
          }
        },
        "id": 1,
        "subject": "Skipped other properties for brevity"
      },
      {
        "_type": "WorkPackage",
        "_links": {
          "self": {
            "href": "/api/v3/work_packages/2"
          }
        },
        "id": 2,
        "subject": "Skipped other properties for brevity"
      }
    ]
  }
}
Response  400
HideShow

Returned if the client sends a query parameter, that the server knows, but does not understand. E.g. by providing a syntactically incorrect filters parameter.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidQuery",
  "message": "Operator can't be blank."
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: view work packages

Note that you will only receive this error, if you are at least allowed to see the corresponding project.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to see the work packages of this project."
}
Response  404
HideShow

Returned if the project does not exist or the client does not have sufficient permissions to see it.

Required permission: view project

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified project does not exist."
}

Create Work Package
POST/api/v3/projects/{id}/work_packages{?notify}

When calling this endpoint the client provides a single object, containing at least the properties and links that are required, in the body. The required fields of a WorkPackage can be found in its schema, which is embedded in the respective form. Note that it is only allowed to provide properties or links supporting the write operation.

Example URI

POST /api/v3/projects/1/work_packages?notify=false
URI Parameters
HideShow
id
integer (required) Example: 1

Project id

notify
boolean (optional) Default: true Example: false

Indicates whether change notifications (e.g. via E-Mail) should be sent. Note that this controls notifications for all users interested in changes to the work package (e.g. watchers, author and assignee), not just the current user.

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_type": "WorkPackage",
  "_links": {
    "self": {
      "href": "/api/v3/work_packages/1528",
      "title": "Develop API"
    },
    "schema": {
      "href": "/api/v3/work_packages/schemas/1-1-2"
    },
    "update": {
      "href": "/api/v3/work_packages/1528",
      "method": "patch",
      "title": "Update Develop API"
    },
    "delete": {
      "href": "/work_packages/bulk?ids=1528",
      "method": "delete",
      "title": "Delete Develop API"
    },
    "log_time": {
      "href": "/work_packages/1528/time_entries/new",
      "type": "text/html",
      "title": "Log time on Develop API"
    },
    "move": {
      "href": "/work_packages/1528/move/new",
      "type": "text/html",
      "title": "Move Develop API"
    },
    "attachments": {
      "href": "/api/v3/work_packages/1528/attachments"
    },
    "addAttachment": {
      "href": "/api/v3/work_packages/1528/attachments",
      "method": "post"
    },
    "author": {
      "href": "/api/v3/users/1",
      "title": "OpenProject Admin - admin"
    },
    "responsible": {
      "href": "/api/v3/users/23",
      "title": "Laron Leuschke - Alaina5788"
    },
    "relations": {
      "href": "/api/v3/work_packages/1528/relations",
      "title": "Show relations"
    },
    "revisions": {
      "href": "/api/v3/work_packages/1528/revisions"
    },
    "assignee": {
      "href": "/api/v3/users/11",
      "title": "Emmie Okuneva - Adele5450"
    },
    "priority": {
      "href": "/api/v3/priorities/2",
      "title": "Normal"
    },
    "project": {
      "href": "/api/v3/projects/1",
      "title": "A Test Project"
    },
    "status": {
      "href": "/api/v3/statuses/1",
      "title": "New"
    },
    "type": {
      "href": "/api/v3/types/1",
      "title": "New"
    },
    "version": {
      "href": "/api/v3/versions/1",
      "title": "Version 1"
    },
    "availableWatchers": {
      "href": "/api/v3/work_packages/1528/available_watchers"
    },
    "watch": {
      "href": "/api/v3/work_packages/1528/watchers",
      "method": "post",
      "payload": {
        "user": {
          "href": "/api/v3/users/1"
        }
      }
    },
    "addWatcher": {
      "href": "/api/v3/work_packages/1528/watchers",
      "method": "post",
      "payload": {
        "user": {
          "href": "/api/v3/users/{user_id}"
        }
      },
      "templated": true
    },
    "removeWatcher": {
      "href": "/api/v3/work_packages/1528/watchers/{user_id}",
      "method": "delete",
      "templated": true
    },
    "addRelation": {
      "href": "/api/v3/relations",
      "method": "post",
      "title": "Add relation"
    },
    "changeParent": {
      "href": "/api/v3/work_packages/694",
      "method": "patch",
      "title": "Change parent of Bug in OpenProject"
    },
    "addComment": {
      "href": "/api/v3/work_packages/1528/activities",
      "method": "post",
      "title": "Add comment"
    },
    "parent": {
      "href": "/api/v3/work_packages/1298",
      "title": "nisi eligendi officiis eos delectus quis voluptas dolores"
    },
    "category": {
      "href": "/api/v3/categories/1298",
      "title": "eligend isi"
    },
    "children": [
      {
        "href": "/api/v3/work_packages/1529",
        "title": "Write API documentation"
      }
    ],
    "ancestors": [
      {
        "href": "/api/v3/work_packages/1290",
        "title": "Root node of hierarchy"
      },
      {
        "href": "/api/v3/work_packages/1291",
        "title": "Intermediate node of hierarchy"
      },
      {
        "href": "/api/v3/work_packages/1298",
        "title": "nisi eligendi officiis eos delectus quis voluptas dolores"
      }
    ],
    "timeEntries": {
      "href": "/work_packages/1528/time_entries",
      "type": "text/html",
      "title": "Time entries"
    },
    "watchers": {
      "href": "/api/v3/work_packages/1528/watchers"
    },
    "customField3": {
      "href": "api/v3/users/14"
    }
  },
  "id": 1528,
  "subject": "Develop API",
  "description": {
    "format": "textile",
    "raw": "Develop super cool OpenProject API.",
    "html": "<p>Develop super cool OpenProject API.</p>"
  },
  "startDate": null,
  "dueDate": null,
  "estimatedTime": "PT2H",
  "percentageDone": 0,
  "customField1": "Foo",
  "customField2": 42,
  "createdAt": "2014-08-29T12:40:53Z",
  "updatedAt": "2014-08-29T12:44:41Z"
}
Response  400
HideShow

Occurs when the client did not send a valid JSON object in the request body.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
  "message": "The request body was not a single JSON object."
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: add work packages

Note that you will only receive this error, if you are at least allowed to see the corresponding project.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to add work packages to this project."
}
Response  404
HideShow

Returned if the project does not exist or the client does not have sufficient permissions to see it.

Required permissions: 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.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified project does not exist."
}
Response  422
HideShow

Returned if:

  • the client tries to write a read-only property

  • a constraint for a property was violated

  • a property was provided in an unreadable format

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation",
  "message": "The subject might not be blank.",
  "_embedded": {
    "details": {
      "attribute": "Subject"
    }
  }
}

Work Package Create Form

This endpoint returns a form to allow a guided creation of a new work package. The returned form will be pre-filled with default values for every property, if available.

For more details and all possible responses see the general specification of Forms.

Work Package Create Form
POST/api/v3/projects/{id}/work_packages/form

Example URI

POST /api/v3/projects/1/work_packages/form
URI Parameters
HideShow
id
integer (required) Example: 1

ID of the project in which the work package will be created

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/example/form"
    },
    "validate": {
      "href": "/api/v3/example/form",
      "method": "POST"
    },
    "previewMarkup": {
      "href": "/api/v3/render/textile",
      "method": "POST"
    },
    "commit": {
      "href": "/api/v3/example",
      "method": "PATCH"
    }
  },
  "_type": "Form",
  "_embedded": {
    "payload": {
      "_links": {
        "status": {
          "href": "/api/v3/statuses/1"
        }
      },
      "_type": "Example",
      "lockVersion": 5,
      "subject": "An example title"
    },
    "schema": {
      "_type": "Schema",
      "_links": {
        "self": {
          "href": "/api/v3/example/schema"
        }
      },
      "lockVersion": {
        "type": "Integer",
        "writable": false
      },
      "subject": {
        "type": "String",
        "minLength": 1,
        "maxLength": 255
      },
      "status": {
        "_links": {
          "allowedValues": [
            {
              "href": "/api/v3/statuses/1",
              "title": "New"
            },
            {
              "href": "/api/v3/statuses/2",
              "title": "Closed"
            }
          ]
        },
        "type": "Status",
        "_embedded": {
          "allowedValues": [
            {
              "_links": {
                "self": {
                  "href": "/api/v3/statuses/1"
                }
              },
              "_type": "Status",
              "id": 1,
              "name": "New",
              "position": 1,
              "isDefault": true,
              "isClosed": false,
              "defaultDoneRatio": 0,
              "createdAt": "2014-05-21T08:51:20Z",
              "updatedAt": "2014-05-21T09:12:00Z"
            },
            {
              "_links": {
                "self": {
                  "href": "/api/v3/statuses/2"
                }
              },
              "_type": "Status",
              "id": 2,
              "name": "Closed",
              "position": 2,
              "isDefault": false,
              "isClosed": true,
              "defaultDoneRatio": 100,
              "createdAt": "2014-05-21T08:51:20Z",
              "updatedAt": "2014-05-21T09:12:00Z"
            }
          ]
        }
      }
    },
    "validationErrors": {
      "subject": {
        "_type": "Error",
        "errorIdentifier": "urn:openproject-org:api:v3:errors:BadExampleError",
        "message": "For the purpose of this example we need a validation error. The remainder of the response pretends there were no errors."
      }
    }
  }
}

Relations

Create Relation
POST/api/v3/work_packages/{work_package_id}/relations

When calling this endpoint the client provides a single object, containing at least the properties and links that are required, in the body. The required fields of a Relation can be found in its schema, which is embedded in the respective form. Note that it is only allowed to provide properties or links supporting the write operation.

Example URI

POST /api/v3/work_packages/1/relations
URI Parameters
HideShow
work_package_id
integer (required) Example: 1

Work package id

Request  Create Relation
HideShow
Headers
Content-Type: application/json
Body
{
    "_links":
    {
        "from": { "href": "/api/v3/work_packages/42" },
        "to": { "href": "/api/v3/work_packages/84" }
    }
    "type": "duplicates",
    "description": "This is the same thing. Let's track it in one place only, shall we?"
}
Response  201
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/relations/1"
    },
    "update": {
      "href": "/api/v3/relations/1/form",
      "method": "POST"
    },
    "updateImmediately": {
      "href": "/api/v3/relations/1",
      "method": "PATCH"
    },
    "delete": {
      "href": "/api/v3/relations/1",
      "method": "DELETE"
    },
    "from": {
      "href": "/api/v3/work_packages/42",
      "title": "Steel Delivery"
    },
    "to": {
      "href": "/api/v3/work_packages/84",
      "title": "Bending the steel"
    }
  },
  "_type": "Relation",
  "id": 1,
  "name": "precedes",
  "type": "precedes",
  "reverseType": "follows",
  "description": "We can't bend the steel before it's been delivered!",
  "delay": 0
}
Response  400
HideShow

Occurs when the client did not send a valid JSON object in the request body.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
  "message": "The request body was not a single JSON object."
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: manage work package relations

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to create a relation."
}
Response  409
HideShow

Returned if there already exists a relation between the given work packages of any type or if the relation is not allowed.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:UpdateConflict",
  "message": "A relation of that type between the work packages either already exists or is not allowed."
}
Response  422
HideShow

Returned if:

  • the client tries to write a read-only property (PropertyIsReadOnly)

  • a constraint for a property was violated (PropertyConstraintViolation)

  • the client provides a link to an invalid resource (ResourceTypeMismatch)

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation",
  "message": "Delay must be a number greater than or equal to 0",
  "_embedded": {
    "details": {
      "attribute": "delay"
    }
  }
}

List relations
GET/api/v3/work_packages/{work_package_id}/relations

Lists all relations this work package is involved in.

Example URI

GET /api/v3/work_packages/1/relations
URI Parameters
HideShow
work_package_id
integer (required) Example: 1

Work package id

Response  302
HideShow
Headers
Content-Type: text/plain
Location: /api/v3/relations?involved={work_package_id}
Body
You are being redirected to /api/v3/relations?involved={work_package_id}

Work Package Relation Form

Relation create form
POST/api/v3/work_packages/{id}/relations/form

Example URI

POST /api/v3/work_packages/1/relations/form
URI Parameters
HideShow
id
integer (required) Example: 1

ID of the relation being modified

Request
HideShow
Body
{
  "_type": "Relation",
  "type": "follows",
  "from": {
    "href": "/api/v3/work_packages/3493"
  },
  "to": {
    "href": "/api/v3/work_packages/4582"
  },
  "description": "let it rest for 3 days",
  "delay": 3
}
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/relations/form"
    },
    "validate": {
      "href": "/api/v3/relations/form",
      "method": "POST"
    },
    "commit": {
      "href": "/api/v3/relations",
      "method": "PATCH"
    }
  },
  "_type": "Form",
  "_embedded": {
    "payload": {
      "_links": {
        "from": {
          "href": "/api/v3/work_packages/4534"
        },
        "to": {
          "href": "/api/v3/work_packages/3857"
        }
      },
      "_type": "WorkPackage",
      "type": "follows",
      "delay": 3,
      "description": "let it rest for 3 days"
    },
    "schema": {
      "_type": "Schema",
      "id": {
        "name": "ID",
        "type": "Integer",
        "writable": false
      },
      "type": {
        "name": "Type",
        "type": "String",
        "writable": true,
        "allowedValues": [
          "relates",
          "duplicates",
          "duplicated",
          "blocks",
          "blocked",
          "precedes",
          "follows",
          "includes",
          "partof",
          "requires",
          "required"
        ]
      },
      "reverseType": {
        "name": "Reverse Type",
        "type": "String",
        "writable": false
      },
      "description": {
        "name": "Description",
        "type": "String",
        "writable": true
      },
      "from": {
        "_links": {
          "allowedValues": [
            {
              "href": "/api/v3/work_packages/{id}"
            }
          ]
        },
        "name": "From work package",
        "type": "WorkPackage",
        "writable": true
      },
      "to": {
        "_links": {
          "allowedValues": {
            "href": "/api/v3/work_packages/{id}/available_relation_candidates",
            "title": "Available work packages to relate to"
          }
        },
        "name": "To work package",
        "type": "WorkPackage",
        "writable": true
      },
      "delay": {
        "name": "Delay",
        "type": "Integer",
        "writable": true
      }
    },
    "validationErrors": {
      "from": {
        "_type": "Error",
        "errorIdentifier": "urn:openproject-org:api:v3:errors:BadExampleError",
        "message": "For the purpose of this example we need a validation error. The remainder of the response pretends there were no errors."
      }
    }
  }
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: manage work package relations

Note that you will only receive this error, if you are at least allowed to see the involved work packages.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to edit the specified relation."
}
Response  404
HideShow

Returned if the relation does not exist or the client does not have sufficient permissions to see it.

Required permission: view (involved) work package(s), manage work package relations

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified relation does not exist."
}

Watchers

List watchers
GET/api/v3/work_packages/{work_package_id}/watchers

Example URI

GET /api/v3/work_packages/1/watchers
URI Parameters
HideShow
work_package_id
integer (required) Example: 1

Work package id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_links": {
        "self": { "href": "/api/v3/work_packages/14/watchers" }
    },
    "total": 2,
    "count": 2,
    "_type": "Collection",
    "_embedded": {
      "elements": [
        {
            "_type": "User",
            "_links": {
                "self": {
                    "href": "/api/v3/users/1",
                    "title": "John Sheppard - j.sheppard"
                },
                "showUser": {
                    "href": "/users/1",
                    "type": 'text/html'
                },
                "lock": {
                    "href": "/api/v3/users/1/lock",
                    "title": "Set lock on j.sheppard"
                    "method": "POST"
                },
                "delete": {
                    "href": "/api/v3/users/1",
                    "title": "Delete j.sheppard"
                    "method": "DELETE"
                }
            },
            "id": 1,
            "login": "j.sheppard",
            "firstName": "John",
            "lastName": "Sheppard",
            "mail": "shep@mail.com",
            "avatar": "https://gravatar/avatar",
            "status": "active",
            "createdAt": "2014-05-21T08:51:20Z",
            "updatedAt": "2014-05-21T08:51:20Z"
        },
        {
            "_type": "User",
            "_links": {
                "self": {
                    "href": "/api/v3/users/2",
                    "title": "Jim Sheppard - j.sheppard2"
                },
                "lock": {
                    "href": "/api/v3/users/2/lock",
                    "title": "Set lock on j.sheppard2"
                    "method": "POST"
                },
                "delete": {
                    "href": "/api/v3/users/2",
                    "title": "Delete j.sheppard2"
                    "method": "DELETE"
                }
            },
            "id": 2,
            "login": "j.sheppard2",
            "firstName": "Jim",
            "lastName": "Sheppard",
            "mail": "shep@mail.net",
            "avatar": "https://gravatar/avatar",
            "status": "active",
            "createdAt": "2014-05-21T08:51:20Z",
            "updatedAt": "2014-05-21T08:51:20Z"
        }]
    }
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: view work package watchers

Note that you will only receive this error, if you are at least allowed to see the corresponding work package.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to see the watchers of this work package."
}
Response  404
HideShow

Returned if the work package does not exist or the client does not have sufficient permissions to see it.

Required permission: view work package

Note that you will effectively not be able to see the watchers of a work package without being able to see the work package.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified work package does not exist."
}

Add watcher
POST/api/v3/work_packages/{work_package_id}/watchers

Adds a watcher to the specified work package.

The request is expected to contain a single JSON object, that contains a link object under the user key.

The response will be user added as watcher. In case the user was already watching the work package an HTTP 200 is returned, an HTTP 201 if the user was added as a new watcher.

Example URI

POST /api/v3/work_packages/1/watchers
URI Parameters
HideShow
work_package_id
integer (required) Example: 1

Work package id

Request
HideShow
Headers
Content-Type: application/json
Body
{
  "user": {
    "href": "/api/v3/users/1"
  }
}
Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_type": "User",
    "_links": {
        "self": {
            "href": "/api/v3/users/1",
            "title": "j.sheppard"
        },
        "show": {
            "href": "/users/1",
            "type": 'text/html'
        },
        "lock": {
            "href": "/api/v3/users/1/lock",
            "method": "POST"
        },
        "updateImmediately": {
            "href": "/api/v3/users/1",
            "method": "PATCH"
        },
        "delete": {
            "href": "/api/v3/users/1",
            "method": "DELETE"
        },
    },
    "id": 1,
    "login": "j.sheppard",
    "firstName": "John",
    "lastName": "Sheppard",
    "email": "shep@mail.com",
    "admin": true,
    "avatar": "https://gravatar/avatar",
    "status": "active",
    "language": "en",
    "createdAt": "2014-05-21T08:51:20Z",
    "updatedAt": "2014-05-21T08:51:20Z"
}
Response  201
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_type": "User",
    "_links": {
        "self": {
            "href": "/api/v3/users/1",
            "title": "j.sheppard"
        },
        "show": {
            "href": "/users/1",
            "type": 'text/html'
        },
        "lock": {
            "href": "/api/v3/users/1/lock",
            "method": "POST"
        },
        "updateImmediately": {
            "href": "/api/v3/users/1",
            "method": "PATCH"
        },
        "delete": {
            "href": "/api/v3/users/1",
            "method": "DELETE"
        },
    },
    "id": 1,
    "login": "j.sheppard",
    "firstName": "John",
    "lastName": "Sheppard",
    "email": "shep@mail.com",
    "admin": true,
    "avatar": "https://gravatar/avatar",
    "status": "active",
    "language": "en",
    "createdAt": "2014-05-21T08:51:20Z",
    "updatedAt": "2014-05-21T08:51:20Z"
}
Response  400
HideShow

Occurs when the client did not send a valid JSON object in the request body.

For example:

  • The request did not contain a single JSON object

  • The JSON object did not contain the key user

  • The value of users was not a link object

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
  "message": "The request body was not a single JSON object."
}
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permissions:

  • view work package (for self)

  • add work package watchers (for other users)

Note that you will only receive this error, if you are at least allowed to see the corresponding work package.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to add watchers to this work package."
}
Response  404
HideShow

Returned if the work package does not exist or the client does not have sufficient permissions to see it.

Required permission: view work package

Note that you will effectively not be able to change the watchers of a work package without being able to see the work package.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified work package does not exist."
}
Response  422
HideShow

Returned if:

  • the client tries to specify a link to a resource that is not a user (ResourceTypeMismatch)

  • the user specified is not allowed to watch that work package (PropertyConstraintViolation)

  • the user specified does not exist (PropertyConstraintViolation)

Headers
Content-Type: application/hal+json
Body
{
    "_type": "Error",
    "errorIdentifier": "urn:openproject-org:api:v3:errors:ResourceTypeMismatch",
    "message": "Expected resource of type 'User', but got a 'Status'.",
}

Remove Watcher

Remove watcher
DELETE/api/v3/work_packages/{work_package_id}/watchers/{id}

Removes the specified user from the list of watchers for the given work package.

If the request succeeds, the specified user is not watching the work package anymore.

Note: This might also be the case, if the specified user did not watch the work package prior to the request.

Example URI

DELETE /api/v3/work_packages/1/watchers/1
URI Parameters
HideShow
work_package_id
integer (required) Example: 1

Work package id

id
integer (required) Example: 1

User id

Response  204
Response  403
HideShow

Returned if the client does not have sufficient permissions.

Required permission: delete work package watchers

Note that you will only receive this error, if you are at least allowed to see the corresponding work package.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
  "message": "You are not allowed to remove watchers from this work package."
}
Response  404
HideShow

Returned in one of the following cases:

Either the work package does not exist or the client does not have sufficient permissions to see it.

Required permission: view work package

Or the specified user does not exist at all.

Note that you will effectively not be able to change the watchers of a work package without being able to see the work package.

Headers
Content-Type: application/hal+json
Body
{
  "_type": "Error",
  "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
  "message": "The specified work package does not exist."
}

Available relation candidates

Lists work packages with which this work package can be in a relation. Only sound candidates are returned. For instance a work package cannot stand in relation to itself, and a work package that follows another cannot precede it.

Candidates can be filtered. Most commonly one will want to filter by subject. You can do this through the filters parameter which works just like the work package index.

For instance to find all work packages with “rollout” in their subject:

?filters=[{"subject":{"operator":"~","values":["rollout"]}}]

For convenience there is also a simple query parameter which is a shortcut for listing work packages whose ID or subject contain the given string.

While the endpoint does support the pageSize parameter to limit the number of results it does not support the offset parameter.

?query=112

Available relation candidates
GET/api/v3/work_packages/available_relation_candidates{?filters,query,type,pageSize}

Example URI

GET /api/v3/work_packages/available_relation_candidates?filters=[{ "status_id": { "operator": "o", "values": null }" }]&query="rollout"&type="follows"&pageSize=25
URI Parameters
HideShow
pageSize
integer (optional) Example: 25

Maximum number of candidates to list (default 10)

filters
string (optional) Example: [{ "status_id": { "operator": "o", "values": null }" }]

JSON specifying filter conditions. Accepts the same format as returned by the queries endpoint.

query
string (optional) Example: "rollout"

Shortcut for filtering by ID or subject

type
string (optional) Example: "follows"

Type of relation to find candidates for (default “relates”)

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
  "_links": {
    "self": {
      "href": "/api/v3/projects/14/work_packages"
    }
  },
  "total": 2,
  "count": 2,
  "_type": "Collection",
  "_embedded": {
    "elements": [
      {
        "_type": "WorkPackage",
        "_links": {
          "self": {
            "href": "/api/v3/work_packages/1"
          }
        },
        "id": 1,
        "subject": "Skipped other properties for brevity"
      },
      {
        "_type": "WorkPackage",
        "_links": {
          "self": {
            "href": "/api/v3/work_packages/2"
          }
        },
        "id": 2,
        "subject": "Skipped other properties for brevity"
      }
    ]
  }
}

Available Watchers

Available watchers
GET/api/v3/work_packages/{id}/available_watchers

Gets a list of users that are able to be watchers of the specified work package.

Example URI

GET /api/v3/work_packages/1/available_watchers
URI Parameters
HideShow
id
integer (required) Example: 1

work package id

Response  200
HideShow
Headers
Content-Type: application/hal+json
Body
{
    "_links": {
        "self": { "href": "/api/v3/work_packages/1/available_watchers" }
    },
    "total": 2,
    "count": 2,
    "_type": "Collection",
    "_embedded": {
      "elements": [
        {
            "_type": "User",
            "_links": {
                "self": {
                    "href": "/api/v3/users/1",
                    "title": "John Sheppard - j.sheppard"
                },
                "lock": {
                    "href": "/api/v3/users/1/lock",
                    "title": "Set lock on j.sheppard"
                    "method": "POST"
                },
                "delete": {
                    "href": "/api/v3/users/1",
                    "title": "Delete j.sheppard"
                    "method": "DELETE"
                }
            },
            "id": 1,
            "login": "j.sheppard",
            "firstName": "John",
            "lastName": "Sheppard",
            "email": "shep@mail.com",
            "avatar": "https://gravatar/avatar",
            "status": "active",
            "createdAt": "2014-05-21T08:51:20Z",
            "updatedAt": "2014-05-21T08:51:20Z"
        },
        {
            "_type": "User",
            "_links": {
                "self": {
                    "href": "/api/v3/users/2",
                    "title": "Jim Sheppard - j.sheppard2"
                },
                "lock": {
                    "href": "/api/v3/users/2/lock",
                    "title": "Set lock on j.sheppard2"
                    "method": "POST"
                },
                "delete": {
                    "href": "/api/v3/users/2",
                    "title": "Delete j.sheppard2"
                    "method": "DELETE"
                }
            },
            "id": 2,