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 Reference

Get access

Contact your Fourth Implementation Consultant. They will provide:

  • 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

CONTACT US 

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 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 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 may have multiple assignments for the same period of time, but only one main assignment at any point in time.

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.

Resources

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

POST <ROOT>/import/{organizationId}/

There are no query parameters. The resources accept POST requests to create and update entries.  

Resource Description
Assignments
Assignments:batchImport
Adds or updates assignments for one or more employees.
Employees
Employees:batchImport
Adds or updates employee details for one or more employees.
Employments
Employments:batchImport
Adds or updates the employment history for one or more employees.
JobTitles
JobTitles:batchImport
Adds or updates one or more job titles across your business. 
Locations
Locations:batchImport
Adds or updates one or more locations across your business. 
PaidAbsences
PaidAbsences:batchImport
Adds or updates the paid absences for one or more employees.
PlannedAbsences
PlannedAbsences:batchImport
Adds or updates the planned absences for one or more employees.

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 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}/employees: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
      }
   ]
}
]