API: Hourly rates
An hourly rate defines what an hour of work by a principal (a user or a placeholder user) costs. It applies from its validFrom date until a later rate of the same kind takes effect.
Two kinds of rate exist, told apart by the presence of the project link:
- A project rate links a project and applies within that project only.
- A default rate carries no
projectlink and applies in every project in which the principal has no project rate.
Both are rendered as HourlyRate and are served below the principal they belong to, ordered by validFrom descending.
Creating, changing or deleting a rate recalculates the costs of time entries and budgets already booked in the period the rate covers.
Linked Properties
| Link | Description | Type | Constraints | Supported operations |
|---|---|---|---|---|
| self | This hourly rate | HourlyRate | not null | READ |
| principal | The user or placeholder user the rate belongs to | Principal | not null | READ |
| project | The project the rate applies in; absent on a default rate | Project | READ / WRITE |
project can only be written when creating a rate. A rate cannot be moved from one project to another, and a project rate cannot be turned into a default rate or the other way around.
Local Properties
| Property | Description | Type | Constraints | Supported operations |
|---|---|---|---|---|
| id | The unique identifier of the rate | Integer | x > 0 | READ |
| validFrom | The date from which the rate takes effect (ISO 8601 format) | Date | not null | READ / WRITE |
| rate | The amount charged per hour, in the currency configured for the instance | Float | not null | READ / WRITE |
Permissions
Reading:
- Reaching a principal’s rates at all requires the
view_hourly_ratespermission in at least one project, unless the principal is the requesting user. - A project rate is readable in the project it applies in, and requires
view_hourly_ratesthere, orview_own_hourly_ratewhen the rate belongs to the requesting user. Having neither hides the rate even from the principal it belongs to. - A default rate belongs to no project and is returned as soon as the principal’s rates are reachable.
Writing:
- A project rate requires the
edit_hourly_ratespermission in the rate’s project, oredit_own_hourly_ratein that project when the rate belongs to the requesting user. - A default rate requires the global
manage_default_hourly_ratespermission. - Administrators may manage every rate.
Methods
List hourly rates of a principal
Lists the hourly rates of the given principal that are visible to the requesting user, ordered by validFrom descending.
The collection mixes both kinds of rate. A rate linking a project applies in that project only, a rate without one is the principal’s default rate and applies wherever no project rate does.
Required permissions:
- Reaching a principal’s rates at all requires
view_hourly_ratesin at least one project, unless the principal is the requesting user. - Project rates are limited to the projects granting the requesting user
view_hourly_rates, plus, for their own rates, the projects granting themview_own_hourly_rate. - Default rates belong to no project and are returned as soon as the principal’s rates are reachable.
id
integer
required path
Principal id.
Example:42
200
OK
HourlyRateCollectionModel{
"allOf": [
{
"$ref": "#/components/schemas/CollectionModel"
},
{
"type": "object",
"required": [
"_links",
"_embedded"
],
"properties": {
"_links": {
"type": "object",
"required": [
"self"
],
"properties": {
"self": {
"allOf": [
{
"$ref": "#/components/schemas/Link"
},
{
"description": "This collection of hourly rates.\n**Resource**: HourlyRateCollectionModel"
}
]
}
}
},
"_embedded": {
"type": "object",
"required": [
"elements"
],
"properties": {
"elements": {
"type": "array",
"description": "The array of hourly rates visible to the requesting user, ordered by `validFrom` descending.\nProject rates and default rates are told apart by the presence of the `project` link.",
"items": {
"$ref": "#/components/schemas/HourlyRateModel"
}
}
}
}
}
}
],
"example": {
"_type": "Collection",
"total": 2,
"count": 2,
"_links": {
"self": {
"href": "/api/v3/principals/42/hourly_rates"
}
},
"_embedded": {
"elements": [
{
"_type": "HourlyRate",
"id": 1,
"validFrom": "2025-01-01",
"rate": 50.0,
"_links": {
"self": {
"href": "/api/v3/principals/42/hourly_rates/1"
},
"principal": {
"href": "/api/v3/users/42",
"title": "Jane Doe"
},
"project": {
"href": "/api/v3/projects/7",
"title": "Customer Portal"
}
}
},
{
"_type": "HourlyRate",
"id": 2,
"validFrom": "2024-01-01",
"rate": 30.0,
"_links": {
"self": {
"href": "/api/v3/principals/42/hourly_rates/2"
},
"principal": {
"href": "/api/v3/users/42",
"title": "Jane Doe"
}
}
}
]
}
}
}
404
Returned if the principal does not exist, is not visible to the requesting user, or the requesting user may not see their rates.
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
"message": "The requested resource could not be found."
}
ErrorResponse{
"type": "object",
"required": [
"_type",
"errorIdentifier",
"message"
],
"properties": {
"_embedded": {
"type": "object",
"properties": {
"details": {
"type": "object",
"properties": {
"attribute": {
"type": "string",
"example": "project"
}
}
}
}
},
"_type": {
"type": "string",
"enum": [
"Error"
]
},
"errorIdentifier": {
"type": "string",
"example": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation"
},
"message": {
"type": "string",
"example": "Project can't be blank."
}
}
}
Create an hourly rate for a principal
Creates an hourly rate for the given principal, taking effect from validFrom.
Linking a project creates a rate for that project. Omitting the link creates the principal’s default rate, which applies in every project where no project rate is set up.
Creating a rate recalculates the costs of time entries and budgets already booked in the period the rate covers.
Required permissions:
- A project rate requires
edit_hourly_ratesin the linked project, oredit_own_hourly_ratein it when the rate is the requesting user’s own. - A default rate requires the global
manage_default_hourly_ratespermission.
id
integer
required path
Principal id.
Example:42
{
"validFrom": "2026-01-01",
"rate": 95,
"_links": {
"project": {
"href": "/api/v3/projects/7"
}
}
}
{
"_type": {
"type": "string",
"enum": [
"HourlyRate"
]
},
"id": {
"type": "integer",
"description": "The unique identifier of the hourly rate.",
"minimum": 1
},
"validFrom": {
"type": "string",
"format": "date",
"description": "The date from which this rate takes effect (ISO 8601 format). It stays in effect until a\nlater rate of the same kind takes over."
},
"rate": {
"type": "number",
"format": "float",
"description": "The amount charged per hour, in the currency configured for the instance."
},
"_links": {
"type": "object",
"required": [
"self",
"principal"
],
"properties": {
"self": {
"allOf": [
{
"$ref": "#/components/schemas/Link"
},
{
"description": "This hourly rate.\n**Resource**: HourlyRate"
}
]
},
"principal": {
"allOf": [
{
"$ref": "#/components/schemas/Link"
},
{
"description": "The user or placeholder user this rate belongs to.\n**Resource**: Principal"
}
]
},
"project": {
"allOf": [
{
"$ref": "#/components/schemas/Link"
},
{
"description": "The project this rate applies in. Absent on a default rate, which applies in every\nproject where the principal has no project rate. Can only be written on creation.\n\n**Resource**: Project"
}
]
}
}
}
}
201
Created
HourlyRateModel{
"type": "object",
"required": [
"_type",
"id",
"validFrom",
"rate"
],
"properties": {
"_type": {
"type": "string",
"enum": [
"HourlyRate"
]
},
"id": {
"type": "integer",
"description": "The unique identifier of the hourly rate.",
"minimum": 1
},
"validFrom": {
"type": "string",
"format": "date",
"description": "The date from which this rate takes effect (ISO 8601 format). It stays in effect until a\nlater rate of the same kind takes over."
},
"rate": {
"type": "number",
"format": "float",
"description": "The amount charged per hour, in the currency configured for the instance."
},
"_links": {
"type": "object",
"required": [
"self",
"principal"
],
"properties": {
"self": {
"allOf": [
{
"$ref": "#/components/schemas/Link"
},
{
"description": "This hourly rate.\n**Resource**: HourlyRate"
}
]
},
"principal": {
"allOf": [
{
"$ref": "#/components/schemas/Link"
},
{
"description": "The user or placeholder user this rate belongs to.\n**Resource**: Principal"
}
]
},
"project": {
"allOf": [
{
"$ref": "#/components/schemas/Link"
},
{
"description": "The project this rate applies in. Absent on a default rate, which applies in every\nproject where the principal has no project rate. Can only be written on creation.\n\n**Resource**: Project"
}
]
}
}
}
},
"example": {
"_type": "HourlyRate",
"id": 1,
"validFrom": "2025-01-01",
"rate": 50.0,
"_links": {
"self": {
"href": "/api/v3/principals/42/hourly_rates/1"
},
"principal": {
"href": "/api/v3/users/42",
"title": "Jane Doe"
},
"project": {
"href": "/api/v3/projects/7",
"title": "Customer Portal"
}
}
}
}
400
Occurs when the client did not send a valid JSON object in the request body.
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
"message": "The request body was not a single JSON object."
}
ErrorResponse{
"type": "object",
"required": [
"_type",
"errorIdentifier",
"message"
],
"properties": {
"_embedded": {
"type": "object",
"properties": {
"details": {
"type": "object",
"properties": {
"attribute": {
"type": "string",
"example": "project"
}
}
}
}
},
"_type": {
"type": "string",
"enum": [
"Error"
]
},
"errorIdentifier": {
"type": "string",
"example": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation"
},
"message": {
"type": "string",
"example": "Project can't be blank."
}
}
}
403
Returned if the client does not have sufficient permissions.
Required permission: edit_hourly_rates or edit_own_hourly_rate in the linked project, or manage_default_hourly_rates globally when creating a default rate.
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
"message": "You are not authorized to access this resource."
}
ErrorResponse{
"type": "object",
"required": [
"_type",
"errorIdentifier",
"message"
],
"properties": {
"_embedded": {
"type": "object",
"properties": {
"details": {
"type": "object",
"properties": {
"attribute": {
"type": "string",
"example": "project"
}
}
}
}
},
"_type": {
"type": "string",
"enum": [
"Error"
]
},
"errorIdentifier": {
"type": "string",
"example": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation"
},
"message": {
"type": "string",
"example": "Project can't be blank."
}
}
}
404
Returned if the principal does not exist, is not visible to the requesting user, or the requesting user may not see their rates.
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
"message": "The requested resource could not be found."
}
ErrorResponse{
"type": "object",
"required": [
"_type",
"errorIdentifier",
"message"
],
"properties": {
"_embedded": {
"type": "object",
"properties": {
"details": {
"type": "object",
"properties": {
"attribute": {
"type": "string",
"example": "project"
}
}
}
}
},
"_type": {
"type": "string",
"enum": [
"Error"
]
},
"errorIdentifier": {
"type": "string",
"example": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation"
},
"message": {
"type": "string",
"example": "Project can't be blank."
}
}
}
406
415
Occurs when the client sends an unsupported Content-Type header.
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:TypeNotSupported",
"message": "Expected CONTENT-TYPE to be (expected value) but got (actual value)."
}
ErrorResponse{
"type": "object",
"required": [
"_type",
"errorIdentifier",
"message"
],
"properties": {
"_embedded": {
"type": "object",
"properties": {
"details": {
"type": "object",
"properties": {
"attribute": {
"type": "string",
"example": "project"
}
}
}
}
},
"_type": {
"type": "string",
"enum": [
"Error"
]
},
"errorIdentifier": {
"type": "string",
"example": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation"
},
"message": {
"type": "string",
"example": "Project can't be blank."
}
}
}
422
Returned if the request body contains invalid parameters.
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation",
"message": "Validation failed."
}
ErrorResponse{
"type": "object",
"required": [
"_type",
"errorIdentifier",
"message"
],
"properties": {
"_embedded": {
"type": "object",
"properties": {
"details": {
"type": "object",
"properties": {
"attribute": {
"type": "string",
"example": "project"
}
}
}
}
},
"_type": {
"type": "string",
"enum": [
"Error"
]
},
"errorIdentifier": {
"type": "string",
"example": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation"
},
"message": {
"type": "string",
"example": "Project can't be blank."
}
}
}
View an hourly rate
Returns a single hourly rate of the given principal.
Required permissions:
- Reaching a principal’s rates at all requires
view_hourly_ratesin at least one project, unless the principal is the requesting user. - A project rate additionally requires
view_hourly_ratesin the project it applies in, orview_own_hourly_ratethere when the rate belongs to the requesting user. - A default rate belongs to no project and is readable as soon as the principal’s rates are reachable.
id
integer
required path
Principal id.
Example:42
rate_id
integer
required path
Hourly rate id.
Example:1
200
OK
HourlyRateModel{
"type": "object",
"required": [
"_type",
"id",
"validFrom",
"rate"
],
"properties": {
"_type": {
"type": "string",
"enum": [
"HourlyRate"
]
},
"id": {
"type": "integer",
"description": "The unique identifier of the hourly rate.",
"minimum": 1
},
"validFrom": {
"type": "string",
"format": "date",
"description": "The date from which this rate takes effect (ISO 8601 format). It stays in effect until a\nlater rate of the same kind takes over."
},
"rate": {
"type": "number",
"format": "float",
"description": "The amount charged per hour, in the currency configured for the instance."
},
"_links": {
"type": "object",
"required": [
"self",
"principal"
],
"properties": {
"self": {
"allOf": [
{
"$ref": "#/components/schemas/Link"
},
{
"description": "This hourly rate.\n**Resource**: HourlyRate"
}
]
},
"principal": {
"allOf": [
{
"$ref": "#/components/schemas/Link"
},
{
"description": "The user or placeholder user this rate belongs to.\n**Resource**: Principal"
}
]
},
"project": {
"allOf": [
{
"$ref": "#/components/schemas/Link"
},
{
"description": "The project this rate applies in. Absent on a default rate, which applies in every\nproject where the principal has no project rate. Can only be written on creation.\n\n**Resource**: Project"
}
]
}
}
}
},
"example": {
"_type": "HourlyRate",
"id": 1,
"validFrom": "2025-01-01",
"rate": 50.0,
"_links": {
"self": {
"href": "/api/v3/principals/42/hourly_rates/1"
},
"principal": {
"href": "/api/v3/users/42",
"title": "Jane Doe"
},
"project": {
"href": "/api/v3/projects/7",
"title": "Customer Portal"
}
}
}
}
404
Returned if the principal or the rate does not exist, or the requesting user may not see it.
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
"message": "The requested resource could not be found."
}
ErrorResponse{
"type": "object",
"required": [
"_type",
"errorIdentifier",
"message"
],
"properties": {
"_embedded": {
"type": "object",
"properties": {
"details": {
"type": "object",
"properties": {
"attribute": {
"type": "string",
"example": "project"
}
}
}
}
},
"_type": {
"type": "string",
"enum": [
"Error"
]
},
"errorIdentifier": {
"type": "string",
"example": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation"
},
"message": {
"type": "string",
"example": "Project can't be blank."
}
}
}
Update an hourly rate
Updates validFrom or rate of the given hourly rate.
The project link can only be written when creating a rate. A rate can neither be moved from one project to another, nor be turned from a project rate into a default rate or the other way around.
Changing a rate recalculates the costs of time entries and budgets already booked in the period the rate covers.
Required permissions:
- A project rate requires
edit_hourly_ratesin the rate’s project, oredit_own_hourly_ratein it when the rate is the requesting user’s own. - A default rate requires the global
manage_default_hourly_ratespermission.
id
integer
required path
Principal id.
Example:42
rate_id
integer
required path
Hourly rate id.
Example:1
{
"_type": {
"type": "string",
"enum": [
"HourlyRate"
]
},
"id": {
"type": "integer",
"description": "The unique identifier of the hourly rate.",
"minimum": 1
},
"validFrom": {
"type": "string",
"format": "date",
"description": "The date from which this rate takes effect (ISO 8601 format). It stays in effect until a\nlater rate of the same kind takes over."
},
"rate": {
"type": "number",
"format": "float",
"description": "The amount charged per hour, in the currency configured for the instance."
},
"_links": {
"type": "object",
"required": [
"self",
"principal"
],
"properties": {
"self": {
"allOf": [
{
"$ref": "#/components/schemas/Link"
},
{
"description": "This hourly rate.\n**Resource**: HourlyRate"
}
]
},
"principal": {
"allOf": [
{
"$ref": "#/components/schemas/Link"
},
{
"description": "The user or placeholder user this rate belongs to.\n**Resource**: Principal"
}
]
},
"project": {
"allOf": [
{
"$ref": "#/components/schemas/Link"
},
{
"description": "The project this rate applies in. Absent on a default rate, which applies in every\nproject where the principal has no project rate. Can only be written on creation.\n\n**Resource**: Project"
}
]
}
}
}
}
200
OK
HourlyRateModel{
"type": "object",
"required": [
"_type",
"id",
"validFrom",
"rate"
],
"properties": {
"_type": {
"type": "string",
"enum": [
"HourlyRate"
]
},
"id": {
"type": "integer",
"description": "The unique identifier of the hourly rate.",
"minimum": 1
},
"validFrom": {
"type": "string",
"format": "date",
"description": "The date from which this rate takes effect (ISO 8601 format). It stays in effect until a\nlater rate of the same kind takes over."
},
"rate": {
"type": "number",
"format": "float",
"description": "The amount charged per hour, in the currency configured for the instance."
},
"_links": {
"type": "object",
"required": [
"self",
"principal"
],
"properties": {
"self": {
"allOf": [
{
"$ref": "#/components/schemas/Link"
},
{
"description": "This hourly rate.\n**Resource**: HourlyRate"
}
]
},
"principal": {
"allOf": [
{
"$ref": "#/components/schemas/Link"
},
{
"description": "The user or placeholder user this rate belongs to.\n**Resource**: Principal"
}
]
},
"project": {
"allOf": [
{
"$ref": "#/components/schemas/Link"
},
{
"description": "The project this rate applies in. Absent on a default rate, which applies in every\nproject where the principal has no project rate. Can only be written on creation.\n\n**Resource**: Project"
}
]
}
}
}
},
"example": {
"_type": "HourlyRate",
"id": 1,
"validFrom": "2025-01-01",
"rate": 50.0,
"_links": {
"self": {
"href": "/api/v3/principals/42/hourly_rates/1"
},
"principal": {
"href": "/api/v3/users/42",
"title": "Jane Doe"
},
"project": {
"href": "/api/v3/projects/7",
"title": "Customer Portal"
}
}
}
}
400
Occurs when the client did not send a valid JSON object in the request body.
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
"message": "The request body was not a single JSON object."
}
ErrorResponse{
"type": "object",
"required": [
"_type",
"errorIdentifier",
"message"
],
"properties": {
"_embedded": {
"type": "object",
"properties": {
"details": {
"type": "object",
"properties": {
"attribute": {
"type": "string",
"example": "project"
}
}
}
}
},
"_type": {
"type": "string",
"enum": [
"Error"
]
},
"errorIdentifier": {
"type": "string",
"example": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation"
},
"message": {
"type": "string",
"example": "Project can't be blank."
}
}
}
403
Returned if the client does not have sufficient permissions.
Required permission: edit_hourly_rates or edit_own_hourly_rate in the rate’s project, or manage_default_hourly_rates globally for a default rate.
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
"message": "You are not authorized to access this resource."
}
ErrorResponse{
"type": "object",
"required": [
"_type",
"errorIdentifier",
"message"
],
"properties": {
"_embedded": {
"type": "object",
"properties": {
"details": {
"type": "object",
"properties": {
"attribute": {
"type": "string",
"example": "project"
}
}
}
}
},
"_type": {
"type": "string",
"enum": [
"Error"
]
},
"errorIdentifier": {
"type": "string",
"example": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation"
},
"message": {
"type": "string",
"example": "Project can't be blank."
}
}
}
404
Returned if the principal or the rate does not exist, or the requesting user may not see it.
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
"message": "The requested resource could not be found."
}
ErrorResponse{
"type": "object",
"required": [
"_type",
"errorIdentifier",
"message"
],
"properties": {
"_embedded": {
"type": "object",
"properties": {
"details": {
"type": "object",
"properties": {
"attribute": {
"type": "string",
"example": "project"
}
}
}
}
},
"_type": {
"type": "string",
"enum": [
"Error"
]
},
"errorIdentifier": {
"type": "string",
"example": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation"
},
"message": {
"type": "string",
"example": "Project can't be blank."
}
}
}
406
415
Occurs when the client sends an unsupported Content-Type header.
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:TypeNotSupported",
"message": "Expected CONTENT-TYPE to be (expected value) but got (actual value)."
}
ErrorResponse{
"type": "object",
"required": [
"_type",
"errorIdentifier",
"message"
],
"properties": {
"_embedded": {
"type": "object",
"properties": {
"details": {
"type": "object",
"properties": {
"attribute": {
"type": "string",
"example": "project"
}
}
}
}
},
"_type": {
"type": "string",
"enum": [
"Error"
]
},
"errorIdentifier": {
"type": "string",
"example": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation"
},
"message": {
"type": "string",
"example": "Project can't be blank."
}
}
}
422
Returned if the request body contains invalid parameters, or if it tries to write the project link, which is read-only once the rate exists.
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation",
"message": "Validation failed."
}
ErrorResponse{
"type": "object",
"required": [
"_type",
"errorIdentifier",
"message"
],
"properties": {
"_embedded": {
"type": "object",
"properties": {
"details": {
"type": "object",
"properties": {
"attribute": {
"type": "string",
"example": "project"
}
}
}
}
},
"_type": {
"type": "string",
"enum": [
"Error"
]
},
"errorIdentifier": {
"type": "string",
"example": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation"
},
"message": {
"type": "string",
"example": "Project can't be blank."
}
}
}
Delete an hourly rate
Deletes the given hourly rate. The costs of time entries and budgets booked in the period the rate covered are recalculated with the rate that takes over.
Required permissions:
- A project rate requires
edit_hourly_ratesin the rate’s project, oredit_own_hourly_ratein it when the rate is the requesting user’s own. - A default rate requires the global
manage_default_hourly_ratespermission.
id
integer
required path
Principal id.
Example:42
rate_id
integer
required path
Hourly rate id.
Example:1
204
No Content. The rate was deleted successfully.
403
Returned if the client does not have sufficient permissions.
Required permission: edit_hourly_rates or edit_own_hourly_rate in the rate’s project, or manage_default_hourly_rates globally for a default rate.
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
"message": "You are not authorized to access this resource."
}
ErrorResponse{
"type": "object",
"required": [
"_type",
"errorIdentifier",
"message"
],
"properties": {
"_embedded": {
"type": "object",
"properties": {
"details": {
"type": "object",
"properties": {
"attribute": {
"type": "string",
"example": "project"
}
}
}
}
},
"_type": {
"type": "string",
"enum": [
"Error"
]
},
"errorIdentifier": {
"type": "string",
"example": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation"
},
"message": {
"type": "string",
"example": "Project can't be blank."
}
}
}
404
Returned if the principal or the rate does not exist, or the requesting user may not see it.
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
"message": "The requested resource could not be found."
}
ErrorResponse{
"type": "object",
"required": [
"_type",
"errorIdentifier",
"message"
],
"properties": {
"_embedded": {
"type": "object",
"properties": {
"details": {
"type": "object",
"properties": {
"attribute": {
"type": "string",
"example": "project"
}
}
}
}
},
"_type": {
"type": "string",
"enum": [
"Error"
]
},
"errorIdentifier": {
"type": "string",
"example": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation"
},
"message": {
"type": "string",
"example": "Project can't be blank."
}
}
}