Skip to main content

V3 Departments API

The V3 departments API is deprecated. The following routes will stop responding starting from September 2026:
  • GET /api/v3/departments
  • GET /api/v3/departments/{id}
  • GET /api/v3/departments/tree

V4 Departments API

The V4 departments API has no announced sunset date, but the Lucca API (V5) is the long-term strategic target.If you are on V3 and want a lower-friction interim step (same API-key authentication), you may migrate to V4 first — but a future migration to the V5 Lucca API will still be required.
The V5 Lucca API departments API endpoints are stable and will not undergo breaking changes. It supports both read and write operations. We recommend moving to the Lucca API as soon as possible to take advantage of its improved performance, richer data model, and long-term support.
The V3 GET /api/v3/departments/tree endpoint has no equivalent in the V5 Lucca API. It was removed because its tree structure made pagination impossible to enforce, causing serious performance issues in large organizations. To reconstruct a tree client-side, page through GET /lucca-api/departments and use each department’s parent.id field to build the hierarchy.

Before You Start: Switch to OAuth 2.0

Regardless of your starting version, the Lucca API requires an OAuth 2.0 bearer token in place of the legacy API key. Request the scope that matches your use case:
OperationRequired scope
Read departmentsdepartments.readonly
Create or update departmentsdepartments.readwrite
Read employees (for department membership)employees.readonly job-positions.readonly
Additionally, all requests must include the Api-Version: 2024-11-01 HTTP header.
A single OAuth 2.0 token can carry multiple scopes. Combine all the scopes you need in one token request — for example: scope=departments.readonly employees.readonly job-positions.readonly.

Authentication

How to obtain and use OAuth 2.0 bearer tokens with the Lucca authorization server.

Versioning

How to use the Api-Version header to specify the API version.

Pick Your Starting Version

Quick Start

1

Get an OAuth 2.0 token

Request a bearer token with the departments.readonly scope (add departments.readwrite if needed). See the auth section above.
2

Add the Api-Version header

Include Api-Version: 2024-11-01 on every request.
3

Replace the list endpoint

Swap GET /api/v3/departments?paging=0,1000 for GET /lucca-api/departments?include=links. Page through results using the cursor token in links.next.
4

Update your data model

Refer to the field mapping reference below for all changes.
5

Replace embedded user lists

The users, currentUsers, and currentUsersCount fields no longer appear on department objects. Use GET /lucca-api/employees?applicableJobPosition.department.id={id}&status=active&include=totalCount instead.

What Changes

  • Authentication: v3 uses a proprietary API key; the Lucca API uses OAuth 2.0 bearer tokens.
  • Versioning: requests must include the Api-Version: 2024-11-01 HTTP header.
  • isActiveisArchived: the boolean is semantically inverted.
  • coderemoteId.
  • parentId is now parent: was an opaque hierarchy path string (e.g. "/1/2/"); now a typed { id, type, url } reference object.
  • IDs become strings: integers in v3 (32), strings in v5 ("32").
  • No embedded users/currentUsers: use the links.activeEmployees or the employees API endpoint filtered by department ID.
  • Pagination: v3 used ?paging={offset},{limit}; the Lucca API uses cursor tokens. Max 100 items per page (default 25).
  • Write operations (new in v5): POST and PATCH are now available. v3 had no write endpoints.

Pagination

How cursor-based pagination works in the Lucca API.

Notable Breaking Changes

Pay close attention to these changes — some may cause silent data errors if overlooked.

isActive is now isArchived (inverted semantics)

v3v5Meaning
isActive: trueisArchived: falseDepartment is in use
isActive: falseisArchived: trueDepartment is no longer in use
A department can only be archived when no employees are currently attached to it.

IDs became strings in v5

// v3: integer
{ "id": 32 }

// v5: string
{ "id": "32" }
The numeric value is preserved. Update any code that stores or compares department IDs to treat them as strings.

parent became a typed reference object in v5

In v3, parentId in the response was an opaque hierarchy path string (e.g. "/1/2/"), not a numeric ID. In v5, the parent is a typed reference:
// v3 response
{ "parentId": "/1/2/" }

// v5 response
{ "parent": { "id": "12", "type": "department", "url": "https://example.ilucca.net/lucca-api/departments/12" } }
Root-level departments have "parent": null. Use parent.id to navigate the hierarchy.

Field code was renamed remoteId

Map v3 code to v5 remoteId. Use it for external identifiers.

Embedded users and currentUsers fields were removed

v3 department objects included users, currentUsers, and currentUsersCount directly on the department. In v5, you may either follow the activeEmployees link (only returned when include=links is specified) or build the link to the employees endpoint manually:
ActiveEmployees link
{
  "id": "32",
  ...,
  "links": {
    "activeEmployees": {
      "href": "https://example.ilucca.net/lucca-api/employees?applicableJobPosition.department.id=32&status=active&include=totalCount"
    }
  }
}
Building the link manually
GET /lucca-api/employees?applicableJobPosition.department.id={DEPARTMENT_ID}&status=active&include=links,totalCount HTTP/1.1
Host: example.ilucca.net
Authorization: Bearer {ACCESS_TOKEN}
Api-Version: 2024-11-01
The totalCount in the response is the equivalent of currentUsersCount. Each department also exposes a pre-built links.activeEmployees.href pointing to this query.

Migration by Use Case

1. List All Departments

GET /api/v3/departments?paging=0,1000 HTTP/1.1
Host: example.ilucca.net
Authorization: lucca application={API_KEY}
Accept: application/json

{
  "data": {
    "items": [
      {
        "id": 32,
        "name": "Finances",
        "code": "FIN",
        "hierarchy": "/1/",
        "parentId": null,
        "isActive": true,
        "level": 1,
        "sortOrder": 1,
        "headID": 416,
        "currentUsersCount": 12
      }
    ]
  }
}
The v5 department.id value is numerically the same as the v3 value, though v5 represents it as a string ("32") rather than an integer (32) in JSON.

2. Retrieve a Department by ID

GET /api/v3/departments/32 HTTP/1.1
Host: example.ilucca.net
Authorization: lucca application={API_KEY}
Accept: application/json

{
  "data": {
    "id": 32,
    "name": "Finances",
    "code": "FIN",
    "hierarchy": "/1/",
    "parentId": null,
    "isActive": true,
    "level": 1,
    "sortOrder": 1,
    "headID": 416
  }
}

3. Filter by Active / Archived Status

Intentv3v5
Active onlyFilter client-side on isActive: true?isArchived=false
Inactive onlyFilter client-side on isActive: false?isArchived=true
AllAll returned by defaultSame behavior (omit isArchived)

4. Navigate the Hierarchy

V3 supported a ?parentId={integer} query filter to retrieve direct children of a department. v5 has no server-side equivalent — page through all departments and group by parent.id client-side. The level field (1 = root) and sortOrder (0-based among siblings) help reconstruct the correct display order.

5. Find Employees in a Department

V3 embedded currentUsers directly on each department object. In v5, use activeEmployees link (to obtain it, add ?include=links) or query the employees endpoint directly:
GET /lucca-api/employees?applicableJobPosition.department.id=32&status=active&include=links,totalCount HTTP/1.1
Host: example.ilucca.net
Authorization: Bearer {ACCESS_TOKEN}
Api-Version: 2024-11-01
The totalCount field in the response is the equivalent of the old currentUsersCount.
You need the employees.readonly and job-positions.readonly scopes to query the employees endpoint, even if you only want the count.

Field Mapping Reference

v3 fieldv5 fieldNotes
ididString in v5 (integer in v3)
(new in v5)typeAlways "department"
urlurlSelf-link URI
namename
descriptiondescription
coderemoteId
hierarchy(removed)Opaque internal path; do not parse or store
parentIdparentNow a { id, type, url } reference (null if root)
isActiveisArchivedSemantics inverted
position(removed)Replaced by level and sortOrder
levellevelMin 1 in v5; root = 1
sortOrdersortOrder0-based index among siblings in v5
headIDmanagerNow a { id, type, url } reference
head (SimpleUser)managerFull reference object in v5
owningApplicationowningApplicationSet by Lucca apps; write attempts rejected with 403 if set
users(removed)Query the employees endpoint
currentUsers(removed)Use links.activeEmployees or query the employees endpoint
currentUsersCount(removed)Add ?include=totalCount to the employee query
(new in v5)links.activeEmployeesPre-built link to active employees in this department

Writing Departments (New in v5)

Neither v3 nor v4 officially exposed write endpoints. The Lucca API introduces POST (create) and PATCH (update) operations, both requiring the departments.readwrite scope.
There is no DELETE endpoint for departments. To decommission a department, set isArchived: true via PATCH. A department can only be archived when no employees are currently attached to it.

Create a Department

V5
POST /lucca-api/departments HTTP/1.1
Host: example.ilucca.net
Authorization: Bearer {ACCESS_TOKEN}
Api-Version: 2024-11-01
Content-Type: application/json

{
  "name": "Legal",
  "description": "Legal & Compliance team",
  "remoteId": "LEGAL",
  "parent": { "id": "32" },
  "manager": { "id": "420" },
  "sortOrder": 0
}
On success, the server responds with 201 Created, the full department representation, and a Location header pointing to the new resource URL.

Update a Department

Use PATCH with a partial body — only the fields you include will be updated:
V5
PATCH /lucca-api/departments/55 HTTP/1.1
Host: example.ilucca.net
Authorization: Bearer {ACCESS_TOKEN}
Api-Version: 2024-11-01
Content-Type: application/json

{
  "name": "Legal & Compliance",
  "manager": { "id": "421" }
}

Further Reading

Lucca API Introduction

Overview of the Lucca API, versioning, and pagination.

V5 Department Reference

Full reference for the Lucca API department resource.

Authentication

How to obtain and use OAuth 2.0 bearer tokens.

Pagination

Cursor-based pagination in the Lucca API, with examples.

Rate Limits

Rate and size limits applied to the Lucca API.