List Timesheets
This endpoint returns a page of timesheet summaries for the authenticated account.
Endpoint
Section titled “Endpoint”GET /v1/timesheets/timesheetsAuthentication
Section titled “Authentication”Include your API key in the x-api-key header. See Authentication.
Required Scope
Section titled “Required Scope”timesheets:readQuery Parameters
Section titled “Query Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
userId | string | No | Return only timesheets of this user. Accepts an external user ID (user-a) or an internal one (tenant-123#user-a, URL-encoded). The API converts the value to lowercase before matching. |
page | number | No | Zero-based page index. Defaults to 0. |
pageSize | number | No | Number of timesheets per page. Defaults to 25. |
sortCol | "submitted_at" | "period_start" | "period_end" | No | Sort column. Must be sent with a valid sortDir. |
sortDir | "asc" | "desc" | No | Sort direction, in lowercase. Must be sent with a valid sortCol. |
There are no status or date-range filters. To find timesheets for a period or status, page through the results and filter on periodStart, periodEnd, and approvals[].status.
See Pagination for paging and sorting rules.
Request Body
Section titled “Request Body”This endpoint does not accept a request body.
Example Request
Section titled “Example Request”curl "https://api.crewsum.com/v1/timesheets/timesheets?userId=user-a&sortCol=submitted_at&sortDir=desc&page=0&pageSize=25" \ -H "x-api-key: $CREWSUM_API_KEY"const response = await fetch( "https://api.crewsum.com/v1/timesheets/timesheets?userId=user-a&sortCol=submitted_at&sortDir=desc&page=0&pageSize=25", { headers: { "x-api-key": process.env.CREWSUM_API_KEY }, },);const result = await response.json();GET /v1/timesheets/timesheets?userId=user-a&sortCol=submitted_at&sortDir=desc&page=0&pageSize=25 HTTP/1.1Host: api.crewsum.comx-api-key: <your-api-key>Response
Section titled “Response”On success, the API returns HTTP 200 OK.
Example Response
Section titled “Example Response”{ "message": "Successfully fetched timesheets", "data": { "count": 1, "timesheets": [ { "id": "tenant-123#user-a#20221231_20230106", "periodStart": "2022-12-31", "periodEnd": "2023-01-06", "submittedAt": "2023-01-07T00:00:00.000Z", "tenantId": "tenant-123", "userId": "user-a", "hours": 40, "projects": [ { "id": "project-mno123pqr4567890", "name": "Project Name" } ], "tasks": [ { "id": "task-pqr123stu4567890", "name": "Task Name" } ], "approvals": [ { "projectId": "project-mno123pqr4567890", "taskId": "task-pqr123stu4567890", "projectName": "Project Name", "taskName": "Task Name", "status": "pending", "approverName": null, "approverEmail": null, "projectCustomFields": {}, "clientCustomFields": {} } ], "userCustomFields": {} } ] }}Response Fields
Section titled “Response Fields”Each item in timesheets is a summary. Use Get Timesheet for the full timecards and daily hours.
| Field | Type | Description |
|---|---|---|
id | string | Timesheet ID. See Timesheet IDs. |
periodStart, periodEnd | string | First and last day of the period (YYYY-MM-DD). |
submittedAt | string | null | Submission time. null for a saved draft that was never submitted. |
tenantId | string | Tenant ID. |
userId | string | External user ID. |
hours | number | Total hours across all timecards. |
projects, tasks | object[] | Unique projects and tasks on the timesheet, sorted by name. |
approvals | object[] | One item per timecard, with its status: draft, pending, approved, or rejected. |
userCustomFields | object | The user’s custom field values. |
Behavior
Section titled “Behavior”countis the total number of matching timesheets, not the number on this page.- Saved drafts that were never submitted are included.
- If
sortColorsortDiris missing or invalid, the API ignores both and sorts bysubmitted_atdescending, with unsubmitted timesheets last. approvals[].clientCustomFieldscurrently contains the project’s custom fields, not the client’s. Use Get Timesheet for the client’s custom fields.
Error Responses
Section titled “Error Responses”| Status | Meaning |
|---|---|
500 | Crewsum could not fetch timesheets. Message: Error fetching timesheets. |
Authentication and scope failures are described in Errors.
Related Webhooks
Section titled “Related Webhooks”This endpoint does not trigger a webhook.