EmployeesGet timesheet approval status for a period

Get timesheet approval status for a period

Returns the approval status of every day of a period of one employee's timesheet, plus an aggregated period status.

Computes ApprovalTimesheetDayRead for each day from startDate to endDate (inclusive) and wraps them in an ApprovalTimesheetPeriodRead with PeriodStatus and, when the period has rejected days, the latest rejection comment. PeriodStatus is a mechanical aggregate that can mislead — decide on WeekDays, not on PeriodStatus.

Use it to:

  • Payroll cut-off: confirm every day of a pay period is Approved before exporting hours (check each WeekDays entry).
  • Show an employee which days of the month still need submitting or fixing.

Not for:

  • ISO weeks — GET /v1/approval/timesheets/get-status-by-week-of-year computes the Monday–Sunday range for you.

Behaviour:

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

Call first: GET /v1/user

Next: POST /v1/approval/timesheets/submit-period, POST /v1/approval/timesheets/resubmit-rejected-time-registrations

See also: GET /v1/approval/timesheets/get-status-by-dates, GET /v1/approval/timesheets/get-status-by-week-of-year

Not yet documented: examples (success).

curl -X GET "https://app3.timelog.com/your-account/api/v1/approval/timesheets/get-status-by-period?employeeUserId=123&startDate=2024-12-25T10%3A00%3A00Z&endDate=2024-12-25T10%3A00%3A00Z&$expand=RejectedRegistrations&$page=25&$pagesize=25" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
{
  "Properties": {
    "WeekDays": [
      {
        "ApprovalStatus": "Empty",
        "Hours": 3.14,
        "Date": "2024-12-25T10:00:00Z",
        "LastRejectedComment": "null",
        "RecentRejectedComment": {
          "ManagerName": "null",
          "ManagerComment": "example_string"
        },
        "RejectedRegistrations": [
          {
            "CustomerID": "null",
            "CustomerName": "John Doe",
            "CustomerNo": "example_string",
            "ProjectID": "null",
            "ProjectName": "John Doe",
            "ProjectNo": "example_string",
            "TaskID": "null",
            "TaskName": "John Doe",
            "TaskFullName": "John Doe",
            "IsFixedPrice": "null",
            "TaskNo": "example_string",
            "TaskIsActive": "null",
            "AbsenceCodeID": "null",
            "AbsenceName": "John Doe",
            "AbsenceCode": "example_string",
            "AbsenceIsActive": "null",
            "AdditionalTextIsRequired": true,
            "DefaultBillable": true,
            "IsETCProject": true,
            "ShowBillable": true,
            "AllocatedHour": "null",
            "TimeRegistrationID": 123,
            "EntityID": 123,
            "EntityType": 42,
            "UserID": 123,
            "Created": "2024-12-25T10:00:00Z",
            "CreatedBy": 42,
            "LastModified": "2024-12-25T10:00:00Z",
            "LastModifiedBy": 42,
            "IsBillable": true,
            "Status": true,
            "Date": "2024-12-25T10:00:00Z",
            "MonthlyPeriod": "example_string",
            "Comment": "example_string",
            "Hours": 3.14,
            "AdditionalTextField": "example_string",
            "InvoiceStatus": true,
            "TimeRegistrationApprovalStatus": 42,
            "TimeTrackingFormat": 42,
            "Minutes": 42,
            "BillableHours": 3.14,
            "BillableMinutes": 42,
            "IsFavourite": true,
            "StartTime": "null",
            "EndTime": "null",
            "IsTimestampOverlapping": true
          }
        ],
        "HasResubmittedRejectedRegistration": true
      }
    ],
    "PeriodStatus": "Empty",
    "LastRejectedComment": "null",
    "RecentRejectedComment": {
      "ManagerName": "null",
      "ManagerComment": "example_string"
    }
  },
  "Links": [
    {
      "Href": "example_string",
      "Rel": "example_string"
    }
  ],
  "Actions": [
    {}
  ]
}
GET
/v1/approval/timesheets/get-status-by-period
GET
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
employeeUserIdinteger
Required

User ID of the employee. Omitted -> 404 action-not-matched. Refers to UserRead.UserID. Look up valid values with GET /v1/user.

Format: int32
query
startDatestring
Required

First day, inclusive. Omitted -> 404 action-not-matched.

Format: date-time
query
endDatestring
Required

Last day, inclusive. Before startDate -> 200 with no WeekDays and PeriodStatus Open.

Format: date-time
query
$expandstring

Expansion of the per-day rejected registrations. Allowed values: | Value | Name | Meaning | |---|---|---| | RejectedRegistrations | RejectedRegistrations | Fill RejectedRegistrations on each Rejected day (case-insensitive; other values ignored). |

Options: RejectedRegistrations
query
$pageinteger

Not a response pager: applied to each Rejected day's RejectedRegistrations list.

query
$pagesizeinteger

Page size of each Rejected day's RejectedRegistrations list.

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

employeeUserIdinteger
Required

User ID of the employee. Omitted -> 404 action-not-matched.

Refers to UserRead.UserID. Look up valid values with GET /v1/user.

startDatestring
Required

First day, inclusive. Omitted -> 404 action-not-matched.

endDatestring
Required

Last day, inclusive. Before startDate -> 200 with no WeekDays and PeriodStatus Open.

$expandstring

Expansion of the per-day rejected registrations.

Allowed values:

ValueNameMeaning
RejectedRegistrationsRejectedRegistrationsFill RejectedRegistrations on each Rejected day (case-insensitive; other values ignored).
Allowed values:RejectedRegistrations
$pageinteger

Not a response pager: applied to each Rejected day's RejectedRegistrations list.

$pagesizeinteger

Page size of each Rejected day's RejectedRegistrations list.

Responses

Propertiesobject

The approval state of a run of consecutive days of one employee's timesheet (a period or an ISO week): every day's status in WeekDays plus one aggregated PeriodStatus. No ID: identified by (employee, first day, last day).

Linksarray
Actionsobject[]