Skip to main content
The v3 users API is a monolithic, read/write endpoint that exposes the current state of employees as a flat JSON object. It is now deprecated in favour of the Lucca API (v5), which introduces a richer, historized model split across several dedicated resources.
As of today, this migration is only applicable to read-only integration scenarios. The Lucca API employee resources (/lucca-api/employees, /lucca-api/employments, /lucca-api/job-positions, and /lucca-api/employee-attributes) are currently read-only. If your integration writes to /api/v3/users (creates, updates, or deletes users), it cannot be migrated to the Lucca API at this time and you should keep using the v3 endpoint until a write API becomes available.
No sunset date has been announced for /api/v3/users yet. Make sure your API key has a valid contact email address so you receive deprecation notices when a date is set.
If your integration uses /directory/api/4.0/work-contracts, see the dedicated work-contracts migration guide.

Quick Start (TL;DR)

1

Switch to OAuth 2.0

Replace your API key header (Authorization: lucca application=...) with an OAuth 2.0 bearer token. Request the scopes you need (e.g. employees.readonly, employee-attributes.readonly).
2

Add the Api-Version header

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

Replace /api/v3/users with /lucca-api/employees

GET /lucca-api/employees?status=active,upcoming returns the same set of active employees.
4

Use employee-attributes for specific fields

Instead of ?fields=..., query GET /lucca-api/employee-attributes?definition.id=employment.start,jobPosition.department,...&applicability.asOf={TODAY} to retrieve any property in a single call. See the Field Mapping Reference for the full translation table.

What Changes

Legacy (v3): /api/v3/users

A single endpoint returning a flat representation of the current state of an employee, combining identity, contract, position, personal data, and application-specific fields.

Lucca API (v5): multiple resources

The employee model is split across several dedicated, historized resources. A unified read endpoint (/lucca-api/employee-attributes) lets you query any property in a consistent way.
The key differences are:
  • Authentication: v3 uses a proprietary API key scheme; the Lucca API uses OAuth 2.0 bearer tokens. Refer to the authentication guide for details.
  • Versioning: requests to the Lucca API must include the Api-Version: 2024-11-01 HTTP header.
  • Historized model: rather than a snapshot of the current state, the Lucca API tracks the full career history of an employee (multiple employments, multiple job-positions over time).
  • Field selection: the v3 ?fields= mechanism is replaced either by querying the relevant sub-resource directly, or by using the employee-attributes endpoint with a definition.id filter.
  • Pagination: collection endpoints use cursor-based pagination (?include=links&limit={page_size}&page={page_token}). Max 1000 items per page (default 25). See the pagination guide and limits documentation below.

Pagination

Learn how to paginate through collection endpoints in the Lucca API.

Rate Limits

Learn about the rate and size limits applied to the Lucca API and best practices to design your integration accordingly.

First: Switch to OAuth 2.0 and Set the Api-Version Header

First of all, replace your API key header with an OAuth 2.0 bearer token obtained from the Lucca authorization server. You will need to request the appropriate scopes for the resources you intend to read:
ResourceRequired scope
employeeemployees.readonly
employee-personal-recordemployee-personal-records.readonly
employmentemployments.readonly
job-positionjob-positions.readonly
employee-attributes (values)employee-attributes.readonly
employee-attributes (definitions)employee-attribute-definitions.readonly
The employee-attribute-definitions.readonly scope is only needed if you want to discover attribute IDs programmatically (e.g. to enumerate all custom fields via GET /lucca-api/employee-attribute-definitions). If your integration already knows the definition IDs it needs, employee-attributes.readonly is sufficient.
A single OAuth 2.0 token can carry multiple scopes. When requesting your token, combine all the scopes you need in one request — for example: scope=employees.readonly employee-attributes.readonly employee-personal-records.readonly. You do not need a separate token per resource.
Additionally, the v5 Lucca API is versioned, so you must include the Api-Version: {VERSION} HTTP header in all your requests. Currently, the latest version is 2024-11-01.

Authentication

Read more about how to obtain and use OAuth 2.0 bearer tokens.

Versioning

Read more about how to use the Api-Version header to specify the API version.

The New Data Model

The legacy user object is split across the following Lucca API resources:
1

Employee

The employee resource holds the public-facing identity of an employee: name, email, employee number, profile picture, and status. It also exposes applicableJobPosition and applicableEmployment references, which point to the employee’s current position and contract respectively.
2

Employee Personal Record

The employee-personal-record resource holds private personal data: birth date, personal email, phone number, bank account details, nationality, gender, and more. Access requires appropriate OAuth scopes and directory section permissions.
3

Employment

The employment resource represents the contractual relationship between an employee and a legal entity. It carries the contract start and end dates, and replaces the legacy dtContractStart / dtContractEnd fields.
4

Job Position

The job-position resource represents a position occupied by an employee during an employment: department, manager, business establishment, job title, job qualification, occupation category, and more. An employee may hold several successive job positions over the course of a single employment.
5

Employee Attributes (unified read endpoint)

The employee-attributes endpoint surfaces any property from any of the above resources — including custom extension fields — in a single, uniform query. This is the recommended starting point for read-only integrations that previously used GET /api/v3/users?fields=....
Use the Field Mapping Reference below to translate every legacy v3 field name to its new employee-attribute definition ID. Before doing so, review the notable breaking changes — several field names are semantically ambiguous or changed type in ways the table alone won’t make obvious.

Migration by Use Case

1. Retrieve Users

The v3 GET /api/v3/users endpoint returns a list of all active and upcoming employees. It automatically excludes former employees. In the Lucca API, use GET /lucca-api/employees?status=active,upcoming to retrieve the same list of active employees. To include former employees (i.e. “deactivated”) as well, then omit the status filter. For reference, the employee (v5) status can be:
  • active: the employee has an active employment (current date is between the start and end dates of one of their employments);
  • upcoming: the employee has no active employment, but at least one future employment (start date is in the future);
  • deactivated: the employee has no active nor future employment (all employments ended in the past).
GET /api/v3/users?fields=id,firstName,lastName,mail,dtContractStart,dtContractEnd HTTP/1.1
Host: example.ilucca.net
Authorization: lucca application={API_KEY}
Accept: application/json
The v3 ?fields= mechanism is not available in the Lucca API. To retrieve specific fields, either query the relevant sub-resource directly (e.g. GET /lucca-api/employee-personal-records/{employeeId} to get personal data), or use the employee-attributes endpoint (more below) with a definition.id filter to retrieve any property in a single call.
When fetching a single user by ID, the v3 endpoint is GET /api/v3/users/{id}. In the Lucca API, use GET /lucca-api/employees/{id}.
The v5 employee.id value is the same as the v3 user.id, though note that v5 represents IDs as strings ("416") rather than integers (416) in JSON.
GET /api/v3/users/416?fields=id,firstName,lastName,mail,dtContractStart,dtContractEnd HTTP/1.1
Host: example.ilucca.net
Authorization: lucca application={API_KEY}
Accept: application/json

{ "id": 416, ... }

2. Retrieve the Current Employment and Job Position

In v3, contract dates and position data were flat properties of the user object. In the Lucca API, new API resources appear: employment and job-position. To retrieve the current employment and job position, use the applicableJobPosition and applicableEmployment references in the employee response. You may either follow their URLs to get the full details, or use the ?include=embedded mechanism to inline them directly in the employee response. Lastly, you can also retrieve them via the employee-attributes endpoint, which is the recommended approach for bulk reads.
The ?include= query parameter accepts a comma-separated list of options:
  • embedded — inlines the full representation of referenced resources directly in the response;
  • links — adds pagination links (links.next, links.prev) and relation links to the response;
  • totalCount — includes the total count of items across all pages.
You can combine them: ?include=embedded,links.

2.1. Via the employee Endpoint (embedded references)

Add ?include=embedded to the GET employee request. This tells the server to inline the full representation of the referenced employment and job-position resources directly in the response, so you do not need to make additional requests to follow their URLs.
GET /api/v3/users/416?fields=id,dtContractStart,dtContractEnd,department[id,name] HTTP/1.1
Host: example.ilucca.net
Authorization: lucca application={API_KEY}
Accept: application/json

{
  "id": 416,
  "dtContractStart": "2020-01-15",
  "dtContractEnd": null,
  "department": {
    "id": 5,
    "name": "Sales"
  },
  ...
}
Rather than embedding them, you may also follow their URLs to get full employment and job-position details.

Includes in v5

Learn more about how to use the ?include=embedded mechanism to inline referenced resources directly in the response.

2.2. Via the employee-attributes Endpoint

The employee-attributes endpoint is the recommended way to retrieve employee data in bulk. It allows you to query any property of an employee — including properties of related resources like employment and job-position — in a single, uniform way. To retrieve attributes of related resources, just include their definition IDs in the definition.id filter.
The applicability.asOf parameter is required when querying time-bounded resources like employment or job-position. Without it, the endpoint may return multiple historical values per attribute (e.g. every job position an employee ever held). Always pass today’s date to retrieve each employee’s current state.
GET /lucca-api/employee-attributes?employee.id={EMPLOYEE_ID}&applicability.asOf={TODAY}&definition.id=employment.start,employment.end,jobPosition.department,jobPosition.manager HTTP/1.1
Host: example.ilucca.net
Authorization: Bearer {ACCESS_TOKEN}
Api-Version: 2024-11-01
Accept: application/json

{
  "type": "employee-attributes",
  "items": [
    {
      "id": "34879",
      "type": "employee-attribute",
      "definition": { "id": "employment.start", "type": "employee-attribute-definition" },
      "employee": { "id": "416", "type": "employee" },
      "applicability": { "start": "2020-01-15", "end": null },
      "value": { "date": "2020-01-15" }
    },
    {
      "id": "7412",
      "type": "employee-attribute",
      "definition": { "id": "employment.end", "type": "employee-attribute-definition" },
      "employee": { "id": "416", "type": "employee" },
      "applicability": { "start": "2020-01-15", "end": null },
      "value": null
    },
    {
      "id": "51903",
      "type": "employee-attribute",
      "definition": { "id": "jobPosition.department", "type": "employee-attribute-definition" },
      "employee": { "id": "416", "type": "employee" },
      "applicability": { "start": "2022-06-01", "end": null },
      "value": { "id": "5", "type": "department" }
    },
    {
      "id": "8266",
      "type": "employee-attribute",
      "definition": { "id": "jobPosition.manager", "type": "employee-attribute-definition" },
      "employee": { "id": "416", "type": "employee" },
      "applicability": { "start": "2022-06-01", "end": null },
      "value": { "id": "417", "type": "employee" }
    }
  ],
  "links": { "prev": null, "next": null }
}

Employee Attributes

Learn more about the employee-attributes endpoint, the recommended way to query employee data in bulk.
When using employee-attributes, applicability.asOf={TODAY} limits results to currently valid attributes but does not exclude employees whose contract has ended — to filter to active employees only, first page through GET /lucca-api/employees?status=active to collect the IDs, then pass batches of up to 1000 at a time as employee.id={ID1},{ID2},... (the employee.id filter accepts a maximum of 1000 values per request).

3. Retrieve Personal Data

Personal data that was previously embedded in the flat v3 user object (birth date, bank details, personal email, etc.) is now housed in the employee-personal-record resource. Accessing it requires the employee-personal-records.readonly OAuth scope and the appropriate directory section permissions. Choose the approach that fits your use case:
  • Use GET /lucca-api/employee-personal-records/{employeeId} when you need the complete personal record for a known employee — it returns all personal fields in one response.
  • Use employee-attributes when you only need specific personal fields, are reading data for many employees in bulk, or want to mix personal data with other attributes (employment, job position, etc.) in a single call.
GET /lucca-api/employee-personal-records/{employeeId} HTTP/1.1
Host: example.ilucca.net
Authorization: Bearer {ACCESS_TOKEN}
Api-Version: 2024-11-01
Accept: application/json

Employee Personal Record

Full reference for the employee-personal-record resource, including all available fields and their types.
Or via employee-attributes:
GET /lucca-api/employee-attributes?employee.id={EMPLOYEE_ID}&applicability.asOf={TODAY}&definition.id=personal.birthDate,personal.email,personal.phoneNumber HTTP/1.1
Host: example.ilucca.net
Authorization: Bearer {ACCESS_TOKEN}
Api-Version: 2024-11-01
Accept: application/json

Notable Breaking Changes

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

legalEntity is ambiguous

The v3 field name legalEntity maps to two different v5 concepts depending on context:
v3 fieldv5 definition IDv5 concept
legalEntity / legalEntityIdjobPosition.businessEstablishmentThe business establishment where the employee physically works
legalUnit / legalUnitIdemployment.legalEntityThe legal entity on the employment contract (called “legal-unit” in the UI)

birthDate moved

Previously a top-level user field, birthDate is now personal.birthDate. A derived employee.birthDay (month and day only, no year) is also exposed as a separate property.

Banking fields consolidated

rib, iban, bic, and bankName are merged into a single bankAccount object with accountIdentifier, bankIdentifier, bankName, and format sub-fields. The bank account is available both on the employee-personal-record resource and as an employee-attribute-definition with ID personal.bankAccount.
v5 BankAccount
{
  "format": "iban",
  "accountIdentifier": "FR1612739000503533694532L71",
  "bankIdentifier": "AGRIFRPP",
  "bankName": "Crédit Agricole"
}
v3 fieldv5 bankAccount.
(no v3 equivalent)format
ribaccountIdentifier
ibanaccountIdentifier
bicbankIdentifier
bankNamebankName

Contract dates are objects

dtContractStart and dtContractEnd are now employment.start and employment.end, each an object with a nested date sub-field rather than a plain date string:
// v3: plain string
"dtContractStart": "2020-01-15"

// v5: nested object
"start": { "date": "2020-01-15" }
This structural change will break any code that reads contract dates directly as strings. Update your parsing logic to extract the date sub-field.

Custom fields (e_*)

V3 extendedData fields (custom extension fields prefixed with e_) have their own v5 employee-attribute-definition and appear in employee-attributes alongside built-in fields. Query GET /lucca-api/employee-attribute-definitions to discover them.
The new employee-attribute-definition created from legacy extended-data kept its ID unchanged (e.g. e_tShirtSize remains e_tShirtSize) to preserve continuity.

Phone numbers: personalMobile vs professionalMobile is ambiguous

The v3 personalMobile and professionalMobile fields both map onto a phoneNumber named property, but which are on two different resources (employee and employee-personal-record):
v3 fieldv5 definition IDv5 resource
personalMobilepersonal.phoneNumberemployee-personal-record — the employee’s private phone number
professionalMobileemployee.phoneNumberemployee — the employee’s work phone number
If your v3 integration used a generic “phone” or “mobile” field, make sure you identify which one you need and map to the correct v5 definition.

Field Mapping Reference

Employee (employee.*)

Legacy field (v3)New definition ID (v5)Notes
mailemployee.email
lastNameemployee.familyName
firstNameemployee.givenName
professionalMobileemployee.phoneNumber
employeeNumberemployee.employeeNumberAlso known as matricule in the legacy API
loginemployee.remoteId
picture, pictureIdemployee.portrait
idemployee.idIs a string in v5.
(no v3 equivalent)employee.statusNew property only
(no v3 equivalent)employee.birthDayDerived from birthDate; exposes month and day sub-fields only (no year)

Employee

Full reference for the employee resource, including all available fields and their types.

Personal Record (personal.*)

Legacy field (v3)New definition ID (v5)Notes
birthDatepersonal.birthDatePreviously a top-level user field
rib, iban, bic, bankNamepersonal.bankAccountConsolidated into one object with accountIdentifier, bankIdentifier, bankName, format sub-fields
personalEmailpersonal.email
insuranceNumberpersonal.insuranceNumberSub-fields: value, format
genderpersonal.legalGender
nationality, nationalityIdpersonal.nationalitiesCountryCodesNow a list of three-letter country codes (ISO 3166-1 alpha-3)
personalMobilepersonal.phoneNumber
civilTitlepersonal.title

Employee Personal Record

Full reference for the employee-personal-record resource, including all available fields and their types.

Employment (employment.*)

Legacy field (v3)New definition ID (v5)Notes
dtContractStartemployment.startNow an object with a date sub-field
dtContractEndemployment.endNow an object with a date sub-field
(no v3 equivalent)employment.legalEntityNew property only
(no v3 equivalent)employment.templateNew property only
(no v3 equivalent)employment.documentNew property only
(no v3 equivalent)employment.remoteIdNew property only
Two probationary period properties are also available on employments, with no v3 equivalent: probationaryPeriod.initialEndsOn and probationaryPeriod.extendedEndsOn.

Employment

Full reference for the employment resource, including all available fields and their types.

Job Position (jobPosition.*)

Legacy field (v3)New definition ID (v5)Notes
department, departmentIdjobPosition.department
manager, managerIdjobPosition.manager
legalEntity, legalEntityIdjobPosition.businessEstablishmentIn the v5 Lucca API, legalEntity at the job level maps to the job-position business establishment, not the employment legal-entity.
jobQualification, jobQualificationIdjobPosition.jobQualification
csp, cspIdjobPosition.occupationCategory
jobTitlejobPosition.jobTitle
(no v3 equivalent)jobPosition.documentNew property only
(no v3 equivalent)jobPosition.endsOnNew property only
(no v3 equivalent)jobPosition.startsOnNew property only
(no v3 equivalent)jobPosition.remoteIdNew property only

Job-Position

Full reference for the job-position resource, including all available fields and their types.

Application & Complementary User Data (user.*)

These fields were root-level or applicationData properties of the legacy user. They retain the user.* namespace in the Lucca API because they don’t map cleanly to the new employee, employment, or job-position model — most are application-specific settings, approval chains, or computed values. Rather than being reassigned to a new resource, they are preserved under this namespace for compatibility.
Legacy field (v3)New definition ID (v5)Notes
seniorityDateuser.seniorityDate
frenchCarTaxHorsePoweruser.frenchCarTaxHorsePower
frenchMotorcyclesTaxHorsePoweruser.frenchMotorcyclesTaxHorsePower
corporateCarduser.corporateCard
personalCarduser.personalCard
personalAccountuser.personalAccount
unitSellPriceuser.unitSellPriceDeprecated even in v3; consider removing from your integration
allowsElectronicPayslipuser.allowsElectronicPayslip
site, siteIduser.siteId
directLineuser.directLine
quoteuser.quote
addressuser.address
cleemyApproverIduser.cleemyApproverId
culture, cultureIduser.cultureId
calendar, calendarIduser.calendarId
manager2, manager2Iduser.manager2Id
profile_cleemy_{{appInstanceId}}user.cleemyProfileSub-fields: appInstanceId, profileId
profile_figgouser.figgoProfileSub-fields: appInstanceId, profileId
{{organizationId}}-cost (timmi-project)user.costSub-fields: organizationId, value
{{organizationId}}-price (timmi-project)user.priceSub-fields: organizationId, value
navisionIduser.navisionId
cegidGescomIduser.cegidGescomId
bergerLevraultCareerNumberuser.bergerLevraultCareerNumber
timesheetApproverId, timesheetApproveruser.timesheetApproverId
remoteWorkProfileId, remoteWorkProfileuser.remoteWorkProfileId
employeeAccountingCodeuser.employeeAccountingCode
userAxisValues_{{axisId}}user.axisValuesSub-fields: axisId, axisSectionId

Further Reading

Work-Contracts Migration

Migrating from the v4 /directory/api/4.0/work-contracts API to v5 employment and job-position resources.

Lucca API Introduction

Overview of the Lucca API, versioning, and pagination.

Get Started With Employees

Deep dive into the employee data model and how the resources relate to each other.

Get Started With Employee Attributes

How to use the unified employee-attributes endpoint to read any employee property.

Rate Limits

Rate and size limits applied to the Lucca API, with best practices for designing bulk sync integrations.