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 project link 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_rates permission 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_rates there, or view_own_hourly_rate when 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_rates permission in the rate’s project, or edit_own_hourly_rate in that project when the rate belongs to the requesting user.
  • A default rate requires the global manage_default_hourly_rates permission.
  • 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_rates in 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 them view_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_rates in the linked project, or edit_own_hourly_rate in it when the rate is the requesting user’s own.
  • A default rate requires the global manage_default_hourly_rates permission.

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

Occurs when the client did not send a Content-Type header

"Missing content-type header"
{
  "type": "string"
}

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_rates in at least one project, unless the principal is the requesting user.
  • A project rate additionally requires view_hourly_rates in the project it applies in, or view_own_hourly_rate there 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_rates in the rate’s project, or edit_own_hourly_rate in it when the rate is the requesting user’s own.
  • A default rate requires the global manage_default_hourly_rates permission.

id
integer

required path

Principal id.

Example:
42

rate_id
integer

required path

Hourly rate id.

Example:
1

{
  "rate": 120
}
{
  "_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

Occurs when the client did not send a Content-Type header

"Missing content-type header"
{
  "type": "string"
}

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_rates in the rate’s project, or edit_own_hourly_rate in it when the rate is the requesting user’s own.
  • A default rate requires the global manage_default_hourly_rates permission.

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