Timesheets and time entries
Timesheets and time entries in the BlueSuite REST API
List timesheets, inspect their entries, and update approval status. There is no timesheet creation endpoint; create time entries instead. Both resources use timesheets:read / timesheets:write scopes.
Time entries can use explicit start/end times or total_time without invented clock times. total_time is an integer number of minutes, from 0 to 1,440. Dates must be real calendar dates; time inputs must be valid clock times. The create route defaults the user to the authenticated acting user when user_id is omitted. Resolve other users through Users. An explicit hourly_rate override requires a manager or higher; omitting it lets the stored labor rate apply, while null leaves the entry uncosted.
Associate an entry with a job, request, quote, or service-plan subscription as supported by the fields below. Do not supply conflicting parent associations. Updates preserve omitted fields and recalculate duration when timing changes.
GET /api/v1/time-entries
GET /api/v1/time-entriesRequired scopes: timesheets:read.
Query parameters
| Field | Type / accepted values | Required | Details |
|---|---|---|---|
page | integer | No | Page number, starting at 1. Default: 1. |
per_page | integer | No | Records per page, from 1 to 100. Default: 25. minimum: 1. maximum: 100. |
search | string | No | Search text. maxLength: 100. |
sort_by | string | No | Sort column. See the supported columns below when listed. |
sort_direction | "asc", "desc" | No | Sort direction. Default: "desc". |
start_date | string | No | Inclusive start date, YYYY-MM-DD. |
end_date | string | No | Inclusive end date, YYYY-MM-DD. |
user_id | string | No | Filter by user UUID from GET /users. |
job_id | string | No | Filter by job ID. |
request_id | string | No | Filter by request ID. |
quote_id | string | No | Filter by quote ID. |
service_plan_subscription_id | string | No | Filter by subscription ID. |
Response
200 with { "success": true, "data": [...], "pagination": { "page": 1, "per_page": 25, "total_pages": 1 } }.
See response conventions and errors.
POST /api/v1/time-entries
POST /api/v1/time-entriesRequired scopes: timesheets:write.
JSON body
| Field | Type / accepted values | Required | Details |
|---|---|---|---|
start_date | string | Yes | Format: date. |
end_date | string | Yes | Format: date. |
start_time | string or null | No | |
end_time | string or null | No | |
total_time | integer | No | minimum: 0. maximum: 1440. |
user_id | string or null | No | |
hourly_rate | number or null | No | |
description | string or null | No | |
job_id | integer or null | No | |
request_id | integer or null | No | |
quote_id | integer or null | No | |
service_plan_subscription_id | integer or null | No |
Unknown body fields are rejected. Conditional requirements are explained above.
Response
201 with { "success": true, "data": ... }. The data contains the result of the operation.
See response conventions and errors.
GET /api/v1/timesheets
GET /api/v1/timesheetsRequired scopes: timesheets:read.
Query parameters
| Field | Type / accepted values | Required | Details |
|---|---|---|---|
page | integer | No | Page number, starting at 1. Default: 1. |
per_page | integer | No | Records per page, from 1 to 100. Default: 25. minimum: 1. maximum: 100. |
search | string | No | Search text. maxLength: 100. |
sort_by | string | No | Sort column. See the supported columns below when listed. |
sort_direction | "asc", "desc" | No | Sort direction. Default: "desc". |
start_date | string | No | Inclusive start date, YYYY-MM-DD. |
end_date | string | No | Inclusive end date, YYYY-MM-DD. |
user_id | string | No | Filter by user UUID from GET /users. |
status | string | No | Filter by status. |
Response
200 with { "success": true, "data": [...], "pagination": { "page": 1, "per_page": 25, "total_pages": 1 } }.
See response conventions and errors.
PUT /api/v1/time-entries/:id
PUT /api/v1/time-entries/:idRequired scopes: timesheets:write.
Path parameters: id. Use positive integer record IDs from this workspace.
JSON body
| Field | Type / accepted values | Required | Details |
|---|---|---|---|
start_date | string | No | Format: date. |
end_date | string | No | Format: date. |
start_time | string or null | No | |
end_time | string or null | No | |
total_time | integer | No | minimum: 0. maximum: 1440. |
user_id | string or null | No | |
hourly_rate | number or null | No | |
description | string or null | No | |
job_id | integer or null | No | |
request_id | integer or null | No | |
quote_id | integer or null | No | |
service_plan_subscription_id | integer or null | No |
Unknown body fields are rejected. Conditional requirements are explained above.
Response
200 with { "success": true, "data": ... }. The data contains the result of the operation.
See response conventions and errors.
DELETE /api/v1/time-entries/:id
DELETE /api/v1/time-entries/:idRequired scopes: timesheets:write.
Path parameters: id. Use positive integer record IDs from this workspace.
No request body.
Response
200 with { "success": true, "data": ... }. The data contains the result of the operation.
See response conventions and errors.
GET /api/v1/timesheets/:id
GET /api/v1/timesheets/:idRequired scopes: timesheets:read.
Path parameters: id. Use positive integer record IDs from this workspace.
Response
200 with { "success": true, "data": ... }. The data contains the result of the operation.
See response conventions and errors.
PUT /api/v1/timesheets/:id/status
PUT /api/v1/timesheets/:id/statusRequired scopes: timesheets:write.
Path parameters: id. Use positive integer record IDs from this workspace.
JSON body
| Field | Type / accepted values | Required | Details |
|---|---|---|---|
status | "draft", "pending", "approved", "rejected" | Yes |
Unknown body fields are rejected. Conditional requirements are explained above.
Response
200 with { "success": true, "data": ... }. The data contains the result of the operation.