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_mode | calculation_base |
|---|---|
| fee | billable_time, billable_time_and_expenses, expenses |
| time | billable_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.
Request
- Base URLhttps://app.hellobonsai.com
- URLhttps://app.hellobonsai.com/public-api/v1/projects/{project_id}/budget
- Auth
- OAuth 2Authorization code: https://app.hellobonsai.com/oauth/authorizeToken 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.