Skip to main content

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.

PATCH/api/integrations/external/estimates/time-tracker/{projectId}/task/{taskId}

Update an operation or activity in the project's time tracker

Path Parameters

NameTypeRequiredDescription
projectIdstring (UUID)The project / estimate identifier
taskIdstring (UUID)The time-tracker item identifier (operation or activity)

Headers

NameValueDescription
apikeyYOUR_API_KEYYour Forecast API authentication key
Content-Typeapplication/jsonMust 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.

FieldTypeAllowed on OperationAllowed on ActivityDescription
namestring (non-empty)Display name of the task
estimatenumber | nullEditable estimate, in hours
actualnumber | nullRecorded actual, in hours
actualDepthnumber | nullRecorded 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): only name may be patched, and name must be the only key in the body. Sending name plus anything else, or any field other than name, returns:

    Operation update not allowed. Only "name" property can be edited.
  • Activity (parentId set to an operation's timeTrackerItemId): any subset of name, estimate, actual, actualDepth is 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 operationname 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:

  1. Fetches the project's last active simulation result.
  2. Recomputes the parent operation's start / finish times so that the operation's window still reflects the sum of its activities.
  3. 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 null for estimate, actual, or actualDepth clears the field (these accept ["number", "null"]).
  • name must be a non-empty string; the empty string is treated as missing and fails the "at least one property" check.
  • The taskId returned in the response is always the value you supplied in the URL.