ProjectsValidate a task update (dry run)

Validate a task update (dry run)

Checks whether a task update would be accepted, without saving anything.

Same path and body as PUT /v1/task/{taskID}. It does not run what the update does after its dry-run stage: the status change's own processing and the project save rules (WBS structure, project time-tracking status), so a 200 does not fully guarantee the update.

Use it to:

  • Pre-check a batch of task changes from an external plan before applying them

Not for:

  • Applying the change → PUT /v1/task/{taskID}

Rules across fields:

  • R1: When both dates are sent, EndDate must be on or after StartDate (400 Code 200).
  • R2: BudgetHours and BudgetAmount may not both be sent when an hourly rate drives the task's budget (400).

Behaviour:

  • Idempotent.
  • Safe to retry.
  • Changes are visible to the next read immediately.

Call first: GET /v1/task

Next: PUT /v1/task/{taskID}

See also: POST /v1/task/validate-new-task

Not yet documented: examples; purpose → description.

curl -X POST "https://app3.timelog.com/your-account/api/v1/task/123/validate-update-task" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -d '{
  "TaskName": "null",
  "TaskNo": "null",
  "Description": "null",
  "StartDate": "null",
  "EndDate": "null",
  "AdditionalTextIsRequired": "null",
  "BudgetHours": "null",
  "BudgetAmount": "null",
  "HourlyRateID": "null",
  "TaskTypeID": "null",
  "Status": "null",
  "ParentTaskID": "null"
}'
"null"
POST
/v1/task/{taskID}/validate-update-task
POST
Base URLstring

Target server for requests. Edit to use your own host.

Bearer Token
Bearer Tokenstring
Required

OAuth 2.0 bearer token, sent as Authorization: Bearer <token>. JWT and reference tokens are both accepted. The token must carry the required scope (default tlp). The token's sub claim is the acting user. A token WITHOUT sub (client-credentials) acts as the system service user. If the sub user cannot log in (inactive, locked, deleted), the request is rejected with 401 — it is no longer let through without a user. > Not yet documented: how to obtain a token. > Not yet documented: token lifetime.

OAuth 2.0 bearer token, sent as Authorization: Bearer <token>. JWT and reference tokens are both accepted. The token must carry the required scope (default tlp). The token's sub claim is the acting user. A token WITHOUT sub (client-credentials) acts as the system service user. If the sub user cannot log in (inactive, locked, deleted), the request is rejected with 401 — it is no longer let through without a user. > Not yet documented: how to obtain a token. > Not yet documented: token lifetime.
path
taskIDinteger
Required

The task to check. Route constraint :int.

Format: int32
Content-Typestring
Required

The media type of the request body

Options: application/json
TaskNamestringnull

New display name of the task. Null: null / omitted = unchanged; there is no way to clear the name. - Sent as empty string — 400 'TaskName cannot be empty when supplied.' > Not yet documented: constraints → max length.

Min length: 1
TaskNostringnull

New task number. Null: null / omitted = unchanged. - The account's task-number setting auto-generates or hides task numbers — Passed to Task.ChangeNo with the ShowTaskNo setting; per the model's comment the value is then ignored. > Not yet documented: behaviour.

Descriptionstringnull

New free-text description. Null: null / omitted = unchanged. An empty string clears it.

StartDatestringnull

New planned start of the task. Null: null / omitted = unchanged. Time zone: not yet documented. - Not a valid date (e.g. 0001-01-01) — 400 'StartDate is not a valid date.' - After the stored EndDate (EndDate not sent) — Not checked by the body validator; left to the task rules (task.Validate / save rules) — 400 from the controller. > Not yet documented: constraints → timezone. > Not yet documented: behaviour.

Format: date-time
EndDatestringnull

New planned end of the task. Null: null / omitted = unchanged. Time zone: not yet documented. - Not a valid date — 400 'EndDate is not a valid date.'. - Both dates sent and EndDate < StartDate — 400 'EndDate must be equal to or greater than StartDate.' > Not yet documented: constraints → timezone.

Format: date-time
AdditionalTextIsRequiredbooleannull

When true, time registrations on this task must carry an additional comment. Null: null / omitted = unchanged.

BudgetHoursnumbernull

New budgeted hours of the task. Null: null / omitted = unchanged. Unit: hours - Negative — 400 (>= 0). - BudgetAmount also sent and an hourly rate drives the budget (time & material or Allocated rate model with HourlyRateID > 0; fixed price Calculated with a task hourly rate > 0) — 400 'BudgetHours and BudgetAmount cannot both be supplied when an hourly rate applies to the task…'. > Not yet documented: behaviour.

Format: double
BudgetAmountnumbernull

New budgeted revenue of the task. Null: null / omitted = unchanged. Unit: project currency - Negative — 400 (>= 0). - BudgetHours also sent and an hourly rate drives the budget — 400 (see BudgetHours). > Not yet documented: behaviour.

Format: double
HourlyRateIDintegernull

New contract hourly rate of the task; 0 = the default hourly rate. Refers to ContractHourlyRateID. Null: null / omitted = unchanged. - Negative — 400 (>= 0). - Changed, fixed-price contract with the Calculated rate model — ChangeHourlyRateId does nothing for this case, yet the call answers 200 (an existence check still runs for > 0). - Applied BEFORE the budget fields — The adapter applies HourlyRateID first, so BudgetHours / BudgetAmount in the same request are judged against the NEW rate. > Not yet documented: values → lookup op.

Format: int32
TaskTypeIDintegernull

New task type (classification). Refers to TaskTypeRead.TaskTypeID. Null: null / omitted = unchanged. 0 is rejected, so a task type cannot be removed through this body. - 0 or negative — 400 (> 0). > Not yet documented: values → lookup op. > Not yet documented: behaviour.

Format: int32
Statusintegernull

New status of the task. Completed and Cancelled close it for time registration. Null: null / omitted = unchanged. - Not a member — 400. - Planning task and a status other than NotStarted / Completed — Violation 'A planning task can only be "not started" or "completed"'. - Reopening (from Completed or Cancelled) — Reopens the task's contract when it is closed, sets allocations back to not completed; from Completed also re-opens the task's vouchers. - Parent task (not a contract-sub-group primary) — The status is pushed down to all sub-tasks. Allowed values: | Value | Name | Meaning | |---|---|---| | 0 | NotStarted | Not started. Rejected when the task already has time registrations (Task_ChangeState violation). | | 1 | InProgress | Open and in progress. | | 2 | OnHold | Open, paused. | | 3 | Completed | Closed. | > Not yet documented: values → members → meaning. > Not yet documented: values → members → meaning.

Format: int32 • Options: 0, 1, 2, 3, 4
ParentTaskIDintegernull

Moves the task in the project plan — under this task, or to the root with 0. Refers to TaskRead.TaskID. Look up valid values with GET /v1/task. Null: null / omitted = placement unchanged. 0 = move to the end of the plan's root level. - Negative — 400 (>= 0). - Same as the current parent — No move. - A task of another project — MovedTaskIsUnderSameProject violation (400). - The task itself or one of its descendants — TaskCannotMoveToOwnSubTask violation (400). - A contract sub-group task — 400 'ParentTaskID points at a contract sub group task…' — that move would change the task's contract and payments. - Recurring / ordinary mix, a receiver that cannot become a parent, WBS depth exceeded, contract-sub-group WBS rule, project-level rules — 400 with the violation messages. - Accepted — The move is SAVED on its own (MoveTaskUnderParentTask saves the project) before the other fields; the task keeps its contract (changeToParentContract false) and the old parent's payment is rebuilt. Valid values come from GET /v1/task.

Format: int32
Request Preview
Response

Response will appear here after sending the request

Authentication

header
Authorizationstring
Required

Bearer token. OAuth 2.0 bearer token, sent as Authorization: Bearer <token>. JWT and reference tokens are both accepted. The token must carry the required scope (default tlp).

The token's sub claim is the acting user. A token WITHOUT sub (client-credentials) acts as the system service user. If the sub user cannot log in (inactive, locked, deleted), the request is rejected with 401 — it is no longer let through without a user.

Not yet documented: how to obtain a token.

Not yet documented: token lifetime.

Path Parameters

taskIDinteger
Required

The task to check. Route constraint :int.

Body

application/json
TaskNamestring,null

New display name of the task.

Null: null / omitted = unchanged; there is no way to clear the name.

  • Sent as empty string — 400 'TaskName cannot be empty when supplied.'

Not yet documented: constraints → max length.

TaskNostring,null

New task number.

Null: null / omitted = unchanged.

  • The account's task-number setting auto-generates or hides task numbers — Passed to Task.ChangeNo with the ShowTaskNo setting; per the model's comment the value is then ignored.

Not yet documented: behaviour.

Descriptionstring,null

New free-text description.

Null: null / omitted = unchanged. An empty string clears it.

StartDatestring,null

New planned start of the task.

Null: null / omitted = unchanged.

Time zone: not yet documented.

  • Not a valid date (e.g. 0001-01-01) — 400 'StartDate is not a valid date.'

  • After the stored EndDate (EndDate not sent) — Not checked by the body validator; left to the task rules (task.Validate / save rules) — 400 from the controller.

Not yet documented: constraints → timezone.

Not yet documented: behaviour.

EndDatestring,null

New planned end of the task.

Null: null / omitted = unchanged.

Time zone: not yet documented.

  • Not a valid date — 400 'EndDate is not a valid date.'.

  • Both dates sent and EndDate < StartDate — 400 'EndDate must be equal to or greater than StartDate.'

Not yet documented: constraints → timezone.

AdditionalTextIsRequiredboolean,null

When true, time registrations on this task must carry an additional comment.

Null: null / omitted = unchanged.

BudgetHoursnumber,null

New budgeted hours of the task.

Null: null / omitted = unchanged.

Unit: hours

  • Negative — 400 (>= 0).

  • BudgetAmount also sent and an hourly rate drives the budget (time & material or Allocated rate model with HourlyRateID > 0; fixed price Calculated with a task hourly rate > 0) — 400 'BudgetHours and BudgetAmount cannot both be supplied when an hourly rate applies to the task…'.

Not yet documented: behaviour.

BudgetAmountnumber,null

New budgeted revenue of the task.

Null: null / omitted = unchanged.

Unit: project currency

  • Negative — 400 (>= 0).

  • BudgetHours also sent and an hourly rate drives the budget — 400 (see BudgetHours).

Not yet documented: behaviour.

HourlyRateIDinteger,null

New contract hourly rate of the task; 0 = the default hourly rate.

Refers to ContractHourlyRateID.

Null: null / omitted = unchanged.

  • Negative — 400 (>= 0).

  • Changed, fixed-price contract with the Calculated rate model — ChangeHourlyRateId does nothing for this case, yet the call answers 200 (an existence check still runs for > 0).

  • Applied BEFORE the budget fields — The adapter applies HourlyRateID first, so BudgetHours / BudgetAmount in the same request are judged against the NEW rate.

Not yet documented: values → lookup op.

TaskTypeIDinteger,null

New task type (classification).

Refers to TaskTypeRead.TaskTypeID.

Null: null / omitted = unchanged. 0 is rejected, so a task type cannot be removed through this body.

  • 0 or negative — 400 (> 0).

Not yet documented: values → lookup op.

Not yet documented: behaviour.

Statusinteger,null

New status of the task. Completed and Cancelled close it for time registration.

Null: null / omitted = unchanged.

  • Not a member — 400.

  • Planning task and a status other than NotStarted / Completed — Violation 'A planning task can only be "not started" or "completed"'.

  • Reopening (from Completed or Cancelled) — Reopens the task's contract when it is closed, sets allocations back to not completed; from Completed also re-opens the task's vouchers.

  • Parent task (not a contract-sub-group primary) — The status is pushed down to all sub-tasks.

Allowed values:

ValueNameMeaning
0NotStartedNot started. Rejected when the task already has time registrations (Task_ChangeState violation).
1InProgressOpen and in progress.
2OnHoldOpen, paused.
3CompletedClosed.

Not yet documented: values → members → meaning.

Not yet documented: values → members → meaning.

Allowed values:01234
ParentTaskIDinteger,null

Moves the task in the project plan — under this task, or to the root with 0.

Refers to TaskRead.TaskID. Look up valid values with GET /v1/task.

Null: null / omitted = placement unchanged. 0 = move to the end of the plan's root level.

  • Negative — 400 (>= 0).

  • Same as the current parent — No move.

  • A task of another project — MovedTaskIsUnderSameProject violation (400).

  • The task itself or one of its descendants — TaskCannotMoveToOwnSubTask violation (400).

  • A contract sub-group task — 400 'ParentTaskID points at a contract sub group task…' — that move would change the task's contract and payments.

  • Recurring / ordinary mix, a receiver that cannot become a parent, WBS depth exceeded, contract-sub-group WBS rule, project-level rules — 400 with the violation messages.

  • Accepted — The move is SAVED on its own (MoveTaskUnderParentTask saves the project) before the other fields; the task keeps its contract (changeToParentContract false) and the old parent's payment is rebuilt.

Valid values come from GET /v1/task.

Responses

Success without content: HTTP 200 with the literal JSON body null. The literal null (TafSuccessResult): the update passed the pre-save checks.