Introduction

This is a guide aimed at helping you achieving the synchronization of all leaves edited in Timmi Absences with a third-party app.

The implementation is a regular synchronization of all leaves that have been created, deleted or modified by the users since the last synchronization date {lastSyncDateTime}.

This synchronization can be done on an users establishment basis leavePeriod.owner.legalEntityId in order to be executed at hours, thus taking into account the different time zones.

About legal establishments filtering: Be careful, this filter on the establishments is applied on the current establishment of the user (at the time of the request), and not his establishment at the time of the leave creation / confirmation / deletion. This should not be a problem as long as all legal entities are synchronized.

Contrary to the export feature in Timmi Absences, the durations returned by the leave API will not correspond to the difference between what was previously synchronized and the new value. The current values will always be returned. The treatment on the client side should thus follow a “delete and replace” (delete / neutralize only in case of a deletion) logic.

Prerequisites

You need:

  • (required) Your domain name {yourDomain}, eg: “https://myawesomecompany.ilucca.net”.
  • (required) An API key {apiKey} that has access to the leaves of the users concerned by your integration project. This key should be created with the help of a Lucca Customer Success Manager.
  • (optional) When filtering on legal establishments, the unique identifiers of said establishments.

Fields

Leaves have a large number of fields. A complete list of all fields can be found in the API reference.

Here are the most commonly relevant ones:

  • (integer) id: unique identifier of the leave.
  • (date) date: date of the leave.
  • (boolean) isAm: half day: true for the morning or false for the afternoon.
  • (integer) ownerId: identifier of the user.
  • (date-time) creationDate: time-stamp of the creation of the leave.
  • (string) comment: comment.
  • (date-time) leavePeriod.confirmationDate: time-stamp of the confirmation of the leave.

The fields you want to retrieve must be listed in the ?fields=a,b,c query parameter (separated by commas). For example to retrieve all the fields listed above:

GET /api/v3/leaves?fields=id,date,isAm,ownerId,creationDate,leavePeriod[confirmationDate],collection.count&paging=0,1 HTTP/1.1
Host: {yourDomain}
Authorization: application={apiKey}
Accept: application/json

Response should look like this:

{
  "data": {
    "count": 1,
    "items": [
      {
        "id": 176,
        "date": "2021-01-01",
        "isAm": true,
        "ownerId": 416,
        "leavePeriod": {
          "confirmationDate": "2020-12-27 13:42:12"
        }
      }
    ]
  }
}

Paging

The leaves endpoint is paginated. It is therefore impossible to retrieve more than 10,000 items in a single GET request.

Paging is done through the paging request parameter which takes two arguments: the index in the collection of the first element to return start (starts at zero) and the number of elements to return limit (maximum 10,000 on the leaves API). For example, to return 100 elements from the 15th: ?paging=14,100.

We recommend not to exceed 1,000 results per page in order to guarantee satisfactory response times.

The total number of elements that meet the criteria of the query can be retrieved through the collection.count field:

GET /api/v3/leaves?paging=0,1&fields=id,collection.count HTTP/1.1
Host: {yourDomain}
Authorization: lucca application={apiKey}
Accept: application/json

Response:
{
  "data": {
    "count": 2874,
    "items": [
      {
        "id": 1
      }
    ]
  }
}

From then on, it is possible to know the total number of pages that it will be necessary to request:

// Javascript:
var itemsPerPage = 100;
var responseBodyJSON = JSON.parse(response.data);
var pageCount = Math.ceil(responseBodyJSON.data.count / itemsPerPage);

A first request asking only for the collection.count field can therefore be sent to retrieve this value, and the sequence of paginated calls shall follow.

Retrieve created & confirmed leaves

The parameters of the request are the following:

  • (date-time) {lastSyncDateTime}: UTC date and time of the last synchronization in ISO-8601 format, eg: 2021-01-01T08:25:45Z.
  • (integer) {offset}: index of the first element to be returned (paging). Starts at zero.
  • (integer) {limit}: number of elements to return (pagination). Maximum value: 10,000.
  • (optional) (array<integer>) {legalEntityIds}: filter on the establishment(s) of the declarants (separated by commas). Allows to return only the time-entries of employees of one or several establishments targeted by their identifier.
  • (array<string>) {fields}: the list of fields (see section above) separated by a comma that you want to retrieve.

Since the maximum precision is the minute, and to avoid forgetting any leaves modified at the same time as the synchronization procedure (it is paged), it is recommended to round down at least to the nearest minute, if not more.

GET /api/v3/leaves?leavePeriod.confirmationDate=since,{lastSyncDateTime}&paging={offset},{limit}&owner.legalEntityId={legalEntityIds}&fields={fields} HTTP/1.1
Domain: {yourDomain}
Authorization: lucca application={apiKey}
Accept: application/json

Response:
{
  "data": {
    "count": 1298,
    "items": [...]
  }
}

Retrieve unconfirmed leaves

The parameters of the request are the following:

  • (date-time) {lastSyncDateTime}: UTC date and time of the last synchronization in ISO-8601 format, eg: 2021-01-01T08:25:45Z.
  • (integer) {offset}: index of the first element to be returned (paging). Starts at zero.
  • (integer) {limit}: number of elements to return (pagination). Maximum value: 10,000.
  • (optional) (array<integer>) {legalEntityIds}: filter on the establishment(s) of the declarants (separated by commas). Allows to return only the leaves of employees of one or several establishments targeted by their identifier.
  • (array<string>) {fields}: the list of fields (see section above) separated by a comma that you want to retrieve.

Since the maximum precision is the minute, and to avoid forgetting any leaves modified at the same time as the synchronization procedure (it is paged), it is recommended to round down at least to the nearest minute, if not more.

GET /api/v3/leaves?creationDate=since,{lastSyncDateTime}isconfirmed=false&paging={offset},{limit}&owner.legalEntityId={legalEntityIds}&fields={fields} HTTP/1.1
Domain: {yourDomain}
Authorization: lucca application={apiKey}
Accept: application/json

Response:
{
  "data": {
    "count": 1298,
    "items": [...]
  }
}

Retrieve deleted leaves

  • (date-time) {lastSyncDateTime}: UTC date and time of the last synchronization in ISO-8601 format, eg: 2021-01-01T08:25:45Z.
  • (integer) {offset}: index of the first element to be returned (paging). Starts at zero.
  • (integer) {limit}: number of elements to return (pagination). Maximum value: 10,000.
  • (optional) (array<integer>) {legalEntityIds}: filter on the establishment(s) of the declarants (separated by commas). Allows to return only the leaves of users of one or several establishments targeted by their identifier.
  • (array<string>) {fields}: the list of fields (see section above) separated by a comma that you want to retrieve.

Since the maximum precision is the minute, and to avoid forgetting any leaves modified at the same time as the synchronization procedure (it is paged), it is recommended to round down at least to the nearest minute, if not more.

GET /api/v3/leaves?cancellationDate=since,{lastSyncDateTime}&creationDate=until,{lastSyncDateTime}&isActive=false&paging={offset},{limit}&owner.legalEntityId={legalEntityIds}&fields={fields} HTTP/1.1
Domain: {yourDomain}
Authorization: lucca application={apiKey}
Accept: application/json

Response:
{
  "data": {
    "count": 1298,
    "items": [...]
  }
}