Skip to main content

Getting Started with the InLoox API

This guide helps you set up authentication, understand OData basics, and send your first API request.


Prerequisites

Before you begin, you need:

  • An active InLoox account (Cloud or Self-Hosted)
  • An HTTP client like cURL, Postman, or a programming language of your choice
  • A valid Personal Access Token (PAT)
Create a Token

In InLoox, click your profile picture in the top-right corner, then click My Profile, followed by the Personal Access Tokens tab. Click New Token. Enter a token name, select an account (if you have access to multiple accounts), and click Create New Token. Copy the generated token — it is only displayed once.

info

Please note that the user permission "Allow authentication via personal access token" is required to use the token. The token can only be used once this permission has been granted. This permission is cached. It may take up to 1 hour for the permission to become active.

Protect Your Token

Your Personal Access Token grants full API access on your behalf. Treat it like a password — never commit it to version control and do not share it publicly.

A token is as powerful as the user it belongs to. For production environments, it is recommended to create a dedicated service user account with permissions restricted to the minimum required scope.


Authentication

The InLoox API uses Personal Access Tokens for authentication. Include your token with every request as an x-api-key HTTP header.

cURL

curl -X GET "https://app.inloox.com/api/odata/Project" \
-H "x-api-key: YOUR_API_TOKEN"

C# (HttpClient)

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", "YOUR_API_TOKEN");

var response = await client.GetAsync("https://app.inloox.com/api/odata/Project");
var json = await response.Content.ReadAsStringAsync();
Console.WriteLine(json);

C# (Simple.OData.Client)

var settings = new ODataClientSettings(new Uri("https://app.inloox.com/api/odata/"));
settings.BeforeRequest += delegate (HttpRequestMessage message)
{
message.Headers.Add("x-api-key", "YOUR_API_TOKEN");
};
var client = new ODataClient(settings);

JavaScript (fetch)

const response = await fetch("https://app.inloox.com/api/odata/Project", {
headers: {
"x-api-key": "YOUR_API_TOKEN"
}
});
const data = await response.json();
console.log(data);
Verify Your Token

A quick way to test your token is to call the AccountInfo endpoint:

curl -X GET "https://app.inloox.com/api/odata/AccountInfo" \
-H "x-api-key: YOUR_API_TOKEN"

On successful authentication, you will receive the account information, including the AccountId and account name.

Example: Retrieve Current User Profile

Use the UserInfo/Me() endpoint to retrieve the profile of the currently authenticated user:

curl -X GET "https://app.inloox.com/api/odata/UserInfo/Me()" \
-H "x-api-key: YOUR_API_TOKEN"

Response:

{
"ContactId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"FirstName": "John",
"LastName": "Doe",
"DisplayName": "John Doe",
"Email": "john.doe@example.com",
"ImageId": null,
"NotifyFrequency": 1,
"TimeZoneInfo": "W. Europe Standard Time",
"EmailConfirmed": true,
"IsReader": false,
"UILanguage": "en-US"
}
Note

To use the API with full read and write access, your account must have "EmailConfirmed": true and "IsReader": false. Users with an unconfirmed email address or a Read-Only license (IsReader: true) have limited API access.


Base URL

All API requests are made against a base URL that depends on your deployment:

DeploymentBase URL
InLoox Cloudhttps://app.inloox.com/api/
InLoox Self-Hostedhttps://YOUR-SELF-HOSTED-URL/api/v1/

All endpoint paths in this documentation are relative to the base URL. For example:

GET /odata/Project

means the full URL for the Cloud is https://app.inloox.com/api/odata/Project.


OData Basics

The InLoox API is based on the OData protocol (Open Data Protocol). OData provides a standardized query language that allows you to filter, sort, select, and paginate data — directly via the URL.

What is OData?

OData is an open standard for building and consuming REST APIs. It defines proven patterns for queries controlled through URL parameters ($filter, $select, $orderby, etc.). This allows you to precisely control what data you receive without requiring special endpoints.

Supported HTTP Methods

MethodUsage
GETRead entities or collections
POSTCreate new entities or invoke actions
PATCHUpdate existing entities (partial update)
DELETEDelete entities

Query Options

OData supports powerful query options as URL parameters. These allow you to filter, sort, paginate, and shape the data returned by the API.


$filter - Filter Data

Use $filter to restrict the returned records based on conditions.

Filter projects by name:

curl -X GET "https://app.inloox.com/api/odata/Project?\$filter=Name eq 'My Project'" \
-H "x-api-key: YOUR_API_TOKEN"

Projects created after a specific date:

curl -X GET "https://app.inloox.com/api/odata/Project?\$filter=CreatedDateTime gt 2024-01-01T00:00:00Z" \
-H "x-api-key: YOUR_API_TOKEN"

Combine multiple conditions (and / or):

curl -X GET "https://app.inloox.com/api/odata/Project?\$filter=IsArchived eq false and Name ne 'Archived'" \
-H "x-api-key: YOUR_API_TOKEN"

Common filter operators:

OperatorMeaningExample
eqEqualName eq 'Test'
neNot equalStatus ne 'Closed'
gtGreater thanCreatedDateTime gt 2024-01-01T00:00:00Z
ltLess thanProgress lt 50
geGreater than or equalProgress ge 80
leLess than or equalProgress le 100
andLogical ANDIsArchived eq false and Progress gt 0
orLogical ORStatus eq 'Open' or Status eq 'InProgress'
contains()Containscontains(Name, 'Marketing')
startswith()Starts withstartswith(Name, 'Project')
String Values in Filters

String values must be enclosed in single quotes: Name eq 'My Project'. GUIDs and dates do not require quotes.

// C# with Simple.OData.Client
var projects = await client
.For<ApiProject>("Project")
.Filter(p => p.Name == "Website Redesign")
.FindEntriesAsync();

$select - Select Fields

Use $select to specify which properties are returned in the response. This reduces the payload size and improves performance.

curl -X GET "https://app.inloox.com/api/odata/Project?\$select=ProjectId,Name,StartDate,EndDate" \
-H "x-api-key: YOUR_API_TOKEN"

C# example:

var response = await client.GetAsync("Project?$select=ProjectId,Name,StartDate");
// C# with Simple.OData.Client
var projects = await client
.For<ApiProject>("Project")
.Select(p => new { p.ProjectId, p.Name })
.FindEntriesAsync();

$orderby - Sorting

Use $orderby to sort results by one or more properties.

Sort ascending (default):

curl -X GET "https://app.inloox.com/api/odata/Project?\$orderby=Name" \
-H "x-api-key: YOUR_API_TOKEN"

Sort descending:

curl -X GET "https://app.inloox.com/api/odata/Project?\$orderby=CreatedDateTime desc" \
-H "x-api-key: YOUR_API_TOKEN"

Multiple sort criteria:

curl -X GET "https://app.inloox.com/api/odata/Project?\$orderby=IsArchived desc,Name asc" \
-H "x-api-key: YOUR_API_TOKEN"
// C# with Simple.OData.Client
var projects = await client
.For<ApiProject>("Project")
.OrderBy(p => p.StartDate)
.FindEntriesAsync();

$top and $skip - Paging

Use $top and $skip to retrieve results page by page.

ParameterDescriptionExample
$topMaximum number of entries returned$top=20
$skipNumber of entries to skip$skip=40

First 20 projects:

curl -X GET "https://app.inloox.com/api/odata/Project?\$top=20" \
-H "x-api-key: YOUR_API_TOKEN"

Page 3 (items 41–60):

curl -X GET "https://app.inloox.com/api/odata/Project?\$top=20&\$skip=40" \
-H "x-api-key: YOUR_API_TOKEN"
// C# with Simple.OData.Client
var page2 = await client
.For<ApiProject>("Project")
.Skip(10)
.Top(10)
.FindEntriesAsync();

Combining Query Options

You can combine multiple query options in a single request:

# Top 5 open tasks in a project, sorted by due date, key fields only
curl "https://app.inloox.com/api/odata/Task?\$filter=ProjectId eq {projectId} and IsDone eq false&\$orderby=EndDateTime asc&\$top=5&\$select=TaskItemId,Name,EndDateTime" \
-H "x-api-key: YOUR_API_TOKEN"

Pagination

The API returns a maximum of 100 items per request by default. To retrieve all records, you need to paginate through the pages.

Pagination Strategy

  1. Send a request with $top
  2. Check whether the response contains an @odata.nextLink field
  3. If so, send the next request to the URL specified in @odata.nextLink
  4. Repeat until no @odata.nextLink is present

How Pagination Works

When more results are available, the response contains an @odata.nextLink property with the URL for the next page:

{
"@odata.context": "https://app.inloox.com/api/odata/$metadata#Project",
"value": [ ... ],
"@odata.nextLink": "https://app.inloox.com/api/odata/Project?$skip=100"
}

Manual Pagination with $top and $skip

# Page 1 (entries 1–100)
curl "https://app.inloox.com/api/odata/Project?\$top=100&\$skip=0" \
-H "x-api-key: YOUR_API_TOKEN"

# Page 2 (entries 101–200)
curl "https://app.inloox.com/api/odata/Project?\$top=100&\$skip=100" \
-H "x-api-key: YOUR_API_TOKEN"

# Page 3 (entries 201–300)
curl "https://app.inloox.com/api/odata/Project?\$top=100&\$skip=200" \
-H "x-api-key: YOUR_API_TOKEN"

Manual Paging Example (C#)

var allProjects = new List<ApiProject>();
int skip = 0;
const int pageSize = 100;

while (true)
{
var response = await client.GetAsync($"Project?$top={pageSize}&$skip={skip}");
var json = await response.Content.ReadAsStringAsync();
var page = JsonSerializer.Deserialize<ODataResponse<ApiProject>>(json);

allProjects.AddRange(page.Value);

if (page.Value.Count < pageSize)
break;

skip += pageSize;
}

Console.WriteLine($"Total {allProjects.Count} projects loaded.");

Pagination with Simple.OData.Client (C#)

The ODataFeedAnnotations class handles pagination automatically:

var allEntries = new List<ApiProject>();
var annotations = new ODataFeedAnnotations();

var page = (await client
.For<ApiProject>("Project")
.FindEntriesAsync(annotations)).ToList();

allEntries.AddRange(page);

while (annotations.NextPageLink != null)
{
page = (await client
.For<ApiProject>("Project")
.FindEntriesAsync(annotations.NextPageLink, annotations)).ToList();
allEntries.AddRange(page);
}

Console.WriteLine($"Total projects loaded: {allEntries.Count}");
Performance Note

When retrieving large datasets, use $filter to narrow the query instead of paginating through all records. This reduces both network traffic and server load.


Response Format

All API responses use JSON with OData metadata annotations. A typical collection response looks like this:

{
"@odata.context": "https://app.inloox.com/api/odata/$metadata#Project",
"value": [
{
"ProjectId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"Name": "Website Relaunch",
"StartDate": "2024-01-15T00:00:00Z",
"EndDate": "2024-06-30T00:00:00Z"
}
]
}

Key elements:

PropertyDescription
@odata.contextURL to the entity metadata schema
valueArray of entities (for collections)
@odata.nextLinkURL of the next page (when more data is available)

A single-entity response (e.g., GET Project({key})) returns the entity directly without the value wrapper:

{
"@odata.context": "https://app.inloox.com/api/odata/$metadata#Project/$entity",
"ProjectId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"Name": "Website Relaunch",
"StartDate": "2024-01-15T00:00:00Z",
"EndDate": "2024-06-30T00:00:00Z"
}

Error Handling

The API uses standard HTTP status codes to indicate the success or failure of a request.

Status CodeMeaningDescription
200 OKSuccessThe request was successful.
201 CreatedCreatedA new resource was successfully created.
204 No ContentNo ContentThe request was successful, there is no return data (e.g., for DELETE).
400 Bad RequestBad RequestThe request is invalid — check the parameters and request body.
401 UnauthorizedUnauthorizedThe API token is missing or invalid.
403 ForbiddenForbiddenYou do not have permission for this resource.
404 Not FoundNot FoundThe requested resource does not exist.
429 Too Many RequestsRate LimitedToo many requests in a short period.
500 Internal Server ErrorServer ErrorAn internal error occurred — contact support.

Error Response Example

{
"error": {
"code": "400",
"message": "The query specified in the URI is not valid. Could not find a property named 'InvalidField' on type 'ApiProject'."
}
}
Troubleshooting Tips
  • 401 errors: Check whether the x-api-key header is set correctly and the token is valid.
  • 400 errors: Verify the syntax of your OData query and field names.
  • 404 errors: Ensure the base URL and endpoint path are correct.
  • Check the spelling of property names in $select, $filter, and $orderby if needed — they are case-sensitive.
  • Use the $metadata endpoint to inspect available entities and properties:
    GET https://app.inloox.com/api/odata/$metadata

Rate Limits

The InLoox API does not publish strict rate limits, but follow these best practices to avoid throttling:

  • Batch read operations — Use $filter and $select to minimize the number of requests
  • Do not poll aggressively — Wait at least a few seconds between repeated requests
  • Paginate efficiently — Follow @odata.nextLink instead of creating overlapping queries
  • Use caching — Cache results locally when data does not change frequently
note

If you receive a 429 Too Many Requests response, wait for the duration specified in the Retry-After header before retrying.


Next Steps

You are ready to get started! Here is where to go next: