External Payroll Integration

Purpose

To provide an integrator with a guide to how to develop an interface to use People First and an external Payroll application.

This document assumes reader has knowledge of People First terminology and is familiar with API authentication methods, general API usage, and HTTP status codes.

Integration types

Integration Overview – External Payroll

Image showing an integration overview of an external payroll.

Integration Overview – External Benefits Provider

Image showing an integration overview of an external benefits provider.

Integration Overview – External Benefits Provider (File based)

Image showing an integration overview of an external benefits provider (file based).

Data mapping/setup

Employees will be mapped using personal reference number in both applications. If multiple payrolls are being used, it would be sensible to set up a custom card in People First against the person to hold the payroll name.

Any People First custom cards used in the integration need to have the integration option enabled so event stream events for those custom cards get sent out.

Potential data that needs to go into external application

At some point, the People First data required by the payroll application to process the payroll, needs to be onboarded into the payroll application.

This data will/could include the following:

Person Data

  • Person Information
  • Bank Details
  • Drivers Details
  • Contact Details
  • Address
  • Custom Cards (Created to support any additional data that People First does not hold that’s mandatory in the system)

Employment Data

  • Job Information Card
  • Terms & Conditions
  • Schemes and Benefits
  • Hours and Basis
  • Working Pattern
  • Salary
  • Custom Cards (Created to support any additional data that People First does not hold that’s mandatory in the system)

Absence Data

  • Start Date
  • End Date
  • Start Date Type
  • End Date Type
  • Absence Type
  • Absence Reason
  • Duration
  • Supplementary Fields

The interface will go live at some date. We only need a snapshot of the data above for the relevant employees at that date to go into the payroll application.

There are several ways of obtaining and loading this data into the payroll application which will be listed here:

A table showing methods of loading data into payroll and associated pros and cons.
Method Advantages Disadvantages
PF Event Stream APIs Same method as going to use for BAU changes Need to process events over all time yet only need data at go live date.

Not all required data covered by event stream, ie. S&Bs, driver details

PF OData APIs Returns current data which is closer to what we need for onboarding.

Can make API calls per employee to make it more granular

Not all required data covered by OData APIs, ie. S&Bs, bank accounts.
PF Exports No development work required. Needs to be manually done by PF user with access.

The recommended option for onboarding depends on many things – the number of employees, the technical level of the developers/integrators, the capabilities of the payroll application etc.

If the payroll application has a file-based onboarding process, then it may be simple to just use People First exports and then manipulate the outputs into files for loading into the payroll application for the onboarding.

Use webhooks to push People First event data changes to external application

Webhooks can be set up to receive the People First events, and then trigger further processing to allow the external payroll application to use the data.

The webhook will be attached to something like an Azure logic app, an Azure function app etc which will get triggered when an event is received. This will trigger further processing, such as storing the event bodies in a data store and performing some processing within the external payroll application.

The payroll application may only process changes periodically so it may end up fetching all of the changes within a period and processing them in bulk. It is likely that the event data will be stored in some sort of data structure like that shown in the later ‘People First Event Type Data’ section later in this document.

External application pulls People First event data changes

Once the integration goes live, we are into BAU (Business as usual) phase where only changes from People First will update the payroll application.

If webhooks are being used then the webhook will receive the People First events and push the contents some some other data store

Making calls to People First event stream APIs

The People First event stream API is:

GET PFBASEURI/api/v1/rtpi/eventstream?eventTypes=xxx&timeOfCreationFrom=YYYY-MM-DDTHH:MI:SSZ&timeOfCreationTo=YYYY-MM-DDTHH:MI:SSZ&page[Limit]=mmm&page[Offset]=nnn

Let’s go through the query parameters on this uri (the query parameters are the part of the uri after the first ?). The different parts of the query string are separated by &

All of these query parameters are mandatory.

eventTypes=xxx means get events with type xxx only

These 2 parameters restrict the events to those created between certain datetimes – the external application will need to know when the interface was last run and only get events after then and before the current time.

timeOfCreationFrom=YYYY-MM-DDTHH:MI:SSZ

timeOfCreationTo=YYYY-MM-DDTHH:MI:SSZ

This parameter is about managing the result set being returned

page[Limit]=mmm&page[Offset]=nnn

mmm is the maximum number of results the API call will return, and nnn is the number of records to skip because we have already retrieved those records. Recommended values are 100 for mmm and 0 for nnn initially. Subsequent calls, if there are more records, will increase nnn by the mmm value so as to not process the same records more than once – this will be explained in more detail below in the example.

List of Event Types

The People First event stream returns a list of event types which can be put into groups because of the structure of the data they return. An interface should process these events by the groups and make separate event stream API calls for each group. The list of event types and groups relevant to an external payroll are:

A table showing examples of event types.
Event Type Group Event Types
Person PersonCreated, PersonNameChanged
PersonAddress PersonAddressCreated, PersonAddressChanged

PersonContact PersonContactDetailCreated, PersonContactDetailChanged
SocialSecurityNumber SocialSecurityNumberChanged
EmploymentPeriod EmploymentPeriodCreated, EmploymentPeriodEnded, EmploymentPeriodReinstated
EmploymentPeriodStartDate EmploymentPeriodStartDateChanged
ReckonableService ReckonableServiceDateCreated, ReckonableServiceDateChanged, ReckonableServiceDateDeleted
SensitiveInformation SensitiveInformationChanged
Occupancy OccupancyCreated, OccupancyEnded, OccupancyReinstated, OccupancyDeleted
OccupancyStartDate OccupancyStartDateChanged
OccupancyHoursAndBasis OccupancyHoursAndBasisCreated, OccupancyHoursAndBasisChanged
OccupancySalary OccupancySalaryTimelineCreated, OccupancySalaryTimelineChanged
OccupancyWorkingPattern WorkingPatternCreated, WorkingPatternChanged
BankAccount BankAccountCreated, BankAccountChanged, BankAccountDeleted
CustomCards CustomCardDataCreated, CustomCardDataChanged, CustomCardDataDeleted

There are other event types for Absence & Time & Attendance which will be included at a later stage.

Event Stream API Example (No Paging)

The following API call will return the Person group events within a timeframe, and we have used the default paging parameters to limit results to 100.

GET PFBASEURI/api/v1/rtpi/eventstream?eventTypes=PersonCreated&eventTypes=PersonNameChanged&timeOfCreationFrom=2024-03-22T15:17:00Z&timeOfCreationTo=2024-04-22T08:44:00Z&page[Limit]=100&page[Offset]=0

The response is:

{
    "meta": {
        "links": {
            "self": {
                "href": "/rtpi/eventstream?eventTypes=PersonCreated&eventTypes=PersonNameChanged&timeOfCreationFrom=2024-03-22T15:17:00Z&timeOfCreationTo=2024-04-22T08:44:00Z&page[Limit]=100&page[Offset]=0"
            },
            "first": {
                "href": "/rtpi/eventStream?page%5BLimit%5D=100&page%5BOffset%5D=0&timeOfCreationFrom=2024-03-22T15%3A17%3A00Z&timeOfCreationTo=2024-04-22T08%3A44%3A00Z"
            },
            "last": {
                "href": "/rtpi/eventStream?page%5BLimit%5D=100&page%5BOffset%5D=0&timeOfCreationFrom=2024-03-22T15%3A17%3A00Z&timeOfCreationTo=2024-04-22T08%3A44%3A00Z"
            }
        },
        "eventStream.results": {
            "items": 11,
            "total": 11
        }
    },
    "data": {
        "eventStream": [
            {
                "_links": {},
                "eventType": "PersonCreated",
                "timeOfReceipt": "2024-04-18T13:00:59.9118186Z",
                "timeOfCreation": "2024-04-18T13:00:58.7318535Z",
                "eventData": {
                    "personId": "64d85598-ae4c-4bf4-9a35-b15600d67fd0",
                    "personalReference": "V71001",
                    "firstName": "Kenny",
                    "lastName": "McCall",
                    "otherNames": "John William",
                    "knownAs": "Kenny",
                    "previousLastName": "",
                    "titleCode": "TITLE0001"
                }
            },
        

9 results removed to save space!

            {
                "_links": {},
                "eventType": "PersonCreated",
                "timeOfReceipt": "2024-04-02T18:28:51.670397Z",
                "timeOfCreation": "2024-04-02T18:28:50.7127437Z",
                "eventData": {
                    "personId": "ed8ee996-2d53-4925-bcab-b14601308cdc",
                    "personalReference": "J50001",
                    "firstName": "Olivia",
                    "lastName": "Jereme",
                    "otherNames": "Jane",
                    "knownAs": "Olivia",
                    "previousLastName": "",
                    "titleCode": "TITLE0001"
                }
            }
        ]
    }
}
        

Notice the following:

  • The items are returned in reverse created datetime order
  • The eventStream.results has items and total of 11 which as they are same value, there are no more results to return for this event type group.

Event Stream API Example (Paging)

The following API call will return the EmploymentPeriod group events within a timeframe, and we have used the default paging parameters to limit results to 100.

GET PFBASEURI/api/v1/rtpi/eventstream?eventTypes=EmploymentPeriodCreated&eventTypes=EmploymentPeriodEnded&eventTypes=EmploymentPeriodReinstated&timeOfCreationFrom=2023-03-22T15:17:00Z&timeOfCreationTo=2024-04-22T08:44:00Z&page[Limit]=100&page[Offset]=0

The response is:

{
    "meta": {
        "links": {
            "self": {
                "href": "/rtpi/eventstream?eventTypes=EmploymentPeriodCreated&eventTypes=EmploymentPeriodEnded&eventTypes=EmploymentPeriodReinstated&timeOfCreationFrom=2023-03-22T15:17:00Z&timeOfCreationTo=2024-04-22T08:44:00Z&page[Limit]=100&page[Offset]=0"
            },
            "first": {
                "href": "/rtpi/eventStream?page%5BLimit%5D=100&page%5BOffset%5D=0&timeOfCreationFrom=2023-03-22T15%3A17%3A00Z&timeOfCreationTo=2024-04-22T08%3A44%3A00Z"
            },
            "last": {
                "href": "/rtpi/eventStream?page%5BLimit%5D=100&page%5BOffset%5D=500&timeOfCreationFrom=2023-03-22T15%3A17%3A00Z&timeOfCreationTo=2024-04-22T08%3A44%3A00Z"
            },
            "next": {
                "href": "/rtpi/eventStream?page%5BLimit%5D=100&page%5BOffset%5D=100&timeOfCreationFrom=2023-03-22T15%3A17%3A00Z&timeOfCreationTo=2024-04-22T08%3A44%3A00Z"
            }
        },
        "eventStream.results": {
            "items": 100,
            "total": 546
        }
    },
    "data": {
        "eventStream": [
            {
                "_links": {},
                "eventType": "EmploymentPeriodCreated",
                "timeOfReceipt": "2024-04-18T13:00:59.7711933Z",
                "timeOfCreation": "2024-04-18T13:00:58.3412218Z",
                "eventData": {
                    "personId": "64d85598-ae4c-4bf4-9a35-b15600d67fd0",
                    "personalReference": "V71001",
                    "startDate": "2024-04-18"
                }
            },

98 records removed

            {
                "_links": {},
                "eventType": "EmploymentPeriodCreated",
                "timeOfReceipt": "2023-06-30T15:54:22.2937798Z",
                "timeOfCreation": "2023-06-30T15:53:42.3793183Z",
                "eventData": {
                    "personId": "5868c457-76cb-4fed-8f1b-b0310105f176",
                    "personalReference": "K00430",
                    "startDate": "2023-07-27"
                }
            }
        ]
    }
}
        

Notice from the response:

  • eventStream.results shows items 100 and total 546 which means only the first 100 have been returned.

In the response meta links there is a next link – this means that there are more records and we should keep making more requests until no data or no next link is returned to get the rest of the data.

The next link contains the next offset value for the paging

The next step is to get the next 100 records which would be using API call:

GET PFBASEURI/api/v1/rtpi/eventstream?eventTypes=EmploymentPeriodCreated&eventTypes=EmploymentPeriodEnded&eventTypes=EmploymentPeriodReinstated&timeOfCreationFrom=2023-03-22T15:17:00Z&timeOfCreationTo=2024-04-22T08:44:00Z&page[Limit]=100&page[Offset]=100
        

And so on until all the records are retrieved.

Processing People First event data in external application

The following diagram gives an idea of how the data from the event types fits together.

Essentially, a person can have one address, one set of sensitive information, many different contact types, many bank accounts.

Each person has one employment period at any one time. Each employment period can have multiple occupancies at any one time.

Each occupancy can have salary, hours and basis, and working pattern details. At any one time, each occupancy has one salary record, one hours and basis record, and one working pattern.

Absences are generated for an occupancy. People First events store same data for different absence types. Absence events are grouped into Leave, Sickness & Other groups. The Other group includes maternity, paternity, unpaid leave types etc.

People First Event Type Data – how the data from the event types fits together

Image showing how data from event types fits together.

Examples of event type bodies in responses

PersonNameChanged


              { 
                  "personId": "e12b10d4-eea2-4328-bf1b-a87f009c537b",
                  "personalReference": "A00014",
                  "firstName": "Lisa",
                  "lastName": "Pollard",
                  "otherNames": "Pollyanna",
                  "knownAs": "Lisa",
                  "previousLastName": "Planer",
                  "titleCode": "TITLE0005"
              }
          

PersonCreated


              {
                  "personId": "04552aea-da95-4160-a79b-b14e0076bf5e",
                  "personalReference": "A41009",
                  "firstName": "Kiara",
                  "lastName": "Middlemiss",
                  "otherNames": "Fleur",
                  "knownAs": "Kiara", 
                  "previousLastName": "",
                  "titleCode": "TITLE0003"
             }  
          

PersonAddressChanged


              { 
                  "personId": "e12b10d4-eea2-4328-bf1b-a87f009c537b",
                  "personalReference": "A00014",
                  "addressLine1": null,
                  "addressLine2": "134 Cambridge Road",
                  "addressLine3": "Hucknall",
                  "addressLine4": "Nottingham",
                  "addressLine5": null,
                  "addressLine6": "NG15 2BD",
                  "countryCode": "GBR"
              }
          

PersonAddressCreated


              { 
                  "personId": "db753242-60e6-491c-a06c-b14800e00d46",
                  "personalReference": "V30001",   
                  "addressLine1": "", 
                  "addressLine2": "181 Eastwood Road",  
                  "addressLine3": "Kimberley",   
                  "addressLine4": "Nottingham",   
                  "addressLine5": "", 
                  "addressLine6": "NG16 2BD",
                  "countryCode": "GBR"  
              }
          

PersonContactDetailChanged


              {   
                  "personId": "db753242-60e6-491c-a06c-b14800e00d46",  
                  "contactType": "PersonalPhone",   
                  "contactDetail": "01159384490", 
                  "internationalDialingCode": "United Kingdom (+44)"  
              }
          

PersonContactDetailCreated


              {
                  "personId": "e12b10d4-eea2-4328-bf1b-a87f009c537b", 
                  "contactType": "CompanyMobile",  
                  "contactDetail": "07791765095",  
                  "internationalDialingCode": "United Kingdom (+44)"  
              }
          

SocialSecurityNumberChanged


              {   
                  "personId": "44eee4dd-8a21-46ab-adea-b15400748736",  
                  "personalReference": "F00001",  
                  "socialSecurityNumbers": [     
                      {       
                          "socialSecurityNumber": "JE198676C",  
                          "legislationCode": "UK"      
              
                      } 
                  ] 
              }
          

EmploymentPeriodStartDateChanged


              {
                  "personId": "64d85598-ae4c-4bf4-9a35-b15600d67fd0",  
                  "employmentPeriodId": "71cfecc7-3d58-4976-932b-b15600d68011",  
                  "personalReference": "V71001",  
                  "startDate": "2024-04-01"  
              }
          

EmploymentPeriodCreated


              {   
                  "personId": "98c1418e-3564-4306-88ff-b14800c97bd6", 
                  "personalReference": "V20002",  
                  "startDate": "2024-04-04"  
              }
              
          

EmploymentPeriodEnded


              {    
                  "personId": "98c1418e-3564-4306-88ff-b14800c97bd6", 
                  "personalReference": "V20002",  
                  "startDate": "2024-04-04",  
                  "endDate": "2024-04-12",  
                  "employerName": "",  
                  "isExitInterviewCompleted": false,  
                  "lastPaymentDate": null,
                  "lastWorkingDate": null,  
                  "reEmployableCode": null,  
                  "reasonForLeavingCode": null,  
                  "forwardingAddress": 
                      {
                          "line1": "",  
                          "line2": "",  
                          "line3": "",    
                          "line4": "",    
                          "line5": "",   
                          "line6": "",     
                          "forwardingAddressTypeCode": null  
                      }
              }
          

EmploymentPeriodReinstated


              {   
                  "personId": "98c1418e-3564-4306-88ff-b14800c97bd6",  
                  "personalReference": "V20002",  
                  "startDate": "2024-04-04"  
              }
          

SensitiveInformationChanged


              {    
                  "personId": "44eee4dd-8a21-46ab-adea-b15400748736",  
                  "personalReference": "F00001",  
                  "dateOfBirth": "1990-01-10",   
                  "countryOfCitizenshipCode": "XXX",  
                  "religionCode": "REL0038", 
                  "countryOfBirthCode": "XXX",   
                  "nationalityCode": "NAT0240",  
                  "genderCode": "GEN0037",  
                  "sexualOrientationCode": "SO0003", 
                  "maritalStatusCode": "MS0007",  
                  "selfCertifiedDisabilityDescription": "", 
                  "regionalSensitiveInformations": [     
                      {   
                          "regionCode": "UK",   
                          "ukEthnicOriginCode": "UKND",    
                          "legalGenderCode": "F"   
                      }
                  ]
              }
          

OccupancyCreated


              {   
                  "occupancyId": "94aad668-4aaf-4a48-9bce-b15600d69675",
                  "personalReference": "V71001",  
                  "jobReference": "A71001", 
                  "startDate": "2024-04-18",  
                  "endDate": null,  
                  "jobTitleRevisions": [  
                      {       
                          "name": "Left Back",     
                          "startDate": "2024-04-18",    
                          "endDate": null   
                      }   
                  ] 
              }	
          

OccupancyStartDateChanged


              {   
                  "personId": "64d85598-ae4c-4bf4-9a35-b15600d67fd0", 
                  "occupancyId": "94aad668-4aaf-4a48-9bce-b15600d69675",
                  "personalReference": "V71001",
                  "startDate": "2024-04-01"  
              }	
          

OccupancyDeleted


              {   
                  "occupancyId": "1d594e5e-d335-4470-a283-a87f00b0ee8e",  
                  "personalReference": "A00342",  
                  "jobReference": "A00342", 
                  "startDate": "2017-04-10",  
                  "endDate": "2024-04-03",  
                  "jobTitleRevisions": [    
                      {       
                          "name": "Developer",  
                          "startDate": "2017-04-10",   
                          "endDate": "2020-02-14"     
                      }, 
                      {
                          "name": "Developer",   
                          "startDate": "2020-02-15",   
                          "endDate": "2024-04-03"
                      }
                  ]
              }
          

OccupancyEnded


              {   
                  "occupancyId": "21248706-03b0-4cf5-9610-b1480100bfcf",  
                  "personalReference": "A00342", 
                  "jobReference": "V50005", 
                  "startDate": "2024-04-04", 
                  "endDate": null,  
                  "jobTitleRevisions": []  
              }
          

OccupancyReinstated


              {    
                  "occupancyId": "90408fe0-974b-4066-aa48-b14800c98a4f", 
                  "personalReference": "V20002", 
                  "jobReference": "A80003", 
                  "startDate": "2024-04-04",  
                  "endDate": null,   
                  "jobTitleRevisions": [    
                      {      
                          "name": "Assistant Accountant",      
                          "startDate": "2024-04-04",    
                          "endDate": "2024-04-14" 
                      }, 
                      {
                          "name": "Assistant Accountant",  
                          "startDate": "2024-04-15",   
                          "endDate": null    
                      }
                  ] 
              }
          

ReckonableServiceDateCreated


              {    
                  "reckonableServiceDate": "2017-03-01",  
                  "personId": "64d85598-ae4c-4bf4-9a35-b15600d67fd0",  
                  "personalReference": "V71001",  
                  "employmentPeriodId": "71cfecc7-3d58-4976-932b-b15600d68011" 
              }	
          

ReckonableServiceDateChanged


              {    
                  "reckonableServiceDate": "2017-04-01",
                  "personId": "64d85598-ae4c-4bf4-9a35-b15600d67fd0",  
                  "personalReference": "V71001",  
                  "employmentPeriodId": "71cfecc7-3d58-4976-932b-b15600d68011" 
              }
          

ReckonableServiceDateDeleted


              {    
                  "personId": "64d85598-ae4c-4bf4-9a35-b15600d67fd0",  
                  "personalReference": "V71001",   
                  "employmentPeriodId": "71cfecc7-3d58-4976-932b-b15600d68011"  
              }	
          

OccupancyHoursAndBasisChanged


              {   
                  "occupancyId": "203c8c77-34b1-4f1f-9201-acc5013bb6e4", 
                  "personalReference": "J00506",
                  "personId": "c2ee85e6-1b37-4d48-8c7b-acc50133f126",  
                  "jobReference": "J00506",  
                  "startDate": "2021-02-04", 
                  "endDate": null,  
                  "hoursAndBasisRevisions": [     
                      {        
                          "startDate": "2024-04-08",  
                          "endDate": null,    
                          "contractualHours": 37.50,    
                          "fteHours": 37.50,      
                          "fteValue": 1.00,      
                          "annualWeeksWorked": 52.14300,    
                          "categoryCode": "EC0001",    
                          "basisCode": "EB0002",    
                          "typeCode": "ET0003",      
                          "employmentIsTermTimeOnly": false,      
                          "lengthOfStandardDay": null      
                      } 
                  ]
              }
          

OccupancyHoursAndBasisCreated


              {    
                   "occupancyId": "ecdcbc42-5ea4-4d1b-932d-b14e0076da21", 
                   "personalReference": "A41009", 
                   "personId": "04552aea-da95-4160-a79b-b14e0076bf5e",
                   "jobReference": "F31164",  
                   "startDate": "2024-04-10",  
                   "endDate": null,   
                   "hoursAndBasisRevisions": [      
                       {       
                           "startDate": "2024-04-10",   
                           "endDate": null,     
                           "contractualHours": 37.50, 
                           "fteHours": 37.50,     
                           "fteValue": 1.00,   
                           "annualWeeksWorked": 52.14300,    
                           "categoryCode": "EC0001",    
                           "basisCode": "EB0002",     
                           "typeCode": "ET0003",      
                           "employmentIsTermTimeOnly": false,   
                           "lengthOfStandardDay": 7.50  
                       }  
                   ]
              }
          

OccupancySalaryTimelineChanged


              {    
                  "occupancyId": "53895dde-a676-4547-88a7-b14800e4c196",  
                  "personalReference": "V30001", 
                  "jobReference": "V40001",    
                  "startDate": "2024-04-04", 
                  "endDate": null,   
                  "salaryRevisions": [     
                      {     
                          "startDate": "2024-04-04",     
                          "endDate": null,      
                          "rateOfPay": 41000.0,   
                          "frequencyCode": "A"   
                      }   
                  ] 
              }
          

OccupancySalaryTimelineCreated


              {   
                  "occupancyId": "8725c5f3-aa50-4545-89fd-b154007499a7",  
                  "personalReference": "F00001", 
                  "jobReference": "F00001",  
                  "startDate": "2024-04-22",  
                  "endDate": null, 
                  "salaryRevisions": [  
                      {      
                          "startDate": "2024-04-22",  
                          "endDate": null,     
                          "rateOfPay": 0.000000,     
                          "frequencyCode": "A"    
                      }   
                  ]  
              }
          

WorkingPatternChanged


              { 
                  "occupancyId": "cda3d25a-0457-4a17-b082-abae0099c0ff",  
                  "personalReference": "B00210",
                  "jobReference": "B00110",
                  "startDate": "2020-05-01",  
                  "endDate": null,  
                  "workingPatternRevisions": [   
                      {       
                          "startDate": "2020-05-01",      
                          "endDate": null,      
                          "name": "Mon-Fri 9-5.30pm",
                          "startDayNumber": 5,     
                          "numberOfDays": [       
                              {     
                                  "dayNumber": 1,    
                                  "totalMinutes": 420       
                              },        
                              {         
                                  "dayNumber": 2,  
                                  "totalMinutes": 450     
                              },       
                              {       
                                  "dayNumber": 3,  
                                  "totalMinutes": 450   
                              },         
                              {        
                                  "dayNumber": 4,   
                                  "totalMinutes": 450    
                              },    
                              {      
                                  "dayNumber": 5,  
                                  "totalMinutes": 450   
                              },        
                              {        
                                  "dayNumber": 6,  
                                  "totalMinutes": 0       
                              },    
                              {      
                                  "dayNumber": 7,    
                                  "totalMinutes": 0    
                              }       
                          ]    
                      }   
                  ]  
              }
          

WorkingPatternCreated


              {    
                  "occupancyId": "8725c5f3-aa50-4545-89fd-b154007499a7",  
                  "personalReference": "F00001",   
                  "jobReference": "F00001", 
                  "startDate": "2024-04-22",   
                  "endDate": null, 
                  "workingPatternRevisions": [   
                      {        
                          "startDate": "2024-04-22",   
                          "endDate": null,      
                          "name": "Mon-Fri 9-5.30pm",   
                          "startDayNumber": 1,     
                          "numberOfDays": [       
                              {         
                                  "dayNumber": 2,
                                  "totalMinutes": 450    
                              },       
                              {       
                                  "dayNumber": 4,  
                                  "totalMinutes": 450   
                              },     
                              {       
                                  "dayNumber": 5,
                                  "totalMinutes": 450  
                              },       
                              {        
                                  "dayNumber": 6,   
                                  "totalMinutes": 0      
                              },
                              {       
                                  "dayNumber": 7,   
                                  "totalMinutes": 0    
                              },     
                              {       
                                  "dayNumber": 3, 
                                  "totalMinutes": 450  
                              },       
                              {        
                                  "dayNumber": 1, 
                                  "totalMinutes": 450    
                              }      
                          ]     
                      }    
                  ] 
              }
          

BankAccountCreated


              {   
                  "personId": "191caf1d-6165-4b92-afa8-acc501344749", 
                  "personalReference": "J00712", 
                  "abaNumber": null,   
                  "accountHolderName": "Mx Ingrid Havers", 
                  "accountNumber": "49805577",
                  "accountTypeCode": null,   
                  "bankAccountCountryCode": "GBR",
                  "bankAddress": null,   
                  "bankName": "Santander",    
                  "bic": "",   
                  "branchName": "",  
                  "clabeNumber": null, 
                  "iban": null,    
                  "isPrimary": false,
                  "percentageSplit": 0, 
                  "rollNumber": "",  
                  "routingCode": null, 
                  "sortCode": "498766" 
              }
          

BankAccountChanged


              {   
                  "personId": "191caf1d-6165-4b92-afa8-acc501344749", 
                  "personalReference": "J00712", 
                  "abaNumber": null,   
                  "accountHolderName": "Mx Ingrid Davies4",  
                  "accountNumber": "49008768",  
                  "accountTypeCode": null, 
                  "bankAccountCountryCode": "GBR",  
                  "bankAddress": null, 
                  "bankName": "HSBC",  
                  "bic": "",  
                  "branchName": "",  
                  "clabeNumber": null,
                  "iban": null, 
                  "isPrimary": true,
                  "percentageSplit": 80,   
                  "rollNumber": "",  
                  "routingCode": null,
                  "sortCode": "457980"  
              }
          

OccupancySalaryAndHoursTimelineChanged


              { 
                  "occupancyId": "53895dde-a676-4547-88a7-b14800e4c196",  
                  "personId": "db753242-60e6-491c-a06c-b14800e00d46", 
                  "personalReferenceNumber": "V30001",  
                  "salaryAndHoursRevisions": [   
                      {       
                          "startDate": "2024-04-04", 
                          "endDate": "9999-01-01", 
                          "proRatedSalary": 39200.00,  
                          "annualHoursWorked": 1825.0050000,  
                          "fteValue": 0.9333333333333333333333333333,  
                          "hourlyRate": 21.48,   
                          "hourlyRateDaily": null,  
                          "frequencyCode": "A",      
                          "currencyCode": "GBP"    
                      }  
                  ]  
              }
          

CustomCardDataCreated


              {
                  "cardId": "dcb97b6b-1c0a-44a4-89ec-1782681a0930",
                  "cardName": "Security Checks",
                  "entityId": "db753242-60e6-491c-a06c-b14800e00d46",
                  "entityType": "employee",
                  "field1": "Yes",
                  "field2": "B",
                  "field3": null,
                  "field4": false,
                  "field5": "2024-04-19",
                  "field6": 0,
                  "field7": null,
                  "field8": "2024-04-19T00:00:00Z",
                  "field9": null,
                  "field10": null,
                  "field11": null,
                  "field12": "",
                  "field13": 0,
                  "field14": null,
                  "field15": null,
                  "field16": null,
                  "field17": null,
                  "field18": null,
                  "field19": "",
                  "field20": "A"
              }
          

CustomCardDataChanged


              {
                  "cardId": "dcb97b6b-1c0a-44a4-89ec-1782681a0930",
                  "cardName": "Security Checks",
                  "entityId": "db753242-60e6-491c-a06c-b14800e00d46",
                  "entityType": "employee",
                  "field1": "Yes",
                  "field2": "B",
                  "field3": "fgfdgfdgdfgfgfdg",
                  "field4": true,
                  "field5": "2024-04-17",
                  "field6": 45,
                  "field7": "No",
                  "field8": "2024-04-17T04:00:00Z",
                  "field9": "Updated Value",
                  "field10": "Field10",
                  "field11": null,
                  "field12": "",
                  "field13": 34,
                  "field14": null,
                  "field15": null,
                  "field16": "fgfdgdf",
                  "field17": null,
                  "field18": null,
                  "field19": "2024-04-17",
                  "field20": "C"
              }
          

CustomCardDataDeleted


              {
                  "cardId": "dcb97b6b-1c0a-44a4-89ec-1782681a0930",
                  "cardName": "Security Checks",
                  "entityId": "db753242-60e6-491c-a06c-b14800e00d46",
                  "entityType": "employee"
              }
          

AbsenceOtherCreated


              {   
                  "personId": "2fa7ec6a-d2e5-4fb8-a65a-aead0050115a",
                  "personalReference": "A00214", 
                  "occupancyId": "426ac7b0-3883-4bfe-acb6-aead00733851",  
                  "jobReference": "A00214",  
                  "absenceId": "f2c300bb-51c1-4553-99be-b15a00d568a7",    
                  "absenceTypeCode": "Maternity",
                  "absenceTypeName": "Maternity Leave",
                  "absenceCategoryCode": "other",  
                  "startDate": "2023-05-30",  
                  "startDatePartCode": "FirstHalf", 
                  "startDateTotalMinutes": null,  
                  "endDate": "2023-08-17",   
                  "endDatePartCode": "SecondHalf", 
                  "endDateTotalMinutes": null,  
                  "expectedEndDate": null,
                  "absenceStateCode": "NotApplicable", 
                  "sicknessReason": "",   
                  "absenceBookedDate": "2024-04-22T12:56:59", 
                  "lostHours": "",   
                  "totalExpectedWorkingTimeInMinutes": 26280,   
                  "totalLostTimeInMinutes": 26280  
              }
          

AbsenceSicknessCreated


              {
                  "personId": "2fa7ec6a-d2e5-4fb8-a65a-aead0050115a", 
                  "personalReference": "A00214", 
                  "occupancyId": "426ac7b0-3883-4bfe-acb6-aead00733851", 
                  "jobReference": "A00214",  
                  "absenceId": "fc1f6aa7-e1e8-41ad-90f2-b15a00d09651",  
                  "absenceTypeCode": "SICKNESS",  
                  "absenceTypeName": "Sickness", 
                  "absenceCategoryCode": "sickness", 
                  "startDate": "2023-05-24",  
                  "startDatePartCode": "FirstHalf",   
                  "startDateTotalMinutes": null,  
                  "endDate": "2023-05-24",   
                  "endDatePartCode": "SecondHalf", 
                  "endDateTotalMinutes": null,  
                  "expectedEndDate": null,   
                  "absenceStateCode": "NotApplicable", 
                  "sicknessReason": "Unknown", 
                  "absenceBookedDate": "2024-04-22T12:39:26",  
                  "lostHours": "",   
                  "totalExpectedWorkingTimeInMinutes": 510,  
                  "totalLostTimeInMinutes": 510  
              }
          

AbsenceLeaveCreated


              {   
                  "personId": "e948bd21-b66f-4999-af10-aead005067db",  
                  "personalReference": "A00410",
                  "occupancyId": "1162be26-18d6-4485-b781-aead0076f04a", 
                  "jobReference": "A00410",   
                  "absenceId": "17bae0f7-ac75-4f35-8129-b15a00cf7812", 
                  "absenceTypeCode": "HOLIDAY",
                  "absenceTypeName": "Leave",   
                  "absenceCategoryCode": "holiday", 
                  "startDate": "2023-05-16",  
                  "startDatePartCode": "FirstHalf",
                  "startDateTotalMinutes": null,  
                  "endDate": "2023-05-16", 
                  "endDatePartCode": "SecondHalf", 
                  "endDateTotalMinutes": null,  
                  "expectedEndDate": null,  
                  "absenceStateCode": "NotApplicable",  
                  "sicknessReason": "",    
                  "absenceBookedDate": "2024-04-22T12:35:22",  
                  "lostHours": "",
                  "totalExpectedWorkingTimeInMinutes": 510,   
                  "totalLostTimeInMinutes": 510 
              }	
          

AbsenceLeaveChanged


              {  
                  "personId": "e948bd21-b66f-4999-af10-aead005067db",
                  "personalReference": "A00410", 
                  "occupancyId": "1162be26-18d6-4485-b781-aead0076f04a",    
                  "jobReference": "A00410",   
                  "absenceId": "17bae0f7-ac75-4f35-8129-b15a00cf7812", 
                  "absenceTypeCode": "HOLIDAY",    
                  "absenceTypeName": "Leave",   
                  "absenceCategoryCode": "holiday",  
                  "originalStartDate": "2023-05-16",   
                  "originalStartDatePartCode": "FirstHalf",  
                  "originalStartDateTotalMinutes": null,    
                  "startDate": "2023-05-16",  
                  "startDatePartCode": "FirstHalf", 
                  "startDateTotalMinutes": null,  
                  "originalEndDate": "2023-05-16", 
                  "originalEndDatePart": "SecondHalf",  
                  "originalEndDateTotalMinutes": null, 
                  "endDate": "2023-05-17",   
                  "endDatePartCode": "SecondHalf", 
                  "endDateTotalMinutes": null,  
                  "expectedEndDate": null, 
                  "absenceStateCode": "NotApplicable",
                  "previousAbsenceStateCode": null,   
                  "sicknessReason": "",   
                  "absenceBookedDate": "2024-04-22T12:35:22", 
                  "lostHours": "",  
                  "totalExpectedWorkingTimeInMinutes": 1020, 
                  "totalLostTimeInMinutes": 1020 
              }
          

AbsenceOtherChanged


              {    
                  "personId": "4d0f052f-ccb3-4c55-83b3-aead004fceb7", 
                  "personalReference": "A00070",   
                  "occupancyId": "e1927321-c52e-4427-b5f1-aead00707748",  
                  "jobReference": "A00070",  
                  "absenceId": "f2b45ea8-8e5f-4010-9901-b13300c275c2", 
                  "absenceTypeCode": "Maternity",  
                  "absenceTypeName": "Maternity Leave",  
                  "absenceCategoryCode": "other",   
                  "originalStartDate": "2023-01-03", 
                  "originalStartDatePartCode": "FirstHalf",    
                  "originalStartDateTotalMinutes": null,  
                  "startDate": "2023-01-03",   
                  "startDatePartCode": "FirstHalf", 
                  "startDateTotalMinutes": null, 
                  "originalEndDate": "2023-06-30",  
                  "originalEndDatePart": "SecondHalf",   
                  "originalEndDateTotalMinutes": null,  
                  "endDate": "2023-09-08",  
                  "endDatePartCode": "SecondHalf",  
                  "endDateTotalMinutes": null,  
                  "expectedEndDate": null, 
                  "absenceStateCode": "NotApplicable",
                  "previousAbsenceStateCode": null,  
                  "sicknessReason": "",  
                  "absenceBookedDate": "2024-03-14T11:48:00", 
                  "lostHours": "", 
                  "totalExpectedWorkingTimeInMinutes": 80490,   
                  "totalLostTimeInMinutes": 80490 
              }
          

AbsenceSicknessChanged


              {    
                  "personId": "09fea856-6738-4d95-a109-aead004fe483", 
                  "personalReference": "A00121",  
                  "occupancyId": "41a7fbea-d541-497a-8280-aead00714267",
                  "jobReference": "A00121",  
                  "absenceId": "952d2482-4d86-47bc-b62c-b124008ac71b",
                  "absenceTypeCode": "SICKNESS",   
                  "absenceTypeName": "Sickness",   
                  "absenceCategoryCode": "sickness",   
                  "originalStartDate": "2022-12-03", 
                  "originalStartDatePartCode": "FirstHalf", 
                  "originalStartDateTotalMinutes": null,  
                  "startDate": "2022-12-03",   
                  "startDatePartCode": "FirstHalf",  
                  "startDateTotalMinutes": null,  
                  "originalEndDate": "2022-12-03", 
                  "originalEndDatePart": "SecondHalf", 
                  "originalEndDateTotalMinutes": null, 
                  "endDate": null,  
                  "endDatePartCode": null, 
                  "endDateTotalMinutes": null, 
                  "expectedEndDate": null, 
                  "absenceStateCode": "NotApplicable", 
                  "previousAbsenceStateCode": null,  
                  "sicknessReason": "Arthritis",  
                  "absenceBookedDate": "2024-02-28T08:25:16", 
                  "lostHours": "",   
                  "totalExpectedWorkingTimeInMinutes": 145530, 
                  "totalLostTimeInMinutes": 145530
              }	
          

AbsenceLeaveDeleted


              {   
                  "personId": "e948bd21-b66f-4999-af10-aead005067db", 
                  "personalReference": "A00410",  
                  "occupancyId": "1162be26-18d6-4485-b781-aead0076f04a",
                  "jobReference": "A00410",   
                  "absenceId": "17bae0f7-ac75-4f35-8129-b15a00cf7812",  
                  "absenceTypeCode": "HOLIDAY",  
                  "absenceTypeName": "Leave",   
                  "absenceCategoryCode": "holiday",  
                  "startDate": "2023-05-16",
                  "startDatePartCode": "FirstHalf",
                  "startDateTotalMinutes": null,  
                  "endDate": "2023-05-17", 
                  "endDateTotalMinutes": null, 
                  "endDatePartCode": "SecondHalf",
                  "expectedEndDate": null,    
                  "sicknessReason": "",  
                  "absenceBookedDate": "2024-04-22T12:35:22", 
                  "lostHours": "",  
                  "totalExpectedWorkingTimeInMinutes": 1020, 
                  "totalLostTimeInMinutes": 1020  
              }
          

AbsenceSicknessDeleted


              {   
                  "personId": "8abc7c4c-341f-4ff4-b044-aead004fe5f6",
                  "personalReference": "A00129",   
                  "occupancyId": "ca5abfe4-04f4-45a5-abf4-aead007162ca", 
                  "jobReference": "A00129", 
                  "absenceId": "ddbf3bd6-ed71-4080-8e79-b15c00934a32", 
                  "absenceTypeCode": "SICKNESS",  
                  "absenceTypeName": "Sickness",  
                  "absenceCategoryCode": "sickness", 
                  "startDate": "2024-05-16",    
                  "startDatePartCode": "FirstHalf",  
                  "startDateTotalMinutes": null, 
                  "endDate": "2024-05-16", 
                  "endDateTotalMinutes": null, 
                  "endDatePartCode": "SecondHalf",  
                  "expectedEndDate": null,  
                  "sicknessReason": "Unknown", 
                  "absenceBookedDate": "2024-04-24T08:56:15",
                  "lostHours": "",  
                  "totalExpectedWorkingTimeInMinutes": 510,  
                  "totalLostTimeInMinutes": 510 
              }
          

AbsenceOtherDeleted


              {   
                  "personId": "f58deb2c-ed41-44b9-9edd-aead004fe91e",   
                  "personalReference": "A00139",   
                  "occupancyId": "3111ec01-e647-474c-a498-aead0071779e", 
                  "jobReference": "A00139", 
                  "absenceId": "22026092-a7a7-4cb7-8336-b15c00957e1c",  
                  "absenceTypeCode": "Maternity", 
                  "absenceTypeName": "Maternity Leave",    
                  "absenceCategoryCode": "other",   
                  "startDate": "2023-05-30",   
                  "startDatePartCode": "FirstHalf", 
                  "startDateTotalMinutes": null,  
                  "endDate": "2023-09-29",   
                  "endDateTotalMinutes": null, 
                  "endDatePartCode": "SecondHalf", 
                  "expectedEndDate": null,   
                  "sicknessReason": "",   
                  "absenceBookedDate": "2024-04-24T09:04:17", 
                  "lostHours": "",    
                  "totalExpectedWorkingTimeInMinutes": 39990,   
                  "totalLostTimeInMinutes": 39990  
              }
          

Resolving reference data in the event type bodies

Some of the bodies of the event types contain fields suffixed with codes which refer to People First reference data – for example, titleCode in PersonCreated & PersonNameChanged.

To get the values that these codes refer to, it is possible to make People First API calls to get the mapping values. We do need to know the People First reference data type to do this. An example API call to get a titleCode is:

GET PFBASEURI/api/v1/hrm/odata/referencedatas?$filter=Type eq 'Title' and Code eq 'TITLE0003'&$expand=Translations($filter=Culture eq '')
        

The response value field contains the People First text for the titleCode.

It is possible to omit the Code eq 'TITLE0003' from the query and get all of the titleCodes and their values in one go. These are unlikely to change over time so they could be just obtained and loaded into the external payroll application as static data.

The Types for the majority of different lists of People First reference data are given by the Code field minus the Code part of the fieldname, ie. titleCode has reference data type of ‘Title’:

  • titleCode
  • religionCode
  • nationalityCode
  • genderCode
  • legalGenderCode
  • sexualOrientationCode
  • maritalStatusCode
  • ukEthnicOriginCode
  • frequencyCode
  • accountTypeCode
  • currencyCode
  • countryCode

The exceptions are the following types for the field codes:

  • categoryCode - EmploymentCategory
  • basisCode - EmploymentBasis
  • typeCode - EmploymentType
  • countryOfCitizenshipCode - Country
  • countryOfBirthCode - Country
  • bankAccountCountryCode - Country