UK Employee API Guide

Introduction

With the UK Employee API, you can create, update and retrieve employee data in Fourth. 

It is intended for customers in the United Kingdom using Fourth as their employee master record and payroll system.

Quick Facts

Integration type HTTP REST with:
  • GET requests: JSON
  • POST requests: JSON / XML
Authentication Basic authentication
Availability United Kingdom only
Testing A test environment available
More information See the Reference

Get Access

Contact your Fourth Implementation Consultant. They will provide:

  • A UK Employee API account to access this API
  • An Organisation ID used as a URL path parameter for identifying your requests
  • The root URL for requests

CONTACT US

Unique identifiers

GET requests to this API will return the following identifiers: 

  • EmployeeID — the Fourth ID for the employee. This ID is globally unique in Fourth.
  • FAIDGET Employees requests additionally return this identifier. This is the Fourth Account ID for the user, and is commonly used as the identifier in SSO integrations.
  • Reference — the individual record in the data; e.g. each address, absence, employment, etc, has a record number. An employee may have multiple records for the same type of data returned in the same request.

Employments and assignments

Amongst other things, this API allows you to get employments data from Fourth. To differentiate between an employee’s jobs and their overall employment, we use the concepts of employment and assignments. You can make an Employees/Employments GET request to retrieve the details of employments from Fourth. 

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, they may have multiple employment records if they are hired multiple times; for example Oct-Dec 2017 and Jun-Aug 2018. 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; for example "sous-chef". 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.

In the following example, an employee (Geoff) has 2 employment records. The first one starts on the 20th of March 2018, and ends on the 3rd of May 2019. The second one starts on the 5th of June, and is ongoing. During his employments, Geoff has multiple assignments, some of which overlap, which represents changes to location and job title.

Date Activity Record changes
20 March 2018 Geoff joins the business. Employment starts.
Main assignment (1) starts: Sous chef at Alpha location.
21 April 2018 Geoff is given additional shifts at another location. Additional assignment (2) starts: Sous chef at Beta location. This assignment is concurrent with the main assignment.
04 July 2018 Geoff is promoted to head chef.

Previous main assignment (1) ends.
Additional assignment (2) ends.
New main assignment (3): Head chef at Alpha location.

03 May 2019 Geoff leaves the business.
 
Main assignment (3) ends.
Employment ends.
05 June 2019 Geoff rejoins the business.

New employment starts.
New main assignment (4) starts.

Resources

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

<ROOT>/organisations/{organisationId}/

The GET requests have query parameters for filtering results. You must include all query parameters with the request; however, you only need to specify a value for delta. For example: 

<ROOT>/organisation/{organizationId}/Employees?start=&duration=&dateFrom=&dateTo=&delta=false

Each resource exposes a single GET method; the Employees resource also accepts POST.

Resource Description
Employees

The POST request creates or updates a single employee. This request can include a wide variety of information such as name, contact details, visa status, national insurance number, next of kin, and pay details. 

The GET request returns a smaller set of core employee information, including name, DOB, nationality, marital status, education and disability.

Employees/Absences Returns the absence records of any employees who were absent during the specified time range. 
Employees/Addresses Returns employee addresses. If the employee has had multiple addresses during the time period, then all addresses are returned as separate records. The EffectiveDate identifies when the address change came into effect.
Employees/CountrySpecific Returns any country-specific fields that are not included in other requests. These fields are determined by Fourth (rather than being custom fields).
See the example below
Employees/Dependents Returns the dependents listed for each employee. 
Employees/Documents Returns the details of any documents (seen and recorded) for each employee during the time period. The documents you require from employees are defined within your business. 
Employees/Employments Returns the employment details for each employee during the specified time period. Employees may have multiple employments. 
Employees/NextOfKin Returns the next of kin for each employee. 
Employees/Passports Returns passports details associated with an employee.
Employees/PaymentDetails 

Returns the payment details of employees. If the employee updated these details during the specified time range, then all payment details are returned as separate records.

Employees/PayParts Returns information about the shifts that occurred during the pay period, such as start time and end, hours worked, job code and description.
There will be a record for each shift. 
Employees/Payslips Returns the details of any payslips issued during the time period. There will be one record returned for each transaction (or “element”) on the payslip.
ImportLogs Used to check whether POST Employee requests were successfully processed. It returns a status and any relevant error message. See the explanation and example below.
PayrollPeriod Returns the details of any payroll periods during the specified period. 

Time ranges and records

This API’s GET requests retrieve data for a specified time range — by default, this is the last calendar month. One of the effects of using a time range is that you may get multiple record entries for the same employee. For example, the GET Employees/Passports request returns the passport information recorded for employees. If this request is made with a time range of 12 months, then any employees who supplied new passport details during that time will have multiple records. In the following example, the same employee (EmployeeID 123) has both old and new passport records (PassportReference 70 and 71):

[ 
  {
   "EmployeeID" : "123",
   "PassportText" : "",
   "PassportReference" : "71",
   "PassportNumber" : "LK654321",
   "IssuingCountry" : "New Zealand",
   "IssueDate" : "2017-02-21",
   "ExpiryDate" : "2022-02-20"
   },
   {
   "EmployeeID" : "123",
   "PassportText" : "",
   "PassportReference" : "70",
   "PassportNumber" : "LK123456",
   "IssuingCountry" : "New Zealand",
   "IssueDate" : "2012-04-05",
   "ExpiryDate" : "2017-04-04"
   }
]

Any employee records that exist during the time range are included in the response, regardless of whether they are currently employed, or were employed through the entire time range.

Specifying the time range

By default, all GET requests will retrieve data for the last calendar month. You can specify an alternative time range using URL query parameters.

Query parameter Description
start and duration

Specifies a time range relative to the current day:

start — the number of days or months in the past to start the time range

duration — the number of days or months to include in the results

The days are inclusive. The format is (n)d for days, and (n)m for calendar months. For example: 

  • 7d — seven days 
  • 0d — today (for start) or zero days (for duration)
  • 2m — two full calendar months (e.g. if it is mid-April the export will start from the beginning of February).

To use these parameters, you must set a value for both. 

dateFrom and dateTo

The parameters dateFrom and dateTo let you get results by date, using the format YYYY-MM-DD. The dates are inclusive.

To use these parameters, you must set a value for both. 

If you use dateFrom and dateTo, then any values set for start and duration are ignored.

delta

The delta parameter allows you to get all records. You can set a boolean value:

true — Results are filtered by the specified time range.

false — All records are returned. The other time-related parameters are ignored.

You cannot use delta in GET requests to the Payroll, Employees/Payslip or ImportLogs resources. 

For example, to get employee absences for the last week, specify:

GET <ROOT>/organisation/{organizationId}/Employees/Absences?start=7d&duration=7d&dateFrom=&dateTo=&delta=true

To get the absences of all employees employed in 2017, specify:

GET <ROOT>/organisation/{organizationId}/Employees/Absences?start=&duration=&dateFrom=2017-01-01&dateTo=2017-12-31&delta=true

If you wish to include all records, set the delta query parameter to false in your request. For example, this request retrieves all employees ever employed:

GET <ROOT>/organisation/{organizationId}/Employees?start=&duration=&dateFrom=&dateTo=&delta=false

Request header

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

Example header:

GET /organisation/{organizationId}/Employees/Absences?
start=90d&amp;duration=90d&amp;datefrom=&amp;dateto=&delta=true  HTTP/1.1
Host: instance.example.com
Authorization: Basic VXNlcm5hbWU6cGFzc3dvcmQ=
Field Description
Authorization Your UK Employee API ID and password, separated by a colon, and then base64 encoded. Your ID and password are case-sensitive.
Content-Type The data format you are using for POST request. Options are: application/json, text/json, application/xml, text/xml.

Request body for POST employee

The POST Employees request allows you to add or update an employee (one per request). For full details of this request, see the reference and the example below.

To update an existing employee, use the same request. Fourth uses the EmployeeNumber to identify the record that needs updating. As it is a POST request, make sure you send the full record details rather than a subset of them. 

Requests are processed asynchronously, so you may want to use the ImportLogs request to confirm that the request was successfully processed.

POST /organisation/{organizationId}/Employees/
Host: instance.example.com
Content-Type: application/json
Authorization: Basic VXNlcm5hbWU6cGFzc3dvcmQ=

[ 
{
   "EmployeeNumber" : "9999",
   "Title" : "Mr",
   "FirstName" : "Chris",
   "MiddleName" : "Starr",
   "Surname" : "Jones",
   "PreferredName" : "Dr Jones",
   "DateOfBirth" : "1979-Jan-01",
   "Gender" : "Male",
   "MaritalStatus" : "Single",
   "Address1" : "17 Wayside Ave",
   "Address2" : "Burnside",
   "Address3" : "",
   "Town" : "Beckenham",
   "County" : “Kent",
   "Postcode" : "AB1 CD1",
   "HomeTel" : "02010000001",
   "MobileTel" : "00000000000",
   "Email" : "noemail@example.com",
   "HomeEmail" : "noemail@example.com",
   "NIN" : "",
   "Location" : "Fourth Restaurant 1",
   "Division" : "Bar",
   "JobTitle" : "Bar Staff",
   "StartDate" : "2018-Jan-01",
   "TerminationDate" : "",
   "PaidByRota" : "N",
   "IncludedInRota" : "Y",
   "PayType" : "",
   "RateOfPay" : "",
   "AnnualSalary" : "34000",
   "EmploymentType" : "Fulltime",
   "ContractHours" : "35",
   "PaymentMethod" : "BACS",
   "BankName" : "Bank Name",
   "BankAccountName" : "xyz abc",
   "BankSortCode" : "112233",
   "BankAccountNumber" : "12345678",
   "BuildingSocietyRollNumber" : "",
   "NOK1Title" : "Mr",
   "NOK1Firstname" : "Brother_Firstname",
   "NOK1Surname" : "Brother_Surname",
   "NOK1Relationship" : "brother",
   "NOK1Phone1" : "01031254522",
   "NOK1Phone2" : "02015847455",
   "NOK1Email" : "brother@example.com",
   "NOK2Title" : "Mrs",
   "NOK2Firstname" : "Mother_Firstname",
   "NOK2Surname" : "Mother_Surname",
   "NOK2Relationship" : "Mother",
   "NOK2Phone1" : "123456789",
   "NOK2Phone2" : "123456789",
   "NOK2Email" : "noemail@fourth.com",
   "OverrideFTE" : "",
   "FTEDays" : "",
   "FTEShifts" : "",
   "FTEHours" : "",
   "HolidayDaysTaken" : "",
   "HolidayAverageHoursPerWeek" : "",
   "HolidayAverageDaysPerWeek" : "",
   "HolidayEffectiveDate" : "",
   "EmployeeSourceDesc" : "ATS",
   "EffectiveDate" : ""
   }
]

Response 

Successful requests

Successful GET requests receive an HTTP 200 OK response with the data requested in the response body.

Unsuccessful requests

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

Response to country specific requests

The Employees/CountrySpecific resource returns country specific fields that are not included in other requests. These fields are determined by Fourth and include the following:

  • NationalInsuranceNumber
  • P45 Rec / P46 Completed?
  • WTD opt-out Date (working time directive)
  • US social security number

The response will have a record for each field relevant in the country, for that employee. For example, a UK employee may have three separate records returned to cover the NI number, working time directive, and P45/46 information.

GET /organisation/{organizationId}Employees/CountrySpecific?start=0d&duration=1d&dateFrom=&dateTo=&delta=true
Host: instance.example.com
Accept: application/json
Authorization: Basic VXNlcm5hbWU6cGFzc3dvcmQ=

[ 
   {
   "EmployeeID"="123",
   "Country"="GB",
   "Property"="NationalInsuranceNumber",
   "Value"="SK000000"
    },
   {
   "EmployeeID"="123",
   "Country"="GB",
   "Property"="P45 Rec / P46 Completed?",
   "Value"="Yes"
    },
   {
   "EmployeeID"="123",
   "Country”="GB",
   "Property”=”WTD opt-out Date",
   "Value"="2018-01-04"
    }
]  

Checking Employee imports

There are a lot of validation checks required when Fourth receives a POST Employees request, and so this data is processed asynchronously. You will receive a synchronous response to acknowledge that the data was successfully received; however, to confirm that it was successfully processed, you must use an ImportLogs request. 

The ImportLogs resource returns batched data for a set time range. We recommend using a request regularly (e.g. daily) to look at recent employee requests. You’ll need to specify importType=employee as a query parameter. For example:

GET <ROOT>/organisations/{organisationId}/ImportLogs?resourceId=&importType=employee&start=1d&duration=1d&dateFrom=&dateTo=

The response from Fourth will include the results of every POST employee request for the last day. Included in the response is:

  • Id — A unique number assigned by Fourth for the original employee request.
  • ReferenceNumber — The unique ID you sent as EmployeeNumber in the request. 
  • Xml — Your original request as XML-formatted data.
  • Status — one of:
    • Added — A new employee record was successfully added.
    • Updated — An existing employee record was successfully updated. 
    • ValidationError — Normally issues to do with the formatting of the original request, including whether values are too long or use invalid characters.
    • InternalError — Normally issues found after the initial validation check, such as missing properties/elements, values that are contradictory (such as around salaried vs waged data), or values that don’t exist yet in Fourth (such as a new job title).
  • Error — If there was an issue, this provides a description of the problem, including help with how to provide valid data. For successfully processed requests, this is left blank. 

In the example response below, the XML data is truncated to make it easier to view the JSON properties. 

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

[
    {
        "Id": 81,
        "XmlType": "employee",
        "ReferenceNumber": "acme12",
        "Xml": "<Employee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">
   <EmployeeNumber>acme12</EmployeeNumber>
   ...
</Employee>",
        "Status": "Updated",
        "DateCreatedUtc": "2018-02-07T14:01:13.0583374",
        "Error": ""
    },
    {
        "Id": 80,
        "XmlType": "employee",
        "ReferenceNumber": "acme31",
        "Xml": "<Employee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">
   <EmployeeNumber>acme31</EmployeeNumber>
   ...
</Employee>",
   "Status": "ValidationError",
   "DateCreatedUtc": "2018-02-07T13:29:32.9535221",
   "Error": "Validation error(s) updating employee: Employee's Pay Type can be changed only on the Rota Week Start Day"
    },
   {
        "Id": 79,
        "XmlType": "employee",
        "ReferenceNumber": "acme23",
        "Xml": "<Employee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">
   <EmployeeNumber>acme23</EmployeeNumber>
   ...
</Employee>",
        "Status": "InternalError",
        "DateCreatedUtc": "2018-02-07T07:46:38.4610637",
        "Error": "System.Exception: Unexpected error adding employee: Missing or invalid 'Personal Email' - . Must be a valid email address because Global Setting 'Personal Email Address Mandatory?' is on. Supported format: [Alphanumeric or Characters ._%+-] [@] [Alphanumeric or Characters &.-][.][This value must be between 2 and 4 characters long]. This value must not exceed 40 characters."
    },
   {
        "Id": 78,
        "XmlType": "employee",
        "ReferenceNumber": "acme03",
        "Xml": "<Employee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">
   <EmployeeNumber>acme03</EmployeeNumber>
   ...
</Employee>",
   "Status": "InternalError",
   "DateCreatedUtc": "2018-02-05T10:27:21.9098163",
   "Error": "System.Exception: Unexpected error adding employee: 'First Names' is a required field."
    }
]