Skip to content

Review Timesheet

This endpoint records approve or reject decisions for each day of one or more timecards in a timesheet.

POST /v1/timesheets/timesheets/review

Include your API key in the x-api-key header. See Authentication.

timesheets:review

The request body is not validated against a schema. Send every field marked Required in the shape shown. A missing or malformed field usually causes a 500, not a 400.

FieldTypeRequiredDescription
timesheetIdstringYesTimesheet ID, for example tenant-123#user-a#20221231_20230106. Do not URL-encode it in the body.
timecardsobject[]YesReview decisions, one item per timecard you review.
sendEmailsbooleanNoWhen true, the API sends review result emails after saving the review. Defaults to false.
userIdstringNoTimesheet owner’s user ID. It is only a fallback for finding the owner’s email address, and it is not recorded as the reviewer.

Each review timecard:

FieldTypeRequiredDescription
projectIdstringYesProject ID of the timecard.
taskIdstringYesTask ID of the timecard.
dataobjectYesOne entry for each day: Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, and Friday. All seven keys are required.
commentsstring | nullNoReviewer comments for the whole timecard. Returned as managerComments by Get Timesheet.

Each day in data:

FieldTypeRequiredDescription
approvedbooleanYestrue to approve the day, false to reject it. A missing value counts as rejected.
rejectionReasonstring | nullNoReason for rejecting the day. The API does not require it for rejected days.
datestringYesThe day’s date (YYYY-MM-DD). The API does not store it. The Friday date must be a valid date, or the API returns 500.

There is no status field. The API derives each timecard’s status from its days:

  • All seven days approved: true: the timecard becomes approved.
  • Any day not approved: the whole timecard becomes rejected.

In this example, Thursday is rejected, so the timecard becomes rejected.

{
"timesheetId": "tenant-123#user-a#20221231_20230106",
"sendEmails": true,
"timecards": [
{
"projectId": "project-mno123pqr4567890",
"taskId": "task-pqr123stu4567890",
"comments": "Please fix Thursday and resubmit.",
"data": {
"Saturday": { "date": "2022-12-31", "approved": true, "rejectionReason": null },
"Sunday": { "date": "2023-01-01", "approved": true, "rejectionReason": null },
"Monday": { "date": "2023-01-02", "approved": true, "rejectionReason": null },
"Tuesday": { "date": "2023-01-03", "approved": true, "rejectionReason": null },
"Wednesday": { "date": "2023-01-04", "approved": true, "rejectionReason": null },
"Thursday": { "date": "2023-01-05", "approved": false, "rejectionReason": "Please clarify the hours entered." },
"Friday": { "date": "2023-01-06", "approved": true, "rejectionReason": null }
}
}
]
}
Terminal window
curl -X POST "https://api.crewsum.com/v1/timesheets/timesheets/review" \
-H "x-api-key: $CREWSUM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"timesheetId": "tenant-123#user-a#20221231_20230106",
"sendEmails": true,
"timecards": [
{
"projectId": "project-mno123pqr4567890",
"taskId": "task-pqr123stu4567890",
"comments": "Please fix Thursday and resubmit.",
"data": {
"Saturday": { "date": "2022-12-31", "approved": true, "rejectionReason": null },
"Sunday": { "date": "2023-01-01", "approved": true, "rejectionReason": null },
"Monday": { "date": "2023-01-02", "approved": true, "rejectionReason": null },
"Tuesday": { "date": "2023-01-03", "approved": true, "rejectionReason": null },
"Wednesday": { "date": "2023-01-04", "approved": true, "rejectionReason": null },
"Thursday": { "date": "2023-01-05", "approved": false, "rejectionReason": "Please clarify the hours entered." },
"Friday": { "date": "2023-01-06", "approved": true, "rejectionReason": null }
}
}
]
}'

On success, the API returns HTTP 200 OK.

{
"message": "Successfully reviewed timesheet"
}
  • For each timecard in the request, the API stores the day decisions and rejection reasons, the derived status, comments, and the review time (reviewedAt).
  • Timecards left out of the request are not changed.
  • approverName and approverEmail are set to null for reviews made through the API.
  • The approval links that were emailed for the reviewed timecards stop working.
  • A rejected timecard lets the user submit the timesheet again. See Submit Self Timesheet.
  • When sendEmails is true, the API emails the review result to the user, to project contacts whose notification level is copy only or copy with link, to the user’s supplier contacts, and to your internal copy address if it is turned on.
  • The API first checks that the timesheet is in your account. If it is not, the API returns 404 and writes nothing.
  • The review is saved before emails are sent. If sending emails fails, the API returns 500, but the review is kept and no webhook is sent.
  • After the review, Crewsum sends the timecards.reviewed webhook event. The payload is { "timecards": [{ "timecard": <timecard>, "review": <review> }] }, with one item per reviewed timecard.
StatusMeaning
404No timesheet in your account has this ID. Nothing is written. Message: Timesheet with ID <id> not found.
500The review could not be saved, for example because a day key is missing or the Friday date is not valid. Message: Error updating timecards.
500The review was saved, but a later step failed, such as sending emails. Message: Error submitting timesheet review.
500The body is missing or has the wrong shape, for example no timecards array. The response has a generic error body.

Authentication and scope failures are described in Errors.