List time registrations for moving hours
Lists the project time registrations in a date range that the caller may move, with filters on customer, project, employee, department and more.
Returns, unpaged, every project time registration whose date lies in [periodStartsAt, periodEndsAt] (both inclusive) on an ACTIVE project the caller can see by project privilege (all projects, or the projects where the caller is project manager / account manager / in the project's department subtree). Twelve ID-list filters each take a comma-separated list and an include (default) / exclude switch; searchText matches customer number and name, project number, name and description, and task name (contains). Each row says whether it is invoiced or in a closed accounting period — those cannot be moved; set hideUnmovableRegistrationsIds to drop them. List Properties: AdditionalCommentFieldName (label of the additional text field, "" when that feature is off), IsShowingProjectNo / IsShowingTaskNo (ProjectNumber / TaskNo features), IsCommentMandatory (MandatoryComment feature) and TotalRegisteredHours (sum of RegisteredHours, a number).
Use it to:
- Find registrations booked on the wrong task before invoicing, to move them with
PUT /v2/adjustments/move-hours
Not for:
- Your own registrations or a paged registration export →
GET /v1/time-registration/{timeRegistrationID}
Behaviour:
- Idempotent.
- Safe to retry.
- Changes are visible to the next read immediately.
Next: PUT /v2/adjustments/move-hours
See also: GET /v2/adjustments/move-hours/projects, GET /v2/projects/{projectId}/time-registrations
Not yet documented: examples; response → empty result.
curl -X GET "https://app3.timelog.com/your-account/api/v2/adjustments/move-hours?periodStartsAt=2024-12-25T10%3A00%3A00Z&periodEndsAt=2024-12-25T10%3A00%3A00Z&searchText=example_string&customerIds=example_string&projectIds=example_string&projectStatusIds=example_string&employeeDepartmentIds=example_string&employeeIds=example_string&projectTypeIds=example_string&projectCategoryIds=example_string&taskTypeIds=example_string&employeeTypeIds=example_string&projectManagerIds=example_string&accountManagerIds=example_string&projectDepartmentIds=example_string&contractTypeIds=example_string&is…Inclusive (13 switches)=true&hideUnmovableRegistrationsIds=false&hideNonBillableIds=false" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN"
import requests
import json
url = "https://app3.timelog.com/your-account/api/v2/adjustments/move-hours?periodStartsAt=2024-12-25T10%3A00%3A00Z&periodEndsAt=2024-12-25T10%3A00%3A00Z&searchText=example_string&customerIds=example_string&projectIds=example_string&projectStatusIds=example_string&employeeDepartmentIds=example_string&employeeIds=example_string&projectTypeIds=example_string&projectCategoryIds=example_string&taskTypeIds=example_string&employeeTypeIds=example_string&projectManagerIds=example_string&accountManagerIds=example_string&projectDepartmentIds=example_string&contractTypeIds=example_string&is…Inclusive (13 switches)=true&hideUnmovableRegistrationsIds=false&hideNonBillableIds=false"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
}
response = requests.get(url, headers=headers)
print(response.json())
const response = await fetch("https://app3.timelog.com/your-account/api/v2/adjustments/move-hours?periodStartsAt=2024-12-25T10%3A00%3A00Z&periodEndsAt=2024-12-25T10%3A00%3A00Z&searchText=example_string&customerIds=example_string&projectIds=example_string&projectStatusIds=example_string&employeeDepartmentIds=example_string&employeeIds=example_string&projectTypeIds=example_string&projectCategoryIds=example_string&taskTypeIds=example_string&employeeTypeIds=example_string&projectManagerIds=example_string&accountManagerIds=example_string&projectDepartmentIds=example_string&contractTypeIds=example_string&is…Inclusive (13 switches)=true&hideUnmovableRegistrationsIds=false&hideNonBillableIds=false", {
method: "GET",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
}
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"net/http"
)
func main() {
req, err := http.NewRequest("GET", "https://app3.timelog.com/your-account/api/v2/adjustments/move-hours?periodStartsAt=2024-12-25T10%3A00%3A00Z&periodEndsAt=2024-12-25T10%3A00%3A00Z&searchText=example_string&customerIds=example_string&projectIds=example_string&projectStatusIds=example_string&employeeDepartmentIds=example_string&employeeIds=example_string&projectTypeIds=example_string&projectCategoryIds=example_string&taskTypeIds=example_string&employeeTypeIds=example_string&projectManagerIds=example_string&accountManagerIds=example_string&projectDepartmentIds=example_string&contractTypeIds=example_string&is…Inclusive (13 switches)=true&hideUnmovableRegistrationsIds=false&hideNonBillableIds=false", nil)
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_API_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Response Status:", resp.Status)
}
require 'net/http'
require 'json'
uri = URI('https://app3.timelog.com/your-account/api/v2/adjustments/move-hours?periodStartsAt=2024-12-25T10%3A00%3A00Z&periodEndsAt=2024-12-25T10%3A00%3A00Z&searchText=example_string&customerIds=example_string&projectIds=example_string&projectStatusIds=example_string&employeeDepartmentIds=example_string&employeeIds=example_string&projectTypeIds=example_string&projectCategoryIds=example_string&taskTypeIds=example_string&employeeTypeIds=example_string&projectManagerIds=example_string&accountManagerIds=example_string&projectDepartmentIds=example_string&contractTypeIds=example_string&is…Inclusive (13 switches)=true&hideUnmovableRegistrationsIds=false&hideNonBillableIds=false')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Content-Type'] = 'application/json'
request['Authorization'] = 'Bearer YOUR_API_TOKEN'
response = http.request(request)
puts response.body
{
"Entities": [
{
"Properties": {
"Id": "123e4567-e89b-12d3-a456-426614174000",
"TimeRegistrationId": 123,
"Date": "2024-12-25T10:00:00Z",
"EmployeeInitials": "example_string",
"EmployeeName": "John Doe",
"ProjectId": 123,
"ProjectName": "John Doe",
"ProjectNo": "null",
"TaskId": 123,
"TaskName": "John Doe",
"TaskFullName": "null",
"TaskNo": "example_string",
"Wbs": "null",
"RegisteredHours": 3.14,
"InvoiceLineId": 123,
"InvoiceId": 123,
"IsInvoiced": true,
"Comment": "example_string",
"AdditionalText": "null",
"AccountingPeriodId": 123,
"IsInClosedAccountingPeriod": true
},
"Links": [
{
"Href": "example_string",
"Rel": "example_string"
}
],
"Actions": [
{}
]
}
],
"Links": [
{
"Href": "example_string",
"Rel": "example_string"
}
]
}
{
"error": "Bad Request",
"message": "The request contains invalid parameters or malformed data",
"code": 400,
"details": [
{
"field": "email",
"message": "Invalid email format"
}
]
}
{
"error": "Unauthorized",
"message": "Authentication required. Please provide a valid API token",
"code": 401
}
{
"error": "Not Found",
"message": "The requested resource was not found",
"code": 404
}
{
"error": "Internal Server Error",
"message": "An unexpected error occurred on the server",
"code": 500,
"requestId": "req_1234567890"
}
/v2/adjustments/move-hours
Target server for requests. Edit to use your own host.
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.
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.First date (inclusive). Omitted → 404 action not matched (captured).
Filters on MoveHoursRead.Date (gte).
Last date (inclusive; compared with the registration's date at midnight, so pass the day itself). Omitted → 404 (captured).
Filters on MoveHoursRead.Date (lte).
Contains-match (LIKE %x%, OR) on customer number, customer name, project number, project name, project description and task name. Not on employee or comment.
Filters on MoveHoursRead.ProjectName (contains).
Customer IDs; with isCustomerInclusive (default true) false = exclude them.
Several values: one string, separated by ,.
Filters on customer of the project (in).
Project IDs; isProjectInclusive (default true).
Several values: one string, separated by ,.
Filters on MoveHoursRead.ProjectId (in).
PAGE-FILTER status codes, not StatusId: 1 Quote, 2 Approved, 3 InProgress, 4 OnHold, 5 Completed, 6 Archived, 7 Cancelled; groups -1 active (Quote..OnHold), -2 inactive (Completed, Archived, Cancelled), -3 all. isProjectStatusInclusive (default true).
Several values: one string, separated by ,.
Filters on project status (in).
Department IDs of the registering employee, sub-departments included; isEmployeeDepartmentInclusive.
Several values: one string, separated by ,.
Filters on employee department (with sub-departments) (in).
USER IDs, not employee IDs; isEmployeeInclusive.
Several values: one string, separated by ,.
Filters on registration owner (USER ID) (in).
isProjectTypeInclusive.
Several values: one string, separated by ,.
Filters on project type (in).
isProjectCategoryInclusive.
Several values: one string, separated by ,.
Filters on project category (in).
Switch is named isProjectTaskTypesInclusive.
Several values: one string, separated by ,.
Filters on task type (in).
isEmployeeTypeInclusive.
Several values: one string, separated by ,.
Filters on employee type (role) (in).
isProjectManagerInclusive.
Several values: one string, separated by ,.
Filters on project manager (employee ID) (in).
isAccountManagerInclusive.
Several values: one string, separated by ,.
Filters on account manager (employee ID) (in).
isProjectDepartmentInclusive.
Several values: one string, separated by ,.
Filters on project department (with sub-departments) (in).
Contract MODEL types; isContractTypeInclusive.
Several values: one string, separated by ,.
Filters on contract model of the task's contract (in).
One per list above (isCustomerInclusive, isProjectInclusive, isProjectStatusInclusive, isEmployeeDepartmentInclusive, isEmployeeInclusive, isProjectTypeInclusive, isProjectCategoryInclusive, isProjectTaskTypesInclusive, isEmployeeTypeInclusive, isProjectManagerInclusive, isAccountManagerInclusive, isProjectDepartmentInclusive, isContractTypeInclusive): true = keep only matching rows, false = drop matching rows. Ignored when its list is empty.
Filters on the ID list it belongs to (include / exclude) (in).
true = drop invoiced registrations and registrations dated in a closed accounting period. Approval / timesheet state is not considered.
Filters on MoveHoursRead.IsInvoiced / IsInClosedAccountingPeriod (eq).
true = drop non-billable registrations. Ignored unless the BillableOnTime feature is on.
Filters on registration NonBillable flag (eq).
Request Preview
Response
Response will appear here after sending the request
Authentication
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
First date (inclusive). Omitted → 404 action not matched (captured).
Filters on MoveHoursRead.Date (gte).
Last date (inclusive; compared with the registration's date at midnight, so pass the day itself). Omitted → 404 (captured).
Filters on MoveHoursRead.Date (lte).
Contains-match (LIKE %x%, OR) on customer number, customer name, project number, project name, project description and task name. Not on employee or comment.
Filters on MoveHoursRead.ProjectName (contains).
Customer IDs; with isCustomerInclusive (default true) false = exclude them.
Several values: one string, separated by ,.
Filters on customer of the project (in).
Project IDs; isProjectInclusive (default true).
Several values: one string, separated by ,.
Filters on MoveHoursRead.ProjectId (in).
PAGE-FILTER status codes, not StatusId: 1 Quote, 2 Approved, 3 InProgress, 4 OnHold, 5 Completed, 6 Archived, 7 Cancelled; groups -1 active (Quote..OnHold), -2 inactive (Completed, Archived, Cancelled), -3 all. isProjectStatusInclusive (default true).
Several values: one string, separated by ,.
Filters on project status (in).
Department IDs of the registering employee, sub-departments included; isEmployeeDepartmentInclusive.
Several values: one string, separated by ,.
Filters on employee department (with sub-departments) (in).
USER IDs, not employee IDs; isEmployeeInclusive.
Several values: one string, separated by ,.
Filters on registration owner (USER ID) (in).
isProjectTypeInclusive.
Several values: one string, separated by ,.
Filters on project type (in).
isProjectCategoryInclusive.
Several values: one string, separated by ,.
Filters on project category (in).
Switch is named isProjectTaskTypesInclusive.
Several values: one string, separated by ,.
Filters on task type (in).
isEmployeeTypeInclusive.
Several values: one string, separated by ,.
Filters on employee type (role) (in).
isProjectManagerInclusive.
Several values: one string, separated by ,.
Filters on project manager (employee ID) (in).
isAccountManagerInclusive.
Several values: one string, separated by ,.
Filters on account manager (employee ID) (in).
isProjectDepartmentInclusive.
Several values: one string, separated by ,.
Filters on project department (with sub-departments) (in).
Contract MODEL types; isContractTypeInclusive.
Several values: one string, separated by ,.
Filters on contract model of the task's contract (in).
One per list above (isCustomerInclusive, isProjectInclusive, isProjectStatusInclusive, isEmployeeDepartmentInclusive, isEmployeeInclusive, isProjectTypeInclusive, isProjectCategoryInclusive, isProjectTaskTypesInclusive, isEmployeeTypeInclusive, isProjectManagerInclusive, isAccountManagerInclusive, isProjectDepartmentInclusive, isContractTypeInclusive): true = keep only matching rows, false = drop matching rows. Ignored when its list is empty.
Filters on the ID list it belongs to (include / exclude) (in).
true = drop invoiced registrations and registrations dated in a closed accounting period. Approval / timesheet state is not considered.
Filters on MoveHoursRead.IsInvoiced / IsInClosedAccountingPeriod (eq).
true = drop non-billable registrations. Ignored unless the BillableOnTime feature is on.
Filters on registration NonBillable flag (eq).
Responses
Omitted (not []) when the list is empty.