Skip to main content

Time Entries

The TimeEntry entity represents recorded time against a project. Time entries track who worked on what, for how long, and whether the work is billable. They can be linked to tasks, planning phases, and documents.

info

All endpoints use the base path /odata/TimeEntry. Comments are managed via /odata/TimeEntryComment. For the flattened list view, use /odata/DynamicTimeEntry which returns all standard properties plus any user-defined fields.


Data Model

PropertyTypeDescription
TimeEntryIdguidUnique identifier of the time entry.
DisplayNamestringAuto-generated display name (read-only).
StartDateTimedatetimeStart date and time of the recorded work.
EndDateTimedatetimeEnd date and time of the recorded work.
ProjectIdguid?ID of the associated project.
DescriptionHTMLstringHTML-formatted description of the work performed.
DescriptionTextstringPlain-text description of the work performed.
PhaseIdguid?ID of the planning phase this entry is associated with.
IsBillableboolWhether this time entry is billable to the client.
PerformedByContactIdguid?ID of the contact who performed the work.
ColorFlagint?Color flag for visual categorization.
GroupIdguid?ID of the time entry group.
TaskItemIdguid?ID of the linked task, if any.
IsBilledboolWhether this time entry has been invoiced.
DurationMinutesdouble?Duration in minutes (computed from start/end, read-only).

Endpoints

CRUD Operations

GET/odata/TimeEntry

List all time entries

Returns all time entries the authenticated user has access to. Supports OData query options such as $filter, $select, $orderby, $top, and $skip.


GET/odata/TimeEntry({key})

Get a single time entry by ID

ParameterTypeRequiredDescription
keyguidThe unique time entry ID.

POST/odata/TimeEntry

Create a new time entry

{
"ProjectId": "project-guid",
"StartDateTime": "2025-04-01T09:00:00Z",
"EndDateTime": "2025-04-01T11:30:00Z",
"DescriptionText": "Frontend development — login page",
"IsBillable": true,
"PerformedByContactId": "contact-guid"
}
tip

If PerformedByContactId is omitted, the time entry is recorded for the authenticated user.


PATCH/odata/TimeEntry({key})

Update an existing time entry

ParameterTypeRequiredDescription
keyguidThe time entry ID to update.

Send only the properties you want to change:

{
"EndDateTime": "2025-04-01T12:00:00Z",
"IsBillable": false
}

DELETE/odata/TimeEntry({key})

Delete a time entry

ParameterTypeRequiredDescription
keyguidThe time entry ID to delete.
warning

Deleting a time entry is permanent. If the entry has been billed, ensure your billing records are updated accordingly.


GET/odata/TimeEntry/$count

Get total number of time entries

Returns the count as a plain integer. Supports $filter to count a subset.


Special Operations

GET/odata/TimeEntry/GetCalendarTimeEntriesForProject(projectId={projectId},take={take})

Get calendar-formatted time entries for a project

ParameterTypeRequiredDescription
projectIdguidThe project ID to retrieve time entries for.
takeintMaximum number of entries to return.

Returns time entries formatted for calendar display.


POST/odata/TimeEntry/CreateTimeEntryFromGraphEvent

Create a time entry from a Microsoft Graph calendar event

Converts a Microsoft 365 calendar event into an InLoox time entry.

{
"GraphEventId": "graph-event-id",
"ProjectId": "project-guid",
"IsBillable": true
}
info

This endpoint requires Microsoft Graph integration to be configured in your InLoox environment.


POST/odata/TimeEntry({key})/Copy

Create a copy of the time entry

ParameterTypeRequiredDescription
keyguidThe source time entry ID to copy.

Returns the newly created time entry.


POST/odata/TimeEntry({key})/CopyWithNewDates

Copy a time entry with different start/end dates

ParameterTypeRequiredDescription
keyguidThe source time entry ID to copy.
{
"StartDateTime": "2025-04-02T09:00:00Z",
"EndDateTime": "2025-04-02T11:30:00Z"
}

Documents

POST/odata/TimeEntry({key})/AddDocumentToTimeEntry

Link a document to the time entry

ParameterTypeRequiredDescription
keyguidThe time entry ID.
{
"DocumentId": "document-guid"
}

POST/odata/TimeEntry({key})/RemoveDocumentFromTimeEntry

Remove a document link from the time entry

ParameterTypeRequiredDescription
keyguidThe time entry ID.
{
"DocumentId": "document-guid"
}

Relations

POST/odata/TimeEntry({key})/AddRelation

Add a relation to another entity

ParameterTypeRequiredDescription
keyguidThe time entry ID.
{
"TargetId": "target-entity-guid",
"RelationType": "RelatedTo"
}

POST/odata/TimeEntry({key})/RemoveRelation

Remove an existing relation

ParameterTypeRequiredDescription
keyguidThe time entry ID.
{
"RelationId": "relation-guid"
}

Notes

POST/odata/TimeEntry({key})/AddNote

Add a note to the time entry

ParameterTypeRequiredDescription
keyguidThe time entry ID.
{
"Text": "Includes pair programming session with backend team."
}

GET/odata/TimeEntry/DeleteNote(noteRelationId={noteRelationId})

Delete a note from a time entry

ParameterTypeRequiredDescription
noteRelationIdguidThe note relation ID to delete.

Custom Fields — DynamicTimeEntry

Use the DynamicTimeEntry endpoint to access time entries with custom fields:

GET /odata/DynamicTimeEntry
GET /odata/DynamicTimeEntry({key})

Custom field names follow the pattern CF_<FieldName>.

GET/odata/DynamicTimeEntry

Flattened time entry view with project, planning, and task data

GET/odata/DynamicTimeEntry/$count

Get total number of DynamicTimeEntry records

warning

DynamicTimeEntry only supports GET requests. To create or update time entries, use the regular /odata/TimeEntry endpoints.


TimeEntryComment Sub-Entity

Time entries can have comments attached. Comments are accessed through the TimeEntryComment entity:

Properties

PropertyTypeDescription
TimeEntryCommentIdguidUnique identifier of the comment.
TimeEntryIdguidID of the parent time entry.
CommentstringComment text (plain text).
CommentHtmlstringComment text (HTML).
ShortDescriptionstringShort description.
CreateDateTimedatetimeWhen the comment was created.
CreatedByContactIdguidID of the contact who created the comment.
# Get comments for a specific time entry
curl -X GET "https://{tenant}.inloox.app/odata/TimeEntryComment?\
$filter=TimeEntryId eq {time-entry-guid}" \
-H "Authorization: Bearer {token}"

TimeEntryComment Endpoints

GET/odata/TimeEntryComment

List all time entry comments

POST/odata/TimeEntryComment

Create a new comment

ParameterTypeRequiredDescription
BodyDelta<ApiTimeEntryComment>JSON object with the comment data.
GET/odata/TimeEntryComment({key})

Get a single comment by ID

ParameterTypeRequiredDescription
keyguidThe TimeEntryCommentId.
PATCH/odata/TimeEntryComment({key})

Update a comment

ParameterTypeRequiredDescription
keyguidThe TimeEntryCommentId.
BodyDelta<ApiTimeEntryComment>JSON object with the fields to update.
DELETE/odata/TimeEntryComment({key})

Delete a comment

ParameterTypeRequiredDescription
keyguidThe TimeEntryCommentId.
GET/odata/TimeEntryComment/$count

Get total number of comments


OData Query Examples

Filter by Project and Date Range

curl -X GET "https://{tenant}.inloox.app/odata/TimeEntry?\
$filter=ProjectId eq {project-guid}\
and StartDateTime ge 2025-04-01T00:00:00Z\
and EndDateTime le 2025-04-30T23:59:59Z\
&$select=TimeEntryId,DisplayName,StartDateTime,EndDateTime,DurationMinutes,IsBillable\
&$orderby=StartDateTime desc" \
-H "Authorization: Bearer {token}"

Billable Time Entries Only

curl -X GET "https://{tenant}.inloox.app/odata/TimeEntry?\
$filter=IsBillable eq true and IsBilled eq false\
&$orderby=StartDateTime asc" \
-H "Authorization: Bearer {token}"

Time Entries by Contact

curl -X GET "https://{tenant}.inloox.app/odata/TimeEntry?\
$filter=PerformedByContactId eq {contact-guid}\
&$top=50&$skip=0\
&$orderby=StartDateTime desc" \
-H "Authorization: Bearer {token}"

C# Example

using System.Net.Http;
using System.Net.Http.Headers;

var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token);

// Query time entries for April 2025
var response = await client.GetAsync(
"https://{tenant}.inloox.app/odata/TimeEntry?" +
$"$filter=ProjectId eq {projectId}" +
" and StartDateTime ge 2025-04-01T00:00:00Z" +
" and EndDateTime le 2025-04-30T23:59:59Z" +
"&$select=TimeEntryId,StartDateTime,EndDateTime,DurationMinutes,IsBillable" +
"&$orderby=StartDateTime asc");

var json = await response.Content.ReadAsStringAsync();
Console.WriteLine(json);

// Create a time entry
var payload = new StringContent(
"""
{
"ProjectId": "{project-guid}",
"StartDateTime": "2025-04-15T09:00:00Z",
"EndDateTime": "2025-04-15T12:00:00Z",
"DescriptionText": "API integration work",
"IsBillable": true
}
""",
System.Text.Encoding.UTF8,
"application/json");

var createResponse = await client.PostAsync(
"https://{tenant}.inloox.app/odata/TimeEntry", payload);
tip

When querying time entries for reporting, always filter by date range (StartDateTime and EndDateTime) to avoid loading the entire history. Combine with $select to reduce payload size.