Projects

Update a project budget

Changes the budget a project already tracks. Every field is optional, and anything you leave out keeps its current value. None of them can be cleared, so null or an empty string returns 422; to stop tracking the budget, use DELETE /public-api/v1/projects/{id}/budget. Keys other than the ones below are ignored.

calculation_mode sets the unit of every number in the budget: fee counts money in the project's currency, time counts hours. Changing it does not convert amount — "40" stays 40, read in the new unit — so send the new amount in the same request.

calculation_base has to be one the budget's mode can count. The check runs on the budget as it will be saved, not only on what you sent, so moving a fee budget based on expenses to time means sending a time base with it:

calculation_modecalculation_base
feebillable_time, billable_time_and_expenses, expenses
timebillable_time, non_billable_time, billable_and_non_billable_time

Changing reset_frequency rebuilds the budget's cycles from the project start date, and current_cycle in the response is the rebuilt one. Any other change keeps the cycles and recounts them in the background, so current_cycle can still show the figures from before the change; read the project again to see the new ones.

A request that changes nothing returns 200 with the budget as it is. The project needs a start_date; set one with PATCH /public-api/v1/projects/{id} first.

A project the token cannot see returns 404, and so does one with no budget; start one with POST /public-api/v1/projects/{id}/budget. A project it can see returns 403 when the token may not change the project or see its budget, or when the plan does not include budgets.

patch/public-api/v1/projects/{project_id}/budget

Request

  • Base URL
    https://app.hellobonsai.com
  • URL
    https://app.hellobonsai.com/public-api/v1/projects/{project_id}/budget
  • Auth
    • OAuth 2
      Authorization code: https://app.hellobonsai.com/oauth/authorize
      Token URL: https://app.hellobonsai.com/oauth/token
    • or HTTP bearer

Request body

Example request

{
  "budget": {
    "calculation_mode": "time",
    "amount": "40",
    "calculation_base": "billable_and_non_billable_time",
    "expenses_calculation_base": "billable",
    "reset_frequency": "monthly",
    "over_budget_notification": "enabled",
    "over_budget_notification_threshold": "80"
  }
}

Response

The budget was updated, or already had these values.

Example response

{
  "data": {
    "id": 41,
    "amount": "5000.0",
    "over_budget_notification_threshold": "80.0",
    "calculation_mode": "fee",
    "calculation_base": "billable_time_and_expenses",
    "expenses_calculation_base": "all",
    "reset_frequency": "monthly",
    "over_budget_notification": "enabled",
    "current_cycle": {
      "opening_date": "2026-03-01",
      "closing_date": "2026-03-31",
      "consumed_amount": "1250.0",
      "consumed_percentage": 25
    }
  },
  "meta": {
    "request_id": "b1f0d2c4-7a9e-4c3b-8d5f-1e2a3b4c5d6e"
  }
}

Changes

No recorded changes to this operation across all 1 revision of this API.