Time Entry
A tracked interval of work on a task.
Whose entries you see depends on your role. By default list, get and search return only your own entries. If your role holds viewTimeReports, list and get return every entry in your team, and memberId narrows that to one person — this is how a team-wide time report is built.
Note for integrations: breadth follows the ROLE, not the token. A token granted time-entry read by someone holding viewTimeReports can read that whole team, not only the person who granted it.
search is the exception: it stays scoped to your own entries whatever your role, so it under-reports a team. Use list for reporting.
Omit end (or send null) to start a running entry, then PATCH end to stop it. taskId and projectId are set once: an entry cannot be moved to another task or project afterwards.
List Time Entries
List timeEntries. Returns a paginated envelope (data, total, limit, hasMore, nextCursor). Filterable by 5 fields. Ordered by start unless you pass sort. Returns your own entries by default. With viewTimeReports on your role it returns every entry in your team instead; filter memberId for one person. This is the endpoint to build a team time report from — search stays scoped to your own entries regardless of role.
Required scope: time-entries:read
query Parameters
sortField to sort by. Prefix with - for descending (-createdAt); a createdAt:desc / createdAt:asc suffix works too, but never both markers at once. Default: start.
cursorOpaque cursor for the next page (the envelope nextCursor).
limitItems per page (1–200, default 50). A larger value is clamped to the cap rather than rejected, so always follow nextCursor instead of assuming one page held everything.
includeTotalWhen true, the response envelope includes the total number of matching rows. Omit it for cheaper pagination.
expandComma-separated relations to inline (see Expanding objects above). Valid values are listed in the enum.
manual[eq]Filter where manual equals.
start[gt]Filter where start is greater than.
start[gte]Filter where start is greater than or equal to.
start[lt]Filter where start is less than.
start[lte]Filter where start is less than or equal to.
projectId[eq]Filter where projectId equals.
projectId[in]Filter where projectId is one of (comma-separated list).
taskId[eq]Filter where taskId equals.
taskId[in]Filter where taskId is one of (comma-separated list).
memberId[eq]Filter where memberId equals.
memberId[in]Filter where memberId is one of (comma-separated list).
List Time Entries › Responses
OK
The page of results.
totalTotal rows matching the query (across pages).
limithasMorenextCursorOpaque cursor for the next page; null on the last page.
Create Time Entry
Create a Time Entry. Server-assigned fields are ignored if sent.
Required scope: time-entries:write
query Parameters
expandComma-separated relations to inline (see Expanding objects above). Valid values are listed in the enum.
Headers
Idempotency-KeyOptional replay key (see Idempotent requests above).
Create Time Entry › Request Body
startWhen the tracked interval began (ISO 8601).
taskIdThe task this time is tracked against. Set once when the entry is created: an entry cannot be moved to another task afterwards.
descriptionFree-text note about what the time was spent on. This is the field GET /time-entries/search matches against.
endWhen the tracked interval ended (ISO 8601). Omit it, or send null, to create a running entry; PATCH end to stop it.
projectIdThe project this time is booked against. Set once when the entry is created: an entry cannot be moved to another project afterwards.
Create Time Entry › Responses
Created
idUnique identifier for this resource.
createdAtCreation timestamp.
startWhen the tracked interval began (ISO 8601).
manualTrue for entries created through this API; false for entries captured by the timer in the Nifty app. Server-set.
memberIdThe team member this time is tracked for. Set by the server from whoever is calling — you cannot log time on someone else's behalf.
taskIdThe task this time is tracked against. Set once when the entry is created: an entry cannot be moved to another task afterwards.
updatedAtLast update timestamp.
descriptionFree-text note about what the time was spent on. This is the field GET /time-entries/search matches against.
endWhen the tracked interval ended (ISO 8601). Omit it, or send null, to create a running entry; PATCH end to stop it.
projectIdThe project this time is booked against. Set once when the entry is created: an entry cannot be moved to another project afterwards.
The related Team Member, present only when you pass ?expand=member.
Get Time Entry
Retrieve a single Time Entry by id. By default only your own entries are reachable here. With viewTimeReports on your role, so is any entry in your team — get widens exactly as list does, so a row you can see in list is a row you can fetch by id. Without that permission another member's entry is 404, not 403.
Required scope: time-entries:read
path Parameters
id^[0-9A-Za-z_!]+$ · requiredId of the Time Entry.
query Parameters
expandComma-separated relations to inline (see Expanding objects above). Valid values are listed in the enum.
Get Time Entry › Responses
OK
idUnique identifier for this resource.
createdAtCreation timestamp.
startWhen the tracked interval began (ISO 8601).
manualTrue for entries created through this API; false for entries captured by the timer in the Nifty app. Server-set.
memberIdThe team member this time is tracked for. Set by the server from whoever is calling — you cannot log time on someone else's behalf.
taskIdThe task this time is tracked against. Set once when the entry is created: an entry cannot be moved to another task afterwards.
updatedAtLast update timestamp.
descriptionFree-text note about what the time was spent on. This is the field GET /time-entries/search matches against.
endWhen the tracked interval ended (ISO 8601). Omit it, or send null, to create a running entry; PATCH end to stop it.
projectIdThe project this time is booked against. Set once when the entry is created: an entry cannot be moved to another project afterwards.
The related Team Member, present only when you pass ?expand=member.
Delete Time Entry
Permanently delete this Time Entry. This cannot be undone.
Required scope: time-entries:delete
path Parameters
id^[0-9A-Za-z_!]+$ · requiredId of the Time Entry.
Headers
Idempotency-KeyOptional replay key (see Idempotent requests above).
Delete Time Entry › Responses
No Content
Update Time Entry
Partially update a Time Entry. Only the fields you send are changed.
Required scope: time-entries:write
path Parameters
id^[0-9A-Za-z_!]+$ · requiredId of the Time Entry.
query Parameters
expandComma-separated relations to inline (see Expanding objects above). Valid values are listed in the enum.
Headers
Idempotency-KeyOptional replay key (see Idempotent requests above).
Update Time Entry › Request Body
descriptionFree-text note about what the time was spent on. This is the field GET /time-entries/search matches against.
startWhen the tracked interval began (ISO 8601).
endWhen the tracked interval ended (ISO 8601). Omit it, or send null, to create a running entry; PATCH end to stop it.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
Update Time Entry › Responses
OK
idUnique identifier for this resource.
createdAtCreation timestamp.
startWhen the tracked interval began (ISO 8601).
manualTrue for entries created through this API; false for entries captured by the timer in the Nifty app. Server-set.
memberIdThe team member this time is tracked for. Set by the server from whoever is calling — you cannot log time on someone else's behalf.
taskIdThe task this time is tracked against. Set once when the entry is created: an entry cannot be moved to another task afterwards.
updatedAtLast update timestamp.
descriptionFree-text note about what the time was spent on. This is the field GET /time-entries/search matches against.
endWhen the tracked interval ended (ISO 8601). Omit it, or send null, to create a running entry; PATCH end to stop it.
projectIdThe project this time is booked against. Set once when the entry is created: an entry cannot be moved to another project afterwards.
The related Team Member, present only when you pass ?expand=member.
Search Time Entries
Full-text ranked search across timeEntries. Ranked by relevance; pages are capped at 200 results. Filterable by 5 fields. Always scoped to your own entries, whatever your role — unlike list and get, a reporting permission does NOT widen it. Do not build a team report from this endpoint; it will silently under-report.
Required scope: time-entries:read
query Parameters
qFull-text search query. Trimmed before matching; URLs, e-mail addresses and HTML markup are rejected.
cursorOpaque cursor for the next page (the envelope nextCursor).
limitItems per page (1–200, default 50). A larger value is clamped to the cap rather than rejected, so always follow nextCursor instead of assuming one page held everything.
includeTotalWhen true, the response envelope includes the total number of matching rows. Omit it for cheaper pagination.
expandComma-separated relations to inline (see Expanding objects above). Valid values are listed in the enum.
manual[eq]Filter where manual equals.
start[gt]Filter where start is greater than.
start[gte]Filter where start is greater than or equal to.
start[lt]Filter where start is less than.
start[lte]Filter where start is less than or equal to.
projectId[eq]Filter where projectId equals.
projectId[in]Filter where projectId is one of (comma-separated list).
taskId[eq]Filter where taskId equals.
taskId[in]Filter where taskId is one of (comma-separated list).
memberId[eq]Filter where memberId equals.
memberId[in]Filter where memberId is one of (comma-separated list).
Search Time Entries › Responses
OK
The page of results.
totalTotal rows matching the query (across pages).
limithasMorenextCursorOpaque cursor for the next page; null on the last page.