Zum Hauptinhalt springen

Zeiterfassung

Die TimeEntry-Entität repräsentiert Zeiteinträge in InLoox. Über die OData-API können Sie Zeiteinträge erstellen, aktualisieren, löschen sowie mit Dokumenten verknüpfen und aus Microsoft-Graph-Kalenderevents erzeugen.

OData-Endpunktbasis

Alle Endpunkte verwenden den Basispfad /odata/TimeEntry. Für die dynamische Listenansicht einschließlich eigener Felder steht /odata/DynamicTimeEntry zur Verfügung.

info

Zeiteinträge sind stets einem Projekt zugeordnet. Verwenden Sie ProjectId beim Filtern, um nur Zeiteinträge eines bestimmten Projekts abzurufen.


Datenmodell​

TimeEntry​

EigenschaftTypBeschreibung
TimeEntryIdGuid (UUID)Eindeutiger Bezeichner des Zeiteintrags (Primärschlüssel).
DisplayNamestring? (max. 255)Anzeigename des Zeiteintrags. Werte mit mehr als 255 Zeichen werden gekürzt.
StartDateTimeDateTimeOffset?Startdatum und -uhrzeit.
EndDateTimeDateTimeOffset?Enddatum und -uhrzeit.
ProjectIdGuid?Zugehöriges Projekt.
DescriptionHTMLstring?Beschreibung als HTML.
DescriptionTextstring?Beschreibung als Klartext.
PhaseIdGuid?Verknüpfte Planungsphase.
IsBillablebooleanGibt an, ob der Zeiteintrag abrechenbar ist.
PerformedByContactIdGuidKontakt-ID der Person, die die Arbeit ausgeführt hat.
ColorFlagint32?Farbmarkierung (als Integer-Wert).
GroupIdGuidGruppen-ID des Zeiteintrags.
TaskItemIdGuid?Verknüpfte Aufgabe.
IsBilledbooleanGibt an, ob der Zeiteintrag bereits abgerechnet wurde.
DurationMinutesint32Dauer in Minuten.

Endpunkte​

CRUD-Operationen​

Alle Zeiteinträge aller Projekte abrufen

GET/odata/TimeEntry

Unterstützt OData-Abfrageparameter.


Einen einzelnen Zeiteintrag abrufen

GET/odata/TimeEntry({key})
ParameterTypErforderlichBeschreibung
keyGuid✅Die TimeEntryId.

Neuen Zeiteintrag erstellen

POST/odata/TimeEntry
ParameterTypErforderlichBeschreibung
BodyDelta<ApiTimeEntry>✅JSON-Objekt mit den Zeiteintragseigenschaften.
tipp

Wenn PerformedByContactId nicht angegeben wird, wird der Zeiteintrag für den authentifizierten Benutzer erfasst.


Zeiteintrag teilweise aktualisieren

PATCH/odata/TimeEntry({key})
ParameterTypErforderlichBeschreibung
keyGuid✅Die TimeEntryId.
BodyDelta<ApiTimeEntry>✅JSON-Objekt mit den zu aktualisierenden Feldern.

Zeiteintrag löschen

DELETE/odata/TimeEntry({key})
ParameterTypErforderlichBeschreibung
keyGuid✅Die TimeEntryId.
warnung

Das Löschen eines Zeiteintrags ist dauerhaft. Falls der Eintrag bereits abgerechnet wurde, ist das Löschen nicht möglich.


Spezialfunktionen​

Kalenderansicht der Zeiteinträge für ein Projekt abrufen

GET/odata/TimeEntry/GetCalendarTimeEntriesForProject(projectId={projectId},take={take})
ParameterTypErforderlichBeschreibung
projectIdGuid✅Die ProjectId.
takeint32✅Maximale Anzahl der zurückgegebenen Einträge.

Einen Zeiteintrag aus einem Microsoft-Graph-Kalenderevent erstellen

POST/odata/TimeEntry/CreateTimeEntryFromGraphEvent
ParameterTypErforderlichBeschreibung
Bodyobject✅JSON-Objekt mit folgenden Feldern:

projectId (Guid, erforderlich) — Das Projekt, in dem der Zeiteintrag erstellt werden soll.
graphEventId (string, erforderlich) — Die ID des Microsoft-Graph-Kalenderevents.
tagEvent (bool?, optional) — Wenn true, wird dem Kalenderevent die Kategorie "InLoox" hinzugefügt.
taskItemId (Guid?, optional) — Optionale Aufgabe, die mit dem Zeiteintrag verknüpft werden soll.
Microsoft-Graph-Integration

Mit CreateTimeEntryFromGraphEvent können Sie Outlook-Kalendertermine direkt in Zeiteinträge umwandeln. Dies setzt eine aktive Microsoft-Graph-Integration voraus.


Einen Zeiteintrag kopieren

POST/odata/TimeEntry({key})/Copy
ParameterTypErforderlichBeschreibung
keyGuid✅Die TimeEntryId des zu kopierenden Eintrags.
Bodyobject✅JSON-Objekt mit folgenden Feldern:

projectId (Guid?, optional) — Zielprojekt für den kopierten Zeiteintrag. Wenn nicht angegeben, bleibt die Kopie im selben Projekt wie das Original.

Einen Zeiteintrag mit neuen Datumswerten kopieren

POST/odata/TimeEntry({key})/CopyWithNewDates
ParameterTypErforderlichBeschreibung
keyGuid✅Die TimeEntryId des zu kopierenden Eintrags.
Bodyobject✅JSON-Objekt mit folgenden Feldern:

projectId (Guid?, optional) — Zielprojekt für die Kopie. Wenn nicht angegeben, bleibt die Kopie im selben Projekt.
startDate (DateTimeOffset?, erforderlich) — Neues Startdatum/-uhrzeit für den kopierten Eintrag (wird als UTC gespeichert).
endDate (DateTimeOffset?, erforderlich) — Neues Enddatum/-uhrzeit für den kopierten Eintrag (wird als UTC gespeichert).

Dokumente​

Ein Dokument mit dem Zeiteintrag verknüpfen

POST/odata/TimeEntry({key})/AddDocumentToTimeEntry
ParameterTypErforderlichBeschreibung
keyGuid✅Die TimeEntryId.
Bodyobject✅JSON-Objekt mit folgenden Feldern:

documentIds (Guid[], erforderlich) — Array von Dokument-IDs, die mit dem Zeiteintrag verknüpft werden sollen.

Ein Dokument vom Zeiteintrag entfernen

POST/odata/TimeEntry({key})/RemoveDocumentFromTimeEntry
ParameterTypErforderlichBeschreibung
keyGuid✅Die TimeEntryId.
Bodyobject✅JSON-Objekt mit folgenden Feldern:

documentId (Guid, erforderlich) — Die ID des Dokuments, das vom Zeiteintrag entfernt werden soll.

Verknüpfungen​

Eine Verknüpfung zum Zeiteintrag hinzufügen

POST/odata/TimeEntry({key})/AddRelation
ParameterTypErforderlichBeschreibung
keyGuid✅Die TimeEntryId.
Bodyobject✅JSON-Objekt mit folgenden Feldern:

itemId (Guid, erforderlich) — Die ID des Elements, das verknüpft werden soll.

Eine Verknüpfung vom Zeiteintrag entfernen

POST/odata/TimeEntry({key})/RemoveRelation
ParameterTypErforderlichBeschreibung
keyGuid✅Die TimeEntryId.
Bodyobject✅JSON-Objekt mit folgenden Feldern:

itemId (Guid, erforderlich) — Die ID des Elements, dessen Verknüpfung entfernt werden soll.

Kommentare​

Alle Zeiteintragskommentare abrufen

GET/odata/TimeEntryComment

Einen einzelnen Kommentar abrufen

GET/odata/TimeEntryComment({key})
ParameterTypErforderlichBeschreibung
keyGuid✅Die TimeEntryCommentId.

Einen Kommentar zum Zeiteintrag hinzufügen

POST/odata/TimeEntry({key})/AddNote
ParameterTypErforderlichBeschreibung
keyGuid✅Die TimeEntryId.
Bodyobject✅JSON-Objekt mit folgenden Feldern:

htmlText (string, erforderlich) — HTML-formatierter Kommentartext.
notificationContactIds (Guid[], erforderlich) — Kontakt-IDs, die benachrichtigt werden sollen (kann ein leeres Array [] sein).

Einen Kommentar vom Zeiteintrag löschen

GET/odata/TimeEntry/DeleteNote(noteRelationId={noteRelationId})
ParameterTypErforderlichBeschreibung
noteRelationIdGuid✅Die ID der Kommentarverknüpfung.
warnung

Das Löschen eines Kommentars kann nicht rückgängig gemacht werden.


DynamicTimeEntry​

Der Endpunkt /odata/DynamicTimeEntry bietet eine schreibgeschützte, abgeflachte Ansicht, die Daten aus Zeiteintrag, Projekt, Planung, Aufgabe und Berechtigungen zusammenführt. Alle Eigenschaften sind mit einem Präfix versehen (z. B. TimeEntry_DisplayName, Project_Name, TaskItem_Name). Eigene Felder folgen dem Muster CF_<Feldname>.

Abgeflachte Zeiteintragsansicht mit Projekt-, Planungs- und Aufgabendaten abrufen

GET/odata/DynamicTimeEntry
Nur lesender Zugriff

DynamicTimeEntry unterstützt ausschließlich GET-Anfragen. Zum Erstellen oder Bearbeiten verwenden Sie die regulären /odata/TimeEntry-Endpunkte.


OData-Abfragebeispiele​

Zeiteinträge eines Projekts abrufen​

GET /odata/TimeEntry?$filter=ProjectId eq 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'

Abrechenbare, aber noch nicht abgerechnete Einträge​

GET /odata/TimeEntry?$filter=IsBillable eq true and IsBilled eq false

Zeiteinträge eines bestimmten Zeitraums​

GET /odata/TimeEntry?$filter=StartDateTime ge 2025-01-01T00:00:00Z and EndDateTime le 2025-01-31T23:59:59Z

Zeiteintrag erstellen​

POST /odata/TimeEntry
Content-Type: application/json

{
"DisplayName": "Entwicklung API-Modul",
"ProjectId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"StartDateTime": "2025-01-15T09:00:00Z",
"EndDateTime": "2025-01-15T12:30:00Z",
"IsBillable": true,
"PerformedByContactId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
Dauer berechnen

Das Feld DurationMinutes wird serverseitig aus StartDateTime und EndDateTime berechnet. Sie können es auch manuell setzen, wenn Sie keine Start-/Endzeit angeben.

Zeiteinträge nach Kontakt​

GET /odata/TimeEntry?$filter=PerformedByContactId eq 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'&$top=50&$skip=0&$orderby=StartDateTime desc

C#-Beispiel​

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

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

// Zeiteinträge für April 2025 abfragen
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);

// Zeiteintrag erstellen
var payload = new StringContent(
"""
{
"ProjectId": "{project-guid}",
"StartDateTime": "2025-04-15T09:00:00Z",
"EndDateTime": "2025-04-15T12:00:00Z",
"DescriptionHTML": "API-Integrationsarbeit",
"IsBillable": true
}
""",
System.Text.Encoding.UTF8,
"application/json");

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

Filtern Sie Zeiteinträge für Auswertungen immer nach Datumsbereich (StartDateTime und EndDateTime), um nicht die gesamte Historie zu laden. Kombinieren Sie dies mit $select, um die Antwortgröße zu reduzieren.