ProjectsMove time registrations to another task

Move time registrations to another task

Moves one or more project time registrations to another task (of any project), keeping each registration's ID, hours and date.

For each ID in timeRegistrationIds, in order, the registration is re-pointed to TargetTaskId: the employee is allocated to the target task when not yet allocated, the registration's allocation (and so its rate) changes, billable duration is re-evaluated (billable-hours / rounding features), and the registration is saved in place — same TimeRegistrationId, GUID, hours, date, comment, factor and approval status (a rejected one becomes "rejected and resolved"). Attached mileage keeps its project and only its registration reference is updated; a running time tracker on the registration is notified as deleted. Refused per registration: absence registrations, target project Cancelled / Archived, target task closed or a parent task, invoiced, on a draft invoice, dated in a closed accounting period, outside the employee's employment, missing mandatory comment / additional text, exceeding allocated hours (feature). A closed (approved) timesheet does NOT block a move. Answers 204 when every registration moved, otherwise 422 with a bare array of MoveHoursResultRead (one entry per ID — moved ones included, and they STAY moved). An unknown or non-integer ID aborts the loop with 500 after earlier IDs were moved.

Use it to:

  • Correct registrations booked on the wrong task or project before invoicing

Not for:

  • Changing hours, date or comment → PUT /v1/time-registration

Behaviour:

  • Idempotent.
  • Moving a registration to the task it is already on re-saves it unchanged in substance.
  • Safe to retry only under a condition. Yes after a 422 or 500 — re-read the registrations first (moved ones are already on the target) and resend the rest.
  • Duplicates: A duplicated ID is moved twice (second time a no-op move).
  • Side effect: Per registration: allocation on the target task created when missing; registration re-pointed to it (rate of the target allocation applies); billable duration re-evaluated.
  • Side effect: A running time tracker on the registration is notified as deleted.
  • On failure: Registrations before the failing ID stay moved (422 array, or 500 with no per-item result).
  • On failure: An allocation created on the target task can remain even when the move is then refused by a later rule.
  • Changes are visible to the next read immediately.
  • Batch: Sequential; each registration in its own transaction; refusals are collected (422), any other error aborts the remainder (500).

Call first: GET /v2/adjustments/move-hours, GET /v2/adjustments/move-hours/projects/{projectId}/tasks

Next: GET /v2/adjustments/move-hours

See also: PUT /v1/time-registration

Not yet documented: behaviour → side effects on failure; examples.

curl -X PUT "https://app3.timelog.com/your-account/api/v2/adjustments/move-hours?timeRegistrationIds=example_string" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -d '{
  "TargetTaskId": 123
}'
{}
PUT
/v2/adjustments/move-hours
PUT
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.
query
timeRegistrationIdsstring
Required

Comma-separated integer TimeRegistrationIds, processed in order. Omitted → 404 action not matched (captured). Unknown or non-integer entry → 500 after earlier entries were moved. Several values: one string, separated by ,.

Content-Typestring
Required

The media type of the request body

Options: application/json
TargetTaskIdinteger
Required

The task to move the registrations to — any task of any project; the registration's employee is allocated to it automatically when not yet allocated. The task must be open, not a parent task, and on a project that is neither Cancelled nor Archived (checked per registration; a violation is reported per ID in the 422 array). Refers to TaskRead.TaskID. Look up valid values with GET /v2/adjustments/move-hours/projects/{projectId}/tasks. - Omitted or 0 / negative — Validator GreaterThan(0) — 400 Invalid model state. Valid values come from GET /v2/adjustments/move-hours/projects/{projectId}/tasks.

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.

Query Parameters

timeRegistrationIdsstring
Required

Comma-separated integer TimeRegistrationIds, processed in order. Omitted → 404 action not matched (captured). Unknown or non-integer entry → 500 after earlier entries were moved.

Several values: one string, separated by ,.

Body

application/json
TargetTaskIdinteger
Required

The task to move the registrations to — any task of any project; the registration's employee is allocated to it automatically when not yet allocated. The task must be open, not a parent task, and on a project that is neither Cancelled nor Archived (checked per registration; a violation is reported per ID in the 422 array).

Refers to TaskRead.TaskID. Look up valid values with GET /v2/adjustments/move-hours/projects/{projectId}/tasks.

  • Omitted or 0 / negative — Validator GreaterThan(0) — 400 Invalid model state.

Valid values come from GET /v2/adjustments/move-hours/projects/{projectId}/tasks.

Responses