Skip to main content

Projects

The Project entity is the central resource in InLoox. Every task, time entry, document, and financial record is associated with a project. Use the endpoints below to create, read, update, and delete projects, manage members, categories, planning snapshots, and more.

info

To access custom fields on projects, query the DynamicProject endpoint instead. It returns all standard properties plus any user-defined fields configured in your InLoox environment.


Data Model

PropertyTypeDescription
ProjectIdguidUnique identifier of the project.
NamestringDisplay name of the project.
NumberPrefixstringPrefix portion of the project number.
NumberIncrementialstringAuto-incremented portion of the project number.
NumberSuffixstringSuffix portion of the project number.
NumberstringFull computed project number (prefix + increment + suffix).
ClientIdguid?ID of the associated client / customer.
DivisionIdguid?ID of the division (business unit) this project belongs to.
ProjectStatusIdguid?ID of the current project status.
ComputedProgressdouble?Auto-calculated project progress (0.0–1.0).
Priorityint?Priority level of the project.
LockModeint?Lock mode flag. Controls how the project is locked.
IsLockedboolWhether the project is currently locked for editing.
StartDatedatetime?Actual start date of the project.
EndDatedatetime?Actual end date of the project.
PlannedStartDatedatetime?Planned start date.
PlannedEndDatedatetime?Planned end date.
IsEndDateFixedboolWhether the end date is fixed and should not shift during scheduling.
PrivateboolIf true, only assigned members can see this project.
IsRecycledboolWhether the project has been moved to the recycle bin.
IsArchivedboolWhether the project is archived.
IsRequestboolWhether this project is still a request (not yet approved).
CreatedByContactIdguid?ID of the contact who created the project.
ChangedByContactIdguid?ID of the contact who last modified the project.
ImageIdguid?ID of the project image/avatar.
PortfolioIdguid?ID of the portfolio this project belongs to.
DescriptionTextstringPlain-text project description.
DescriptionHTMLstringHTML-formatted project description.
CategoriesstringComma-separated list of assigned category names.
NotestringProject notes (plain text).
BackwardSchedulingboolIf true, the project is scheduled backward from the end date.

Endpoints

CRUD Operations

GET/odata/Project

List all projects

Returns a collection of all projects the authenticated user has access to. Supports OData query options such as $filter, $select, $orderby, $top, and $skip.


GET/odata/Project({key})

Get a single project by ID

ParameterTypeRequiredDescription
keyguidThe unique project ID.

POST/odata/Project

Create a new project

Send a JSON body with the project properties. At minimum, provide a Name.

{
"Name": "Website Redesign",
"PlannedStartDate": "2025-03-01T00:00:00Z",
"PlannedEndDate": "2025-06-30T00:00:00Z",
"Private": false
}
tip

Omit ProjectId to let the server generate one automatically, or supply your own GUID.


PATCH/odata/Project({key})

Update an existing project

ParameterTypeRequiredDescription
keyguidThe project ID to update.

Send only the properties you want to change.

{
"Name": "Website Redesign v2",
"Priority": 1
}

DELETE/odata/Project({key})

Delete a project

ParameterTypeRequiredDescription
keyguidThe project ID to delete.
warning

Deleting a project permanently removes it and all associated data (tasks, time entries, documents, etc.). This action cannot be undone.


GET/odata/Project/$count

Get total number of projects

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


Members & Contacts

POST/odata/Project({key})/AddMember

Add a member to the project

ParameterTypeRequiredDescription
keyguidThe project ID.
{
"ContactId": "a1b2c3d4-...",
"RoleId": "e5f6a7b8-..."
}

POST/odata/Project({key})/RemoveMember

Remove a member from the project

ParameterTypeRequiredDescription
keyguidThe project ID.
{
"ContactId": "a1b2c3d4-..."
}

GET/odata/Project({key})/GetProjectContactRelations()

Get all contact relations for a project

ParameterTypeRequiredDescription
keyguidThe project ID.

Returns a list of contacts associated with the project, including their roles.


Categories

GET/odata/Project({key})/GetAssignedCategories()

Get categories assigned to a project

ParameterTypeRequiredDescription
keyguidThe project ID.

POST/odata/Project({key})/SetCategories

Set categories on a project (replaces existing)

ParameterTypeRequiredDescription
keyguidThe project ID.
{
"CategoryIds": ["cat-id-1", "cat-id-2"]
}
info

SetCategories replaces all existing category assignments. To add or remove a single category, use AssignCategory or UnAssignCategory instead.


GET/odata/Project({key})/AssignCategory(categoryId={categoryId})

Assign a single category to the project

ParameterTypeRequiredDescription
keyguidThe project ID.
categoryIdguidThe category ID to assign.

GET/odata/Project({key})/UnAssignCategory(categoryId={categoryId})

Remove a single category from the project

ParameterTypeRequiredDescription
keyguidThe project ID.
categoryIdguidThe category ID to remove.

Notes

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

Add a note to the project

ParameterTypeRequiredDescription
keyguidThe project ID.
{
"Text": "Kickoff meeting scheduled for next Monday."
}

POST/odata/Project({key})/DeleteNote

Delete a note from the project

ParameterTypeRequiredDescription
keyguidThe project ID.
{
"NoteRelationId": "note-relation-guid"
}

Project Number

POST/odata/Project({key})/UpdateProjectNumber

Update the project number components

ParameterTypeRequiredDescription
keyguidThe project ID.
{
"NumberPrefix": "PRJ",
"NumberIncremential": "0042",
"NumberSuffix": "-A"
}

GET/odata/Project({key})/CheckIfProjectNumberExists(projectNumber={projectNumber})

Check whether a project number is already in use

ParameterTypeRequiredDescription
keyguidThe project ID (context).
projectNumberstringThe full project number to check.

Returns true if the number already exists, false otherwise.


GET/odata/Project({key})/CorrectIncrementIfNecessary(projectNumber={projectNumber})

Auto-correct the incremental part to avoid duplicates

ParameterTypeRequiredDescription
keyguidThe project ID.
projectNumberstringThe project number to validate.

Status & Actions

POST/odata/Project({key})/ApproveRequest

Approve a project request

ParameterTypeRequiredDescription
keyguidThe project ID (must be a request).

Converts a project request into an active project.


POST/odata/Project({key})/RejectRequest

Reject a project request

ParameterTypeRequiredDescription
keyguidThe project ID (must be a request).

GET/odata/Project({key})/ToggleFavorite(isFavorite={isFavorite})

Add or remove a project from favorites

ParameterTypeRequiredDescription
keyguidThe project ID.
isFavoriteboolSet to true to mark as favorite, false to remove.

GET/odata/Project({key})/CopyProject()

Create a copy of the project

ParameterTypeRequiredDescription
keyguidThe source project ID to copy.

Returns the newly created project.


GET/odata/Project({key})/GenerateImage()

Generate a project image

ParameterTypeRequiredDescription
keyguidThe project ID.

GET/odata/Project({key})/GenerateProjectDescription(language={language})

Auto-generate a project description

ParameterTypeRequiredDescription
keyguidThe project ID.
languagestringLanguage code for the generated description (e.g., 'en', 'de').

Planning Snapshots

Planning snapshots let you capture and compare the state of a project plan at a specific point in time.

GET/odata/Project({key})/CreatePlanningSnapshot(name={name})

Create a new planning snapshot

ParameterTypeRequiredDescription
keyguidThe project ID.
namestringName for the snapshot (e.g., 'Baseline Q1').

POST/odata/Project({key})/DeletePlanningSnapshot

Delete an existing planning snapshot

ParameterTypeRequiredDescription
keyguidThe project ID.
{
"SnapshotId": "snapshot-guid"
}

POST/odata/Project({key})/RenamePlanningSnapshot

Rename an existing planning snapshot

ParameterTypeRequiredDescription
keyguidThe project ID.
{
"SnapshotId": "snapshot-guid",
"Name": "Updated Baseline Name"
}

Project Groups

POST/odata/Project({key})/AddProjectGroup

Add a new group to the project

ParameterTypeRequiredDescription
keyguidThe project ID.
{
"Name": "Phase 1"
}

POST/odata/Project({key})/DeleteProjectGroup

Delete a project group

ParameterTypeRequiredDescription
keyguidThe project ID.
{
"GroupId": "group-guid"
}

POST/odata/Project({key})/SetProjectGroupColor

Set the color of a project group

ParameterTypeRequiredDescription
keyguidThe project ID.
{
"GroupId": "group-guid",
"Color": "#FF5733"
}

Relations

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

Add a relation to another entity

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

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

Remove an existing relation

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

Notification Followers

Notification followers receive updates when the project changes.

POST/odata/Project({key})/AddNotificationFollowers

Add notification followers to the project

ParameterTypeRequiredDescription
keyguidThe project ID.
{
"ContactIds": ["contact-id-1", "contact-id-2"]
}

POST/odata/Project({key})/RemoveNotificationFollower

Remove a notification follower

ParameterTypeRequiredDescription
keyguidThe project ID.
{
"ContactId": "contact-guid"
}

GET/odata/Project({key})/GetNotificationFollowerContacts()

Get all notification followers for a project

ParameterTypeRequiredDescription
keyguidThe project ID.

Custom Fields — DynamicProject

The standard Project endpoint only returns built-in properties. To read or write custom fields (user-defined fields configured in InLoox), use the DynamicProject endpoint instead:

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

DynamicProject returns all standard project properties plus any custom fields. Custom field names follow the pattern CF_<FieldName>.

warning

DynamicProject only supports GET requests. To create or update projects, use the regular /odata/Project endpoints.


OData Query Examples

Filtering & Selecting

Retrieve active projects that are not archived, selecting only key fields:

curl -X GET "https://{tenant}.inloox.app/odata/Project?\
$filter=IsArchived eq false and IsRecycled eq false\
&$select=ProjectId,Name,Number,StartDate,EndDate,ComputedProgress\
&$orderby=Name asc\
&$top=50" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"

Paging

Use $top and $skip for server-side paging:

# Page 1
curl -X GET "https://{tenant}.inloox.app/odata/Project?$top=20&$skip=0" \
-H "Authorization: Bearer {token}"

# Page 2
curl -X GET "https://{tenant}.inloox.app/odata/Project?$top=20&$skip=20" \
-H "Authorization: Bearer {token}"

Filtering by Date

curl -X GET "https://{tenant}.inloox.app/odata/Project?\
$filter=PlannedStartDate ge 2025-01-01T00:00:00Z\
and PlannedEndDate le 2025-12-31T23:59:59Z" \
-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);

// List active projects
var response = await client.GetAsync(
"https://{tenant}.inloox.app/odata/Project?" +
"$filter=IsArchived eq false and IsRecycled eq false" +
"&$select=ProjectId,Name,Number,ComputedProgress" +
"&$orderby=Name asc&$top=100");

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

// Create a project
var payload = new StringContent(
"""{"Name":"New API Project","Private":false}""",
System.Text.Encoding.UTF8,
"application/json");

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

Use $select to request only the properties you need. This reduces response size and improves performance, especially for large project lists.