The Timesheet model represents a collection of time entries for a user, used for tracking time.

Property
Required
Type
Description

_id



objectId

Planhat identifier.

approvedBy



objectId

User who approved the timesheet.

status



string

Status of the timesheet. Possible values are: "submitted", "approved", "returned". Default is "submitted".

timeEntries



array

Array of time entries associated with the timesheet.

dateOfApproval



string

Date when the timesheet was approved.

dateFrom



number

Start date of the timesheet period. Number of days since 1970-01-01.

dateTo



number

End date of the timesheet period. Number of days since 1970-01-01.

assignedModel



string

Model which the Timesheet is assigned to. Current supported value is "User".

assignedId



objectId

Id of which the Timesheet is assigned to. Currently only supports User Ids.

The Timesheet model represents a collection of time entries for a user, used for tracking time.

Property
Required
Type
Description

_id



objectId

Planhat identifier.

approvedBy



objectId

User who approved the timesheet.

status



string

Status of the timesheet. Possible values are: "submitted", "approved", "returned". Default is "submitted".

timeEntries



array

Array of time entries associated with the timesheet.

dateOfApproval



string

Date when the timesheet was approved.

dateFrom



number

Start date of the timesheet period. Number of days since 1970-01-01.

dateTo



number

End date of the timesheet period. Number of days since 1970-01-01.

assignedModel



string

Model which the Timesheet is assigned to. Current supported value is "User".

assignedId



objectId

Id of which the Timesheet is assigned to. Currently only supports User Ids.

The Timesheet model represents a collection of time entries for a user, used for tracking time.

Property
Required
Type
Description

_id



objectId

Planhat identifier.

approvedBy



objectId

User who approved the timesheet.

status



string

Status of the timesheet. Possible values are: "submitted", "approved", "returned". Default is "submitted".

timeEntries



array

Array of time entries associated with the timesheet.

dateOfApproval



string

Date when the timesheet was approved.

dateFrom



number

Start date of the timesheet period. Number of days since 1970-01-01.

dateTo



number

End date of the timesheet period. Number of days since 1970-01-01.

assignedModel



string

Model which the Timesheet is assigned to. Current supported value is "User".

assignedId



objectId

Id of which the Timesheet is assigned to. Currently only supports User Ids.

To create a timesheet there are no required fields. The timesheet will be created with the status "submitted", but the date range should be provided in the request body.

Example Request

curl --location -g --request POST 'https://api.planhat.com/timesheets' \
 --header 'Content-Type: application/json' \
 --header 'Authorization: Bearer {{apiToken}}' \
 --data-raw '{
  "timeEntries": [
  {
  "_id": "67d07487557181002fd16d50"
  },
  {
  "_id": "67d07694557181002fd16e1e"
  }
  ],
  "assignedId": "66eb28a6ef8857a5097fbce3",
  "assignedModel": "User",
  "dateFrom": 20156,
  "dateTo": 20163
 }'


Example Response

200 ok

'{
  "timeEntries": [
  "67d07487557181002fd16d50",
  "67d07694557181002fd16e1e"
  ],
  "status": "submitted",
  "assignedModel": "User",
  "_id": "67d078fe557181002fd16f3e",
  "assignedId": "66eb28a6ef8857a5097fbce3",
  "dateFrom": 20156,
  "dateTo": 20163,
  "createdAt": "2025-03-11T17:55:10.313Z",
  "updatedAt": "2025-03-11T17:55:10.313Z",
  "__v": 0
 }'

To create a timesheet there are no required fields. The timesheet will be created with the status "submitted", but the date range should be provided in the request body.

Example Request

curl --location -g --request POST 'https://api.planhat.com/timesheets' \
 --header 'Content-Type: application/json' \
 --header 'Authorization: Bearer {{apiToken}}' \
 --data-raw '{
  "timeEntries": [
  {
  "_id": "67d07487557181002fd16d50"
  },
  {
  "_id": "67d07694557181002fd16e1e"
  }
  ],
  "assignedId": "66eb28a6ef8857a5097fbce3",
  "assignedModel": "User",
  "dateFrom": 20156,
  "dateTo": 20163
 }'


Example Response

200 ok

'{
  "timeEntries": [
  "67d07487557181002fd16d50",
  "67d07694557181002fd16e1e"
  ],
  "status": "submitted",
  "assignedModel": "User",
  "_id": "67d078fe557181002fd16f3e",
  "assignedId": "66eb28a6ef8857a5097fbce3",
  "dateFrom": 20156,
  "dateTo": 20163,
  "createdAt": "2025-03-11T17:55:10.313Z",
  "updatedAt": "2025-03-11T17:55:10.313Z",
  "__v": 0
 }'

To create a timesheet there are no required fields. The timesheet will be created with the status "submitted", but the date range should be provided in the request body.

Example Request

curl --location -g --request POST 'https://api.planhat.com/timesheets' \
 --header 'Content-Type: application/json' \
 --header 'Authorization: Bearer {{apiToken}}' \
 --data-raw '{
  "timeEntries": [
  {
  "_id": "67d07487557181002fd16d50"
  },
  {
  "_id": "67d07694557181002fd16e1e"
  }
  ],
  "assignedId": "66eb28a6ef8857a5097fbce3",
  "assignedModel": "User",
  "dateFrom": 20156,
  "dateTo": 20163
 }'


Example Response

200 ok

'{
  "timeEntries": [
  "67d07487557181002fd16d50",
  "67d07694557181002fd16e1e"
  ],
  "status": "submitted",
  "assignedModel": "User",
  "_id": "67d078fe557181002fd16f3e",
  "assignedId": "66eb28a6ef8857a5097fbce3",
  "dateFrom": 20156,
  "dateTo": 20163,
  "createdAt": "2025-03-11T17:55:10.313Z",
  "updatedAt": "2025-03-11T17:55:10.313Z",
  "__v": 0
 }'

To update a timesheet it's required to pass the timesheet _id in the request URL as a parameter.

Example Request

curl --location -g --request PUT 'https://api.planhat.com/timesheets/67d078fe557181002fd16f3e' \
 --header 'Content-Type: application/json' \
 --header 'Authorization: Bearer {{apiToken}}' \
 --data-raw '{
  "status": "approved"
 }'


Example Response

200 ok

'{
  "_id": "67d078fe557181002fd16f3e",
  "timeEntries": [
  "67d07487557181002fd16d50",
  "67d07694557181002fd16e1e"
  ],
  "status": "approved",
  "assignedModel": "User",
  "assignedId": "66eb28a6ef8857a5097fbce3",
  "dateFrom": 20159,
  "dateTo": 20165,
  "createdAt": "2025-03-11T17:55:10.313Z",
  "updatedAt": "2025-03-11T17:57:12.306Z",
  "__v": 0,
  "approvedBy": "66eb28a6ef8857a5097fbce3",
  "dateOfApproval": "2025-03-11T17:57:12.305Z"
 }'

To update a timesheet it's required to pass the timesheet _id in the request URL as a parameter.

Example Request

curl --location -g --request PUT 'https://api.planhat.com/timesheets/67d078fe557181002fd16f3e' \
 --header 'Content-Type: application/json' \
 --header 'Authorization: Bearer {{apiToken}}' \
 --data-raw '{
  "status": "approved"
 }'


Example Response

200 ok

'{
  "_id": "67d078fe557181002fd16f3e",
  "timeEntries": [
  "67d07487557181002fd16d50",
  "67d07694557181002fd16e1e"
  ],
  "status": "approved",
  "assignedModel": "User",
  "assignedId": "66eb28a6ef8857a5097fbce3",
  "dateFrom": 20159,
  "dateTo": 20165,
  "createdAt": "2025-03-11T17:55:10.313Z",
  "updatedAt": "2025-03-11T17:57:12.306Z",
  "__v": 0,
  "approvedBy": "66eb28a6ef8857a5097fbce3",
  "dateOfApproval": "2025-03-11T17:57:12.305Z"
 }'

To update a timesheet it's required to pass the timesheet _id in the request URL as a parameter.

Example Request

curl --location -g --request PUT 'https://api.planhat.com/timesheets/67d078fe557181002fd16f3e' \
 --header 'Content-Type: application/json' \
 --header 'Authorization: Bearer {{apiToken}}' \
 --data-raw '{
  "status": "approved"
 }'


Example Response

200 ok

'{
  "_id": "67d078fe557181002fd16f3e",
  "timeEntries": [
  "67d07487557181002fd16d50",
  "67d07694557181002fd16e1e"
  ],
  "status": "approved",
  "assignedModel": "User",
  "assignedId": "66eb28a6ef8857a5097fbce3",
  "dateFrom": 20159,
  "dateTo": 20165,
  "createdAt": "2025-03-11T17:55:10.313Z",
  "updatedAt": "2025-03-11T17:57:12.306Z",
  "__v": 0,
  "approvedBy": "66eb28a6ef8857a5097fbce3",
  "dateOfApproval": "2025-03-11T17:57:12.305Z"
 }'

To get a specific timesheet it's required to pass the _id in the request URL as a parameter.

Example Request

curl --location -g --request GET 'https://api.planhat.com/timesheets/67aca36fa8ba08053dee2ebf' \
 --header 'Content-Type: application/json' \
 --header 'Authorization: Bearer {{apiToken}}'

Example Response

200 ok

'{
  "_id": "67aca36fa8ba08053dee2ebf",
  "timeEntries": [
  "67aca36ea8ba08053dee2e73",
  "67aca36ea8ba08053dee2e74",
  "67aca36ea8ba08053dee2e75"
  ],
  "status": "submitted",
  "assignedModel": "User",
  "assignedId": "66eb28a6ef8857a5097fbce3",
  "dateFrom": 20128,
  "dateTo": 20135,
  "createdAt": "2025-02-12T13:34:39.353Z",
  "updatedAt": "2025-02-12T13:34:39.353Z",
  "__v": 0
 }'

To get a specific timesheet it's required to pass the _id in the request URL as a parameter.

Example Request

curl --location -g --request GET 'https://api.planhat.com/timesheets/67aca36fa8ba08053dee2ebf' \
 --header 'Content-Type: application/json' \
 --header 'Authorization: Bearer {{apiToken}}'

Example Response

200 ok

'{
  "_id": "67aca36fa8ba08053dee2ebf",
  "timeEntries": [
  "67aca36ea8ba08053dee2e73",
  "67aca36ea8ba08053dee2e74",
  "67aca36ea8ba08053dee2e75"
  ],
  "status": "submitted",
  "assignedModel": "User",
  "assignedId": "66eb28a6ef8857a5097fbce3",
  "dateFrom": 20128,
  "dateTo": 20135,
  "createdAt": "2025-02-12T13:34:39.353Z",
  "updatedAt": "2025-02-12T13:34:39.353Z",
  "__v": 0
 }'

To get a specific timesheet it's required to pass the _id in the request URL as a parameter.

Example Request

curl --location -g --request GET 'https://api.planhat.com/timesheets/67aca36fa8ba08053dee2ebf' \
 --header 'Content-Type: application/json' \
 --header 'Authorization: Bearer {{apiToken}}'

Example Response

200 ok

'{
  "_id": "67aca36fa8ba08053dee2ebf",
  "timeEntries": [
  "67aca36ea8ba08053dee2e73",
  "67aca36ea8ba08053dee2e74",
  "67aca36ea8ba08053dee2e75"
  ],
  "status": "submitted",
  "assignedModel": "User",
  "assignedId": "66eb28a6ef8857a5097fbce3",
  "dateFrom": 20128,
  "dateTo": 20135,
  "createdAt": "2025-02-12T13:34:39.353Z",
  "updatedAt": "2025-02-12T13:34:39.353Z",
  "__v": 0
 }'

When fetching multiple timesheets there are some options that can be used via query params:

  • limit: Limit the list length. Default as 100, max. 2000.

  • offset: Start the list on a specific integer index.

  • sort: Sort based on a specific property. Prefix the property "-" to change the sort order.

  • select: Select specific properties. Multiple properties can be specified separating them by commas.

Example Request

curl --location -g --request GET 'https://api.planhat.com/timesheets?limit=2&offset=0&select=_id,dateFrom,dateTo' \
 --header 'Content-Type: application/json' \
 --header 'Authorization: Bearer {{apiToken}}'

Example Response

200 ok

'[
  {
  "_id": "679a8fe00a84a200cd465542",
  "dateFrom": 20107,
  "dateTo": 20114
  },
  {
  "_id": "67a266e7c3074c019778e17c",
  "dateFrom": 20121,
  "dateTo": 20128
  }
 ]'

When fetching multiple timesheets there are some options that can be used via query params:

  • limit: Limit the list length. Default as 100, max. 2000.

  • offset: Start the list on a specific integer index.

  • sort: Sort based on a specific property. Prefix the property "-" to change the sort order.

  • select: Select specific properties. Multiple properties can be specified separating them by commas.

Example Request

curl --location -g --request GET 'https://api.planhat.com/timesheets?limit=2&offset=0&select=_id,dateFrom,dateTo' \
 --header 'Content-Type: application/json' \
 --header 'Authorization: Bearer {{apiToken}}'

Example Response

200 ok

'[
  {
  "_id": "679a8fe00a84a200cd465542",
  "dateFrom": 20107,
  "dateTo": 20114
  },
  {
  "_id": "67a266e7c3074c019778e17c",
  "dateFrom": 20121,
  "dateTo": 20128
  }
 ]'

When fetching multiple timesheets there are some options that can be used via query params:

  • limit: Limit the list length. Default as 100, max. 2000.

  • offset: Start the list on a specific integer index.

  • sort: Sort based on a specific property. Prefix the property "-" to change the sort order.

  • select: Select specific properties. Multiple properties can be specified separating them by commas.

Example Request

curl --location -g --request GET 'https://api.planhat.com/timesheets?limit=2&offset=0&select=_id,dateFrom,dateTo' \
 --header 'Content-Type: application/json' \
 --header 'Authorization: Bearer {{apiToken}}'

Example Response

200 ok

'[
  {
  "_id": "679a8fe00a84a200cd465542",
  "dateFrom": 20107,
  "dateTo": 20114
  },
  {
  "_id": "67a266e7c3074c019778e17c",
  "dateFrom": 20121,
  "dateTo": 20128
  }
 ]'

To delete a timesheet it's required to pass the _id in the request URL as a parameter.

Example Request

curl --location -g --request DELETE 'https://api.planhat.com/timesheets/679a8fdd0a84a200cd4654aa' \
 --header 'Content-Type: application/json' \
 --header 'Authorization: Bearer {{apiToken}}'

Example Response

200 ok

'{
  "n": 1,
  "ok": 1,
  "deletedCount": 1
 }'

To delete a timesheet it's required to pass the _id in the request URL as a parameter.

Example Request

curl --location -g --request DELETE 'https://api.planhat.com/timesheets/679a8fdd0a84a200cd4654aa' \
 --header 'Content-Type: application/json' \
 --header 'Authorization: Bearer {{apiToken}}'

Example Response

200 ok

'{
  "n": 1,
  "ok": 1,
  "deletedCount": 1
 }'

To delete a timesheet it's required to pass the _id in the request URL as a parameter.

Example Request

curl --location -g --request DELETE 'https://api.planhat.com/timesheets/679a8fdd0a84a200cd4654aa' \
 --header 'Content-Type: application/json' \
 --header 'Authorization: Bearer {{apiToken}}'

Example Response

200 ok

'{
  "n": 1,
  "ok": 1,
  "deletedCount": 1
 }'

To create a timesheet, there are no required fields.

To update a timesheet it is required to specify _id in the payload.

Since this is a bulk upsert operation it's possible to create and/or update multiple timesheets with the same payload.

For more details please refer to the bulk upsert section.

There is an upper limit of 5,000 items per request.

Example Request

curl --location -g --request PUT 'https://api.planhat.com/timesheets' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{apiToken}}' \
--data-raw '[
                {
                    "assignedId": "66eb28a6ef8857a5097fbce3",
                    "assignedModel": "User"
                },
                {
                    "_id": "67aca36fa8ba08053dee2ebf",
                    "status": "returned"
                },
                {
                    "_id": "67bf484af303d806b63d9a49",
                    "status": "submitted"
                }
            ]'


Example Response

200 ok

'{
    "created": 1,
    "createdErrors": [],
    "insertsKeys": [
        {
            "_id": "67d08140557181002fd170dd"
        }
    ],
    "updated": 1,
    "updatedErrors": [],
    "updatesKeys": [
        {
            "_id": "67aca36fa8ba08053dee2ebf"
        }
    ],
    "nonupdates": 1,
    "modified": [
        "67aca36fa8ba08053dee2ebf"
    ],
    "upsertedIds": [
        "67d08140557181002fd170dd"
    ],
    "permissionErrors": [],
    "validationErrors": []
}'


To create a timesheet, there are no required fields.

To update a timesheet it is required to specify _id in the payload.

Since this is a bulk upsert operation it's possible to create and/or update multiple timesheets with the same payload.

For more details please refer to the bulk upsert section.

There is an upper limit of 5,000 items per request.

Example Request

curl --location -g --request PUT 'https://api.planhat.com/timesheets' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{apiToken}}' \
--data-raw '[
                {
                    "assignedId": "66eb28a6ef8857a5097fbce3",
                    "assignedModel": "User"
                },
                {
                    "_id": "67aca36fa8ba08053dee2ebf",
                    "status": "returned"
                },
                {
                    "_id": "67bf484af303d806b63d9a49",
                    "status": "submitted"
                }
            ]'


Example Response

200 ok

'{
    "created": 1,
    "createdErrors": [],
    "insertsKeys": [
        {
            "_id": "67d08140557181002fd170dd"
        }
    ],
    "updated": 1,
    "updatedErrors": [],
    "updatesKeys": [
        {
            "_id": "67aca36fa8ba08053dee2ebf"
        }
    ],
    "nonupdates": 1,
    "modified": [
        "67aca36fa8ba08053dee2ebf"
    ],
    "upsertedIds": [
        "67d08140557181002fd170dd"
    ],
    "permissionErrors": [],
    "validationErrors": []
}'


To create a timesheet, there are no required fields.

To update a timesheet it is required to specify _id in the payload.

Since this is a bulk upsert operation it's possible to create and/or update multiple timesheets with the same payload.

For more details please refer to the bulk upsert section.

There is an upper limit of 5,000 items per request.

Example Request

curl --location -g --request PUT 'https://api.planhat.com/timesheets' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{apiToken}}' \
--data-raw '[
                {
                    "assignedId": "66eb28a6ef8857a5097fbce3",
                    "assignedModel": "User"
                },
                {
                    "_id": "67aca36fa8ba08053dee2ebf",
                    "status": "returned"
                },
                {
                    "_id": "67bf484af303d806b63d9a49",
                    "status": "submitted"
                }
            ]'


Example Response

200 ok

'{
    "created": 1,
    "createdErrors": [],
    "insertsKeys": [
        {
            "_id": "67d08140557181002fd170dd"
        }
    ],
    "updated": 1,
    "updatedErrors": [],
    "updatesKeys": [
        {
            "_id": "67aca36fa8ba08053dee2ebf"
        }
    ],
    "nonupdates": 1,
    "modified": [
        "67aca36fa8ba08053dee2ebf"
    ],
    "upsertedIds": [
        "67d08140557181002fd170dd"
    ],
    "permissionErrors": [],
    "validationErrors": []
}'