API: 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.
For resources invisible to the client (e.g. because of missing permissions), a link will contain the uri urn:openproject-org:api:v3:undisclosed
instead of a url. This indicates the existence of a value without revealing the actual value. An example for this is the parent project. A project resource which itself might be visible to the client can have a reference to a parent project invisible to the same client. Revealing the existence of a parent over hiding has the benefit of allowing the client to make an informed decision of whether to keep the existing reference or updating it. Sending ‘{ “href”: “urn:openproject-org:api:v3:undisclosed” }` for a resource will have the effect of keeping the original value. This is especially beneficial if the client creates and updates resources based on the payload object provided as part of a form as is recommended when interacting with the API.
Errors
In case of an error, the API will respond with an appropriate 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 erroneous response.
General errors
-
Error objects have their
_type
set toError
-
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 occurred. 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",
"erroneousField": "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 occurred.
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:InvalidRenderContext
(HTTP 400) The client specified a rendering context that does not exist -
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:InvalidSignal
(HTTP 400) The client specified a select not available on the resource, e.g because the property/link does not exist on it. -
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:PropertyConstraintViolation
(HTTP 422) The client tried to set a property to an invalid value -
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: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:PropertyMissingError
(HTTP 422) The request is syntactically correct, but is missing a property to perform the requested action -
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:InternalServerError
(HTTP 500) Default for HTTP 500 when no further information is available -
urn:openproject-org:api:v3:errors:MultipleErrors
Multiple errors occurred. See the embeddederrors
array for more details.
Formattable Text
OpenProject supports text formatting in Markdown. 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 | markdown | 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 -
markdown
- formatting using Markdown -
custom
- There is no apparent formatting rule that transforms the raw version to HTML (only used for read only properties)
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": "markdown",
"raw": "I **am** formatted!",
"html": "I <strong>am</strong> formatted!"
}
Dates, Times, Durations and Timestamps
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, optionally with milliseconds, e.g. “2014-05-21T13:37:00Z” or “2014-05-21T13:37:00.396Z” -
Duration
- refers to an ISO 8601 duration, e.g. “P1DT18H” -
Timestamp
- refers to an ISO 8601 combined date and time, e.g. “2014-05-21T13:37:00Z” or to an ISO 8601 duration, e.g. “P1DT18H”. The following shorthand values are also being parsed as duration: “1d”, “1w”, “1m”, “1y”, “1y-2m”, “-2y”. It can also refer the following relative date keywords:"oneDayAgo@HH:MM+HH:MM", "lastWorkingDay@HH:MM+HH:MM", "oneWeekAgo@HH:MM+HH:MM", "oneMonthAgo@HH:MM+HH:MM"
. The"HH:MM"
part represents the zero padded hours and minutes, e.g."oneMonthAgo@21:00+00:00"
. The last “+HH:MM” part represents the timezone offset from UTC associated with the time, e.g."oneMonthAgo@21:00+02:00"
means a +2 hour timezone offset from UTC. The offset can be positive or negative e.g.“oneDayAgo@01:00+01:00”, “oneDayAgo@01:00-01:00”. Values older than 1 day are accepted only with valid Enterprise Token available.
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.
Example
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"
}