Time Entries

Update a time entry

Updates a logged time entry. Every field is optional, and anything you leave out keeps its current value.

Move the entry between projects or tasks with project_id and task_uuid. Sending task_uuid also settles the project — it is taken from the task, and any project_id you send is ignored. Send either as null to detach.

Moving the entry to a different project recalculates rate and non_billable from the new project unless you set them yourself.

As on creation, rate and non_billable are only honoured for a token allowed to set billing, and reassigning owner_member_id to somebody else needs permission to manage the whole team's time.

An entry already billed on a paid or in-progress invoice is frozen: editing it fails with 422 not_accessible. Remove the invoice line item first if you need to change it.

Set billing_status to billed or unbilled to move the entry's billing state. It is only honoured for a token allowed to set billing, and a token without that permission gets 422 not_accessible rather than a silent no-op. non_billable is not a writable value here — use the non_billable flag instead.

Marking an entry billed requires it to be on a project and billable, and fails with 422 invalid_value otherwise. Moving a billed entry out of billed indirectly — by clearing its project or task, or by moving it to a non-billable project — needs the same billing permission and fails with 422 not_accessible without it. An entry attached to an invoice cannot be moved in either direction and fails with 422 not_accessible. Repeating billed re-stamps the entry with the current time, matching the bulk action in the app; repeating unbilled on an already-unbilled entry changes nothing. A request that only sets billing_status is accepted on a locked timesheet, matching the app's mark-as-billed action.

status and billing_status answer different questions. status tracks whether the entry sits on an invoice, so an entry you mark billed by hand keeps status: unbilled while billing_status reads billed.

patch/public-api/v1/time_entries/{key}

Request

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

Path parameters

keystring required

The entry's key, as returned in a time entry response.

Request body

Example request

{
  "time_entry": {
    "seconds": 5400,
    "date": "2026-06-17",
    "project_id": 51,
    "task_uuid": "ad3fdad8-5072-46df-8800-bb57299179df",
    "notes": "Homepage build",
    "rate": "150.00",
    "billing_status": "billed"
  }
}

Response

The time entry was updated.

Example response

{
  "data": {
    "key": "01JTR8Z9K5QW3M7VX4YB2NC6HD",
    "seconds": 3600,
    "date": "2026-06-17",
    "notes": "Homepage build",
    "rate": "150.0",
    "billable_amount": "150.0",
    "status": "unbilled",
    "project_id": 51,
    "owner_member_id": 314,
    "created_at": "2026-04-14T09:12:04.000Z",
    "billing_status": "unbilled",
    "currency": "USD",
    "formatted_time": "01:00:00",
    "task_uuid": "ad3fdad8-5072-46df-8800-bb57299179df"
  },
  "meta": {
    "request_id": "b1f0d2c4-7a9e-4c3b-8d5f-1e2a3b4c5d6e"
  }
}

Changes

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