Skip to main content
If you update employee data through a user import file, whether you upload a CSV or Excel file manually or drop it on an SFTP server for automatic import, each line of that file describes an employee as they are today. The file import only updates an employee’s current employment and position. A new manager or department overwrites the previous one without recording when the change happened, and when a former employee returns, their past employment is overwritten. The Lucca API preserves this history. An employee can have several successive employments, and each employment can have several successive job positions, each with its own start date. Instead of overwriting a column, the integration you build on the Lucca API creates a dated record for each change.
The write endpoints described in this guide are in beta. Their contract may change before general availability.

Quick Start (TL;DR)

1

Set up API access

Create an OAuth 2.0 client with the readwrite scopes listed under Required Scopes, and send Api-Version: 2024-11-01 with every request.
2

Look up each employee by login

GET /lucca-api/employees?remoteId={login} tells you whether a line refers to a new or an existing employee.
3

Create new employees in a single call

POST /lucca-api/employees creates the employee along with their first employment and first job position, in a single transaction.
4

Date every position change

A change of manager, department, occupation category or business establishment means a new job position: call POST /lucca-api/job-positions with the date the change takes effect.
5

Create a new employment for each new contract

When a former employee returns, add a new employment to their existing record with POST /lucca-api/employments.
6

Write the remaining columns as employee attributes

The second manager, seniority date, public holidays calendar, work cycles, leave profile and your organization’s extensions are all written through /lucca-api/employee-attributes.

What Changes Between a File Import and the API

The API behaves differently from the file import in four ways:
  • One line, several calls. A line in your file used to trigger a single update. With the API, it takes one call per record that changes: the employee, an employment, a job position or an attribute.
  • No upsert. Your integration reads the current data in Lucca, compares it with the line, and only sends the calls it needs.
  • IDs instead of names and codes. Your file refers to departments, establishments and managers by name, code or login. The API expects their id: see Translate Names and Codes Into IDs.
  • Explicit dates. Your file reflects the situation on the day it was generated. The API needs the date each change takes effect. If your source system only exports current data, use the export date.
Migrate progressively. You can keep the file import running while you move columns to the API one at a time. Remove each column from your file as soon as your integration writes it: once a value has been written outside the import, the import no longer overwrites it for that employee, so a column sent through both channels would silently drift apart.

Required Scopes

A single OAuth 2.0 token can hold every scope your integration needs.
Scopes grant access to endpoints. Your integration also needs access to the HR file sections that contain the data it writes.

Authentication

How to obtain and use OAuth 2.0 bearer tokens.

Mapping Your Columns to the API

This table lists the column names recognized by the file import, in English and French. Your file may use any of them.
In the file import, the legalEntity column refers to what the Lucca API calls a business establishment. In the API, legalEntity is the legal entity of the employment, and it must be the legal entity that the first job position’s business establishment belongs to.
Every employment requires an employment template, which corresponds to the contract type in your file. If your file has no contract type column, define a rule before you build your integration, for example one template per legal entity or per occupation category.

Translate Names and Codes Into IDs

Build a lookup table once per synchronization run instead of making one call per line:
Identify managers by login rather than by name, since two employees can share the same name. If a manager joins in the same batch, create them before the employees who report to them.
Handle pagination on every collection. Pages hold up to 1,000 items.

Processing a Line From Your File

Each line is matched to an employee by login, then compared with that employee’s employments and job positions.

Use Cases

1. Create an Employee

POST /lucca-api/employees creates the employee along with their first employment and first job position, in a single transaction. The first job position is nested inside firstEmployment. If any part of the request is invalid, nothing is created.
The response contains the new employee and their id. Use this id to write the rest of the line: the birth date (see Update Identity and Personal Data) and the remaining columns (see Remaining Columns).
If you leave out the public holidays calendar, occupation category or role, the defaults configured for the business establishment apply.
Employees cannot be deleted through the API. If a call fails after POST /lucca-api/employees has succeeded, retry that call instead of creating the employee again: their login is already in use.

2. Create a New Employment

A new work contract means a new employment on the existing employee record, and the previous employment stays in their history. This applies in two situations:
  • A former employee returns after their previous contract has ended.
  • An employee moves to another legal entity: end the current employment, then create the new one.
1

Look up the employee by login

Do not create the employee again: their login is already in use.
2

Check the dates

List their employments with GET /lucca-api/employments?employee.id={employeeId}. The new employment must start after the previous one ends. Overlapping employments are rejected with urn:employees:error:employment-overlap.Creating an employment does not end the previous one. If the previous employment has no end date, set it first with PATCH /lucca-api/employments/{id} (see use case 4).
3

Create the employment

Nothing carries over from the previous employment, so send the full first job position.
4

Update the columns that changed between the two employments

For example, the seniority date, work cycles or leave profile.

3. Create a New Job Position

When an employee’s manager, department, occupation category or business establishment changes under the same contract, create a new job position. It starts on the date the change takes effect. Lucca ends the previous position the day before, and both appear in the employee’s career history.
1

List the job positions of the employment

Keep the position with the latest startsOn, which may be in the future.
2

Compare it with the line from your file

If nothing differs, there is nothing to send. Otherwise, copy every value from the latest position and replace the ones that your file changes.
3

Create the new job position

Send every field of the position, including those that your file does not contain, such as workingTimeArrangement or jobQualification. Any field you leave out will be empty on the new position.
The API rejects a new job position in the following cases:

4. Correct an Existing Employment or Job Position

Use PATCH to fix a record that was entered incorrectly, or to end a contract. A correction does not add an entry to the career history. PATCH only updates the fields you send, and any field sent as null is cleared.
The last job position ends on the same date. Sending "end": null removes the end date, which undoes a departure entered by mistake. You can correct the start date, template, reference (remoteId) and document the same way.The API rejects the update if a job position starts after the new end date, or if the probationary period ends after it. The legal entity of an existing employment cannot be changed: create a new employment instead.

5. Update Identity and Personal Data

Name, email address, login and employee number are fields of the employee.
Employee numbers must be unique within a business establishment. The birth date is stored on the personal record, which is created empty along with the employee. The personal record shares the employee’s id:

6. Remaining Columns

All other columns are written through /lucca-api/employee-attributes. Each value is an attribute with its own id.
1

Fetch the attribute

2

Update its value

The value must match the definition’s schema, which you can fetch with GET /lucca-api/employee-attribute-definitions/{id}. See Understanding the value Property. Where your file uses a name (calendar, work cycle, leave profile), the API expects the corresponding id.

Work Cycles

Work cycles are being progressively replaced by working time arrangements, which are set on the job position (workingTimeArrangement). If your account already uses working time arrangements, write them on the job position instead.
Your file can contain several workCycles periods, each with its own .start and .end columns. In the API, each period is a separate attribute. An end of null means the period is open-ended.
An employee’s periods cannot overlap (urn:employees:error:work-cycles-overlap). To switch to a different cycle, first set the end of the current period with PATCH, then create the next one.

Extensions

Extensions created by your organization keep the ID of their e_xxx column. Create the first value with POST:
If the employee already has a value, the API returns urn:employees:error:attribute-already-set-for-user. In that case, fetch its id and use PATCH instead. To list the extensions on your account, call GET /lucca-api/employee-attribute-definitions?category=extension.

Leave Profile

user.figgoProfile contains an appInstanceId and a profileId. It can only be updated for employees who already have a leave profile, and the new profile must be available for the employee’s business establishment.

Not Yet Available

Roles

Roles cannot be assigned through the Lucca API yet. When an employee is created, they receive the default role configured for their business establishment, and creation fails if no default role is configured. To assign a different role, use the Lucca interface.

Best Practices

  • Compare before you write. Read the employee, their employments and their latest job position, and only send the calls that change something. Your integration can then run as often as you need without adding duplicate positions to the history.
  • Follow the order of operations. Create managers before the employees who report to them, employments before their job positions, and employees before their attributes.
  • Process changes in chronological order. A job position cannot be inserted before an existing position in the same employment.
  • Handle errors by problem type. Every 4xx response is a Problem JSON object whose type, or the type of its field-level errors, identifies the cause. Flag rejected lines instead of retrying them unchanged.
  • Stay within the rate limits. See Limits to plan a full synchronization.

Further Reading

Migrating From V3 Users

The Lucca API data model, and how to read employee data.

Get Started With Employee Attributes

Definitions, value schemas and write operations on employee attributes.

Employment

Full reference for the employment resource.

Job-Position

Full reference for the job-position resource.