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?Anzeigename des Zeiteintrags.
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
keyGuidDie 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
keyGuidDie TimeEntryId.
BodyDelta<ApiTimeEntry>JSON-Objekt mit den zu aktualisierenden Feldern.

Zeiteintrag löschen

DELETE/odata/TimeEntry({key})
ParameterTypErforderlichBeschreibung
keyGuidDie 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
projectIdGuidDie ProjectId.
takeint32Maximale Anzahl der zurückgegebenen Einträge.

Einen Zeiteintrag aus einem Microsoft-Graph-Kalenderevent erstellen

POST/odata/TimeEntry/CreateTimeEntryFromGraphEvent
ParameterTypErforderlichBeschreibung
BodyobjectJSON-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
keyGuidDie TimeEntryId des zu kopierenden Eintrags.
BodyobjectJSON-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
keyGuidDie TimeEntryId des zu kopierenden Eintrags.
BodyobjectJSON-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
keyGuidDie TimeEntryId.
BodyobjectJSON-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
keyGuidDie TimeEntryId.
BodyobjectJSON-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
keyGuidDie TimeEntryId.
BodyobjectJSON-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
keyGuidDie TimeEntryId.
BodyobjectJSON-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
keyGuidDie TimeEntryCommentId.

Einen Kommentar zum Zeiteintrag hinzufügen

POST/odata/TimeEntry({key})/AddNote
ParameterTypErforderlichBeschreibung
keyGuidDie TimeEntryId.
BodyobjectJSON-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
noteRelationIdGuidDie 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.