Labor Productivity API Guide

Introduction

With the Labor Productivity API you can update the employee and organization data stored in Fourth. This includes both static data and temporary or transactional data such as employee absences (planned and unplanned). 

Data received via this API is processed asynchronously. This means that it may take a moment before the same data is shown in Fourth modules. 

Quick Facts

API type HTTP REST with JSON and XML
Authentication Basic authentication
Availability All customers using Workforce Management solutions
Testing A test environment is available
More information See the API Reference

Get access

To get started with this API, you will need:

  • A Labor Productivity API account to access this API
  • An Organization ID used as a URL path parameter for identifying your requests
  • The root URL for requests to both test and live environments

Your mutual Fourth customer must request credentials on your behalf. Please ensure they do this as soon as possible. The Fourth Professional Services team member managing the integration can provide the above information and help you with any integration questions you may have.

Updates

You can find any updates on the Release Notes page for the Labor Productivity API.

Unique identifiers 

When you send requests to this API, you need to include your own unique identifier for the person, job or location that you are adding or updating in Fourth. We use this to identify whether it is a new or existing entity. Provide them in the request using:

  • employee_ID — for all employee-related requests
  • job_Code — for requests to change the job titles across your business
  • location_Code — for requests to change the names of locations across your business
  • assignment_Reference — for requests to update an existing assignment for an employee
  • employment_Reference — for requests to update an existing employment for an employee 

Batch importing 

There are two endpoint options for each resources type: one that accepts a single item (like employee) and another batchImport version that accepts multiple entries for the same item. While each endpoint accepts the same object, you must use the batchImport version if you wish to include more than one item in the request. We recommend integrating with the batchImport version wherever possible.

Employees

You should send in the details of your employee (using an employees request) before adding an employment or assignment. This ensures, amongst other things, that the employee has a Fourth Account

If you send in an assignment (or employment) request with an employee_ID that doesn’t exist, then Fourth creates a dummy employee account, with the expectation that additional data for the employee will arrive shortly. Once we have received a matching employee request, we send out the “Welcome” email for Fourth Engage to the employee. 

Assignments and employment

Because Fourth’s Workforce Management solution is built with the hospitality industry in mind, the employee record for an individual allows them to have multiple jobs across multiple locations. To differentiate between an employee’s jobs and their overall employment, we use the concepts of employment and assignments.

Employment

Employment represents the contract between an employee and employer. As employees have one contract with an employer, an employee can only have one employment for the same period with the same employer. However, for different periods they can have multiple employments. This ensures that rehired employees have just the one record about their overall employment at the business. 

Assignments

Assignments represents what an employee is doing for an employer. The minimal properties that define this is location, job, rate type, contracted hours, rates, and whether it is the primary job (“main” assignment) of the employee.

An employee must always have a main assignment. They can only have one at any point in time; however, during their employment, they may have multiple main assignments that occur one after the other.

An employee may also have multiple secondary assignments for the same period of time. However, their must be an existing main assignment before you can add secondary assignments.

New assignments are expected to have unique IDs. If we receive an assignment with an ID that already exists, we will update the one we find instead of create a new one.

Best practices for employment and assignments requests

This API is designed to intelligently update existing employment and assignment information based on known data. For example, if a request adds a new main assignment for an employee, then Fourth ends the existing one on the same day that the new one starts; or, if a request sends a series of future assignments based on start date (with no end dates specified), Fourth will order the assignments appropriately. 

However, we recommend all start and end dates for assignments and employment are sent to Fourth, when they’re known. This reduces the likelihood of issues such as employees remaining assigned to secondary roles that they no longer work on. 

For example, imagine Barbara is employed on the 12th of March as a duty manager at a downtown restaurant, then provides emergency cover for several shifts between the 10th-24th of May at another restaurant, before eventually leaving employment on the 21st of July. The requests for Barbara employment would be:

  1. Create employee request sent.
  2. Create employment request sent, with the start date set to the 12th of March. There is no end date required. 
  3. Create main assignment request sent, with the start date set to the 12th of March. This sets her job, location, and pay rate for the assignment. You don’t need to specify an end date.
  4. Create secondary assignment request sent in early May, with a start date of the 10th of May. 
  5. Update secondary assignment request sent in late May, with an end date specified. This finishes the secondary assignment.
  6. Update employment request sent, with an end date of the 21st of July. This also ends any assignments and removes Barbara from shift schedules. Her access to specific Fourth applications may be disabled automatically (based on your agreement with Fourth).

Note that any change to the core properties of an assignment — location, job, rate type, contracted hours, rates, and whether it’s the main assignment — constitutes a new assignment in Fourth. Ideally this means that, if an employee’s hours changed, you would send both an update assignment request (to end the current assignment) and a create assignment request (to create a new assignment with the revised hours). 

Rehires

When you rehire an employee, you need to create a new employment, rather than update the previous one. Updating the previous employment will make your records seem like the employee had never left the business between the two employment periods (or make the record seem like they were never previously employed).

Rehired employee can have the same employee record, as long as your HR system sends through the new employment using the original employeeNumber for the employee.

You can continue an employment even if there are no current assignments for that person. For example, if your employee is on a break from assignments — for example, a student who goes home during the Summer break — you can end their current assignment and restart a new one when they return. 

Other behavior notes

  • If we receive an assignment request where there is no related employment, then the request creates the employment. The employment start date will be the same as the assignment start date. 
  • Assignments and employments can have start and end dates in the future or in the past. This is useful for sending planned changes in assignments; for example, a planned pay rise or change in location.
  • The employment end date automatically becomes the end date of any active assignments. Any shifts past the end date are removed in Labor Productivity.

Deleting unused assignments and employments

The following endpoints allow you to delete assignments and employments. Please note that these are POST request, rather than DELETE:

These endpoints support Fourth partners who create employments and assignments in advance. It's intended to allow partners to remove employments or assignments that an employee will not begin. However, we accept requests to delete employments or assignments regardless of whether they are in use or not; that is, you can potentially delete an employment or assignment for a current employee. Deleting an employment will delete any assignments that are part of that employment, as well as any associated data such as tips and shifts.

Behavior when using batch deletes: We delete all valid assignments and employments in the request, and ignore any that we do not find.

Holidays and absences

There are a number of endpoints that let you manage employee holidays and absences.

To get employee absences, use:

To add or update paid absences for employees, use either:

To add or update planned absences employees, use either:

To delete planned absences, use either:

Adding half days to planned absences

For planned absences you can submit both full and half day absences. However, you must submit a half day absence as a separate request (or array member) from any full day absence.

To create a half day absence, in a request, set:

  • half_Day to true
  • absence_Start_Date and absence_End_Date (if included) to the same date.
  • absence_Days (if included) to 1.

For example, if you need to create a planned absence for 5.5 days, your request would look similar to this:

POST /import/examplecustomer/PlannedAbsences:batchImport HTTP/1.1 
Host: instance.example.com 
Accept: text/json 
Authorization: Basic VXNlcm5hbWU6cGFzc3dvcmQ=

[
   {
       "employee_ID": "M02653",
       "job_Code": "BRST",
       "absence_Reference": "ref73737",
       "absence_Type": "-2",
       "absence_Days": 1,
       "absence_Start_Date": "2021-04-23T00:00:00",
       "absence_Status": "active",
       "absence_Paid": 100,
       "half_Day": true
   },
   {  
       "employee_ID": "M02653", 
       "job_Code": "BRST", 
       "absence_Reference": "ref73738", 
       "absence_Type": "-2",
       "absence_Days": 5,
       "absence_Start_Date": "2021-04-24T00:00:00",
       "absence_Status": "active",
       "absence_Paid": 100,
       "half_Day": false
   }
]

The API will respond with an error message if you send through a request where half_Day is set to true, but the absence_Days is 2 or more (or the start and end dates are not the same).

Resources

You need to put your organization ID in the URL path. The base path is:

POST <ROOT>/import/{organizationId}/

For the list of endpoints and methods this API supports, see the API Reference.

Request header

For all requests, you must provide your authentication details using Basic authentication in the header.

Example header:

POST /import/{organizationId}/Employments HTTP/1.1
Host: instance.example.com
Accept: text/json
Authorization: Basic VXNlcm5hbWU6cGFzc3dvcmQ=
Field Description
Authorization Your Labor Productivity API ID and password, separated by a colon, and then base64 encoded. Your ID and password are case-sensitive. 
Accept The data format you are using for the request. Options are: application/json, text/json, application/xml, text/xml.

Request body

For full details of request bodies, see the API reference. The hierarchy of employee-related resource is:

Payroll
   Employee
      Personal Details
         Passport
      Contact Details
         Address
         Email
         Telephone
      Dependents
      Next of Kin
      Payment Details
         Account Details
             Split
      Employment Details
         Assignment Details
      Documentation
      Country Specific
         Country
      Absence
      Pay Parts    
         Pay Part Values
      Payslip

Response 

Successful requests

Successful requests receive an HTTP 202 Accepted response. This includes a location header, which contains a resource location (also referred to as the request ID.) The response body is empty. 

HTTP/1.1 202 Accepted
Location: 015-3DD6C366-D68A-4A02-9777
Content-Type: text/json

Unsuccessful requests

Unsuccessful requests receive an HTTP 400-599 response, with an empty response body. 

Example use case 

This API is often used during the setup and maintenance of employee schedules in Fourth Labor Productivity. To create schedules, Fourth needs the following information: 

  • Locations
  • Job titles
  • Employees 
  • Assignments 

You must provide your location and job title information before employees or assignments. 

Step 1: Send your locations 

Use the resource: 

POST <ROOT>/import/{organizationId}/locations:batchImport

Your request body should look similar to the example below. Although not required, we recommend you to provide location_Latitude and location_Longitude for more precise weather forecasting. If these are not available, please set them to 0.

Once Fourth receives the request, you will see your locations appear in Labor Productivity.

POST /import/{organizationId}/locations:batchImport HTTP/1.1
Host: instance.example.com
Accept: text/json
Authorization: Basic VXNlcm5hbWU6cGFzc3dvcmQ=

[
{
   "location_Code": "0001",
   "location_Name": "Designer Burgers",
   "location_Address": {
      "address_1": "134 N 4th St",
      "address_Town": "New York",
      "address_Zip": "11249",
      "address_Province": "NY",
      "address_Country": "USA"
   },
   "location_Start_Of_Schedule_Week_Day": "MON"
}
]

Step 2: Send your job titles 

Use the resource: 

POST <ROOT>/import/{organizationId}/jobtitles:batchImport

Your request body should look similar to the example.

POST /import/{organizationId}/jobtitles:batchImport HTTP/1.1
Host: instance.example.com
Accept: text/json
Authorization: Basic VXNlcm5hbWU6cGFzc3dvcmQ=

[
{
   "job_Code": "0001",
   "job_Name": "Chef",
   "is_Tippable": "true"
}
]

Step 3: Link the job titles to roles

Only a Fourth user with the management privileges can link job titles to roles, so this step must occur within the Fourth Labour Productivity module.  

The job titles will rapidly appear in the Job Titles settings. From here, link any new job titles to the relevant RoleName. You must do this step before sending any employee data.

Edit Job Title screenshot showing the "RoleName" dropdown

Step 4: Send employees 

Use the resource:

POST <ROOT>/import/{organizationId}/employees:batchImport

If everything is successful, the employee receives a “Welcome!” email from Fourth with a link to activate a Fourth Engage account.

All data is processed asynchronously, so it may take a moment before you can see all the employees in Labor Productivity. 

POST /import/{organizationId}/employees:batchImport HTTP/1.1
Host: instance.example.com
Accept: text/json
Authorization: Basic VXNlcm5hbWU6cGFzc3dvcmQ=

[
{
   "employee_id": "000001",
   "personal_details": {
      "payroll_no": "000001",
      "first_name": "John",
      "last_name": "Doe",
      "date_of_birth": "1980-01-01T00:00:00",
      },
   "contact_details": {
      "address": {
         "address_1": "40 Richards Avenue",
         "address_town": "Norwalk",
         "address_code": "06854",
         "address_province": "CT",
         "address_country": "USA"
      },
      "email": {
         "email_home": "john.doe@example.com"
      },
      "telephone": {
         "tel_mobile": "0012038383700"
      }
   }
}
]

Step 5: Send employment

Use the resource:

POST <ROOT>/import/{organizationId}/employments:batchImport

Note that it is possible — but not ideal — to miss this step. Fourth creates an employment with the same start date as the assignment. 

POST /import/{organizationId}/employments:batchImport HTTP/1.1
Host: instance.example.com
Accept: text/json
Authorization: Basic VXNlcm5hbWU6cGFzc3dvcmQ=

[
{
   "Employee_ID": "000001",
   "Employment_Reference": "1000001",
   "Employment_Join_Date": "2018-03-28T00:00:00",
   "First_Working_Day": "2018-03-28T00:00:00",
   "Orignal_Hire_Date": "2018-03-28T00:00:00",
   "Employment_Type": "employee",
   "Employment_Status": "active",
   "Contract_Perm": "true",
   "Contract_FullTime": "true",
   "Contracted_Hours": 35,
   "Pay_Group": "PG1"
}
]

Step 6: Send assignments 

Use the resource: 

POST <ROOT>/import/{organizationId}/assignments:batchImport

Once the assignments are in, the employees are available to schedule in Fourth. All data is processed asynchronously, so it may take a moment before you can see all the assignments in Labor Productivity. 

POST /import/{customerlId}/assignments:batchImport HTTP/1.1
Host: instance.example.com
Accept: text/json
Authorization: Basic VXNlcm5hbWU6cGFzc3dvcmQ=

[
{
   "assigment_reference": 0000100,
   "employee_id": "000001",
   "assignment_start_date": "2018-01-01T00:00:00",
   "main_assignment": "true",
   "location_code": "0001",
   "job_code": "0001",
   "rate_type": "hourly",
   "contracted_hours": 40,
   "rates": [
      {
         "rate_unit": "HOUR",
         "rate_amount": 13
      },
      {
         "rate_unit": "WEEK",
         "rate_amount": 520
      },
      {
         "rate_unit": "MONTH",
         "rate_amount": 2080
      },
      {
         "rate_unit": "YEAR",
         "rate_amount": 27040
      }
   ]
}
]

Troubleshooting & FAQs

Questions

What rules are enforced on the employment data that will override external HR system logic?

There is a hierarchy which decides if an assignment is valid. The period of a main assignment must be covered by an employment record, and the period of a non-main assignment must be covered by one or more main assignments. This logic controls what employees are available for scheduling, but the system still receives and stores the data. This means that if the main assignment is submitted to the API before the employment, no data is lost and the employee is available to schedule once both are received.

Should I provide incremental employment history and only notify Fourth of the changes made, or should I send an employee's complete history?

There are options in the API to support both methods. If you intend to always send an employee’s complete employment history with each update please send it to the Full History endpoint. This will overwrite our existing data for the employee and replace with the history provided. If you can only send us the changes, please use the employment and assignment endpoints respectively to send over the new data. 

Does Fourth have user groups in People Systems or Labor Productivity? If so, how are they exposed?

Not explicitly for users, no. User can be grouped by location or job title though.