Update Time Tracker Task
Patch a single task in the time tracker — either an operation (top-level item, parentId === null) or an activity (child of an operation). The set of fields you may change depends on which type of task :taskId resolves to.
When you change an activity's estimate or actual, the parent operation's start/finish times are automatically resynced from the project's last active simulation result.
Update an operation or activity in the project's time tracker
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
projectId | string (UUID) | ✓ | The project / estimate identifier |
taskId | string (UUID) | ✓ | The time-tracker item identifier (operation or activity) |
Headers
| Name | Value | Description |
|---|---|---|
apikey | YOUR_API_KEY | Your Forecast API authentication key |
Content-Type | application/json | Must be application/json |
Request Body
At least one of name / estimate / actual / actualDepth. Operations only accept name; activities accept all four.
Request body fields
The body is a flat object. At least one of the four fields below must be present; an empty {} is rejected.
| Field | Type | Allowed on Operation | Allowed on Activity | Description |
|---|---|---|---|---|
name | string (non-empty) | ✓ | ✓ | Display name of the task |
estimate | number | null | ✗ | ✓ | Editable estimate, in hours |
actual | number | null | ✗ | ✓ | Recorded actual, in hours |
actualDepth | number | null | ✗ | ✓ | Recorded actual depth |
Any field not listed above is rejected with additionalProperties: false.
Operation vs. activity rules
The server looks up :taskId, then enforces the type-specific rules:
-
Operation (
parentId === null): onlynamemay be patched, andnamemust be the only key in the body. Sendingnameplus anything else, or any field other thanname, returns:Operation update not allowed. Only "name" property can be edited. -
Activity (
parentIdset to an operation'stimeTrackerItemId): any subset ofname,estimate,actual,actualDepthis accepted.
Validation errors
The endpoint returns 400 Bad Request for three distinct cases:
1. Empty body or no recognised field
{
"msg": "Bad Request. Validation failed.",
"errorMessages": [
"Payload must provide value for at least one of the expected properties."
],
"statusCode": 400
}
2. Unknown field in body (anything other than name, estimate, actual, actualDepth) — same shape as above, with an additionalProperties message.
3. Forbidden field on an operation — name plus any other key, or any non-name key, when :taskId resolves to an operation:
{
"msg": "Operation update not allowed. Only \"name\" property can be edited.",
"statusCode": 400
}
Resync behavior
Whenever the request body contains estimate or actual, the server:
- Fetches the project's last active simulation result.
- Recomputes the parent operation's
start/finishtimes so that the operation's window still reflects the sum of its activities. - Persists the resynced times alongside your patch.
Updates to name or actualDepth only do not trigger a resync.
Notes
- The response is intentionally minimal — just
{ "taskId": "<id>" }. To see the updated record in context, re-fetch Get Time Tracker. - Sending
nullforestimate,actual, oractualDepthclears the field (these accept["number", "null"]). namemust be a non-empty string; the empty string is treated as missing and fails the "at least one property" check.- The
taskIdreturned in the response is always the value you supplied in the URL.