Summary
Time tracking entries now expose an assignee field: the user whose timesheet the entry’s logged time is attributed to.
Until now, the only user on a time tracking entry was created_by, which identifies who created the entry, not who it belongs to. The two often differ: a time reviewer or domain admin can log time on behalf of another user. Integrations that used created_by to attribute time for reporting, billing, or payroll could attribute those entries to the wrong person.
Key highlights:
- New response field:
assigneeis returned on every time tracking entry, from all read endpoints, and from create/update responses - Write support: Set
assigneewhen creating an entry, or reassign it when updating one, so integrations can log time on behalf of other users (subject to permissions) - New filter:
GET /time_tracking_entriesaccepts a newassigneequery parameter - Deprecation: The
userquery parameter onGET /time_tracking_entriesis deprecated in favor ofassignee. It continues to work and returns the same results
This is a non-breaking change. Existing requests and responses keep working as before.
Who is affected
If you read time tracking entries for reporting, billing, or payroll: use assignee to determine whose time an entry is. If your integration currently treats created_by as the owner of the entry, switch to assignee. created_by keeps its existing meaning (the user who created the entry) and is unchanged.
If you filter GET /time_tracking_entries by user: no immediate action is required. user already filters by the user the time is attributed to, which is exactly what assignee represents. The new assignee parameter behaves identically, and we recommend switching to it. The user parameter will be removed from the API reference documentation but will keep working.
If you create or update time tracking entries: no action is required. When assignee is omitted on create, the entry is attributed to the authenticated user, as it is today. You can now optionally pass assignee to log time for someone else.
Timeline
This is available now!
Usage
The assignee field
| Field | Description |
|---|---|
assignee |
New. The user this entry’s logged time is attributed to. Returned as a compact user object. |
created_by |
Unchanged. The user who created the time tracking entry. Its description is being added to the API reference to make the distinction clear. |
Example where a time reviewer logged time on behalf of a team member:
GET /time_tracking_entries/{time_tracking_entry_gid}
{
"data": {
"gid": "12345",
"resource_type": "time_tracking_entry",
"duration_minutes": 120,
"entered_on": "2026-10-01",
"created_by": {
"gid": "67890",
"resource_type": "user",
"name": "Alex Chen"
},
"assignee": {
"gid": "11111",
"resource_type": "user",
"name": "Jamie Smith"
}
}
}
Setting assignee when creating an entry
assignee is optional and takes a user GID. If omitted, it defaults to the authenticated user.
// POST /tasks/{task_gid}/time_tracking_entries
{
"data": {
"duration_minutes": 120,
"entered_on": "2026-10-01",
"assignee": "11111"
}
}
Reassigning an existing entry
// PUT /time_tracking_entries/{time_tracking_entry_gid}
{
"data": {
"assignee": "11111"
}
}
Who can set assignee
You can set assignee to:
- Yourself
- A user whose time you review (requires the Timesheets & Budgets add-on, where reviewer relationships are configured)
- Any user (including View-Only users and Guests), if you are a domain admin
If you set assignee to a user outside these rules, the request fails with 403 Forbidden and the error code time_tracking_entry_invalid_assignee:
// 403 Forbidden
{
"errors": [
{
"message": "You can only set assignee to yourself or to a user whose time you review. Domain admins can set it to any user."
}
]
}
Filtering by assignee
GET /time_tracking_entries?assignee={user_gid}&workspace={workspace_gid}
assignee works exactly like the existing user parameter and can be combined with the same parameters (workspace, attributable_to, portfolio, task, entered_on_start_date, entered_on_end_date).
If you pass both user and assignee with different values, the request fails with 400 Bad Request:
// 400 Bad Request
{
"errors": [
{
"message": "assignee: cannot be combined with a different value for the deprecated user parameter"
}
]
}
Migration steps
1. Attribute time using assignee, not created_by.
// Before: attributes time to whoever created the entry
const owner = entry.created_by.gid;
// After: attributes time to the user whose timesheet it belongs to
const owner = entry.assignee.gid;
2. Replace the user filter with assignee.
// Before
GET /time_tracking_entries?user={user_gid}&workspace={workspace_gid}
// After
GET /time_tracking_entries?assignee={user_gid}&workspace={workspace_gid}
3. (Optional) Log time on behalf of other users.
Pass assignee on POST /tasks/{task_gid}/time_tracking_entries or PUT /time_tracking_entries/{time_tracking_entry_gid}, and handle the 403 response for users your integration can’t assign time to.