Introduction
The People First OData APIs are ideal for bulk data query operations, such as report generation. OData is a standard protocol that defines a RESTful API for consuming and querying data. As a RESTful API, it places very few technology constraints on how it can be accessed. It is supported natively by many third party products, such as Microsoft Excel and Microsoft Power BI. OData libraries are available for most popular programming languages. For detailed information and specifications regarding OData please refer to the OData site.
OData Support
While the OData protocol itself provides supports for data create, read, update, and delete operations, the People First OData APIs are designed specifically for data extraction purposes and is therefore read-only. The People First OData services support OData v4.0 and both JSON and XML response formats.
OData API Authentication
All OData API requests should be authenticated using an access token. For data tools that have native support for either HTTP Bearer, or Basic Authentication, you should follow the People First Access Token instructions here.
Where a data tool doesn't natively support Bearer or Basic Authentication, you might be able to configure a custom authentication mechanism within the tool. An example of creating a custom authentication configuration for tools using Microsoft Power Query (e.g. Excel and Power BI) can be found here.
API Compatibility Considerations
As with the other People First APIs, consumers of the OData APIs will need to be aware of the type of changes that are considered to be backwards compatible, and will need to code their applications to handle them. Further details are available here.
Data API Discovery
OData aims to provide a self-describing data model and API for accessing that data model. This allows generic clients to interact with an OData service by discovering its data API using well defined mechanisms. The starting point for accessing any OData service is the service root URI.
All OData services publish a service document resource. The service document lists all of the
resources (entity sets, functions, singletons) that are available from the service. The service
document resource can be retrieved by issuing a GET
request to the service root URI.
In addition, an OData service will publish a metadata document resource. The metadata document lists
all of the data types, sets, functions, and actions understood by the service. This allows you to
understand the entities (resources) that the service exposes and how to interact with them. The
metadata document resource can be retrieved by issuing a GET
request to the URI
obtained by appending /$metadata
to the service root URI.
The following examples show the relationship between the discovery URIs:
- Service Root -
https://mydomain.com/myservice/odata
- Service Document -
https://mydomain.com/myservice/odata
- Metadata Document -
https://mydomain.com/myservice/odata/$metadata
Below is a snippet from a typical service document:
{
"@odata.context": "https://mydomain.com/myservice/odata/$metadata",
"value": [
{
"name": "applicationstates",
"url": "applicationstates"
},
{
"name": "applications",
"url": "applications"
},
{
"name": "applicants",
"url": "applicants"
}
]
}
The above service document describes an OData service that exposes three entity set resources, namely applicants, applications, and applicationstates. The service document also provides a link to the metadata document describing those resources.
Below is a snippet from a typical metadata document:
<?xml version='1.0' encoding='UTF-8'?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
<edmx:DataServices>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="MyService">
<EntityType Name="applicant">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Forename" Type="Edm.String" MaxLength="255"/>
<Property Name="Surname" Type="Edm.String" MaxLength="255"/>
<Property Name="Id" Type="Edm.Guid"/>
<NavigationProperty Name="Applications" Type="Collection(MyService.application)" Partner="Applicant">
<ReferentialConstraint Property="Id" ReferencedProperty="Applicantid"/>
</NavigationProperty>
</EntityType>
<EntityType Name="application">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.Guid"/>
<Property Name="CurrentStateId" Type="Edm.Guid"/>
<Property Name="Applicantid" Type="Edm.Guid"/>
<NavigationProperty Name="CurrentState" Type="MyService.applicationstate">
<ReferentialConstraint Property="CurrentStateId" ReferencedProperty="Id"/>
</NavigationProperty>
<NavigationProperty Name="Applicant" Type="MyService.applicant" Partner="Applications">
<ReferentialConstraint Property="Applicantid" ReferencedProperty="Id"/>
</NavigationProperty>
</EntityType>
<EntityType Name="applicationstate">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="CurrentStage" Type="Edm.String" MaxLength="255"/>
<Property Name="Id" Type="Edm.Guid"/>
<Property Name="CreationDate" Type="Edm.DateTimeOffset" Precision="3"/>
<Property Name="ApplicationId" Type="Edm.Guid"/>
<Property Name="CurrentStageDescription" Type="Edm.String" MaxLength="255"/>
<Property Name="NextStage" Type="Edm.String" MaxLength="255"/>
<NavigationProperty Name="Application" Type="MyService.application">
<ReferentialConstraint Property="ApplicationId" ReferencedProperty="Id"/>
</NavigationProperty>
</EntityType>
<EntityContainer Name="MyServiceContainer">
<EntitySet Name="applicationstates" EntityType="MyService.applicationstate">
<NavigationPropertyBinding Path="Application" Target="applications"/>
</EntitySet>
<EntitySet Name="applications" EntityType="MyService.application">
<NavigationPropertyBinding Path="CurrentState" Target="applicationstates"/>
<NavigationPropertyBinding Path="Applicant" Target="applicants"/>
</EntitySet>
<EntitySet Name="applicants" EntityType="MyService.applicant">
<NavigationPropertyBinding Path="Applications" Target="applications"/>
</EntitySet>
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
The above metadata document describes the types that are contained within the entity sets that the service exposes e.g. the applicants entity set is comprised of MyService.applicant entities.
The document also defines the data model for each of those entities e.g. MyService.applicant has an Id, Forename, Surname, and navigable collection of applications (MyService.application).
People First OData Service Endpoints
Below is a list of the Service Root URIs for the People First OData services:
HRM - (Object model of all entities here)
- Service Root -
https://TENANT_CODE-ENVIRONMENT_CODE.people-first.com/api/v1/hrm/odata
Absence - (Object model of all entities here)
- Service Root -
https://TENANT_CODE-ENVIRONMENT_CODE.people-first.com/api/v1/hrm/odata/absences
Learning - (Object model of all entities here)
- Service Root -
https://TENANT_CODE-ENVIRONMENT_CODE.people-first.com/api/v1/learning/odata
Talent - (Object model of all entities here)
- Service Root -
https://TENANT_CODE-ENVIRONMENT_CODE.people-first.com/api/v1/talent/odata
Checkins - (Object model of all entities here)
- Service Root -
https://TENANT_CODE-ENVIRONMENT_CODE.people-first.com/api/v1/checkins/odata
Goals - (Object model of all entities here)
- Service Root -
https://TENANT_CODE-ENVIRONMENT_CODE.people-first.com/api/v1/goals/odata
Recognitions - (Object model of all entities here)
- Service Root -
https://TENANT_CODE-ENVIRONMENT_CODE.people-first.com/api/v1/recognitions/odata
Recruitment - (Object model of all entities here)
- Service Root -
https://TENANT_CODE-ENVIRONMENT_CODE.people-first.com/api/v1/recruitment/odata
Socialfeed - (Object model of all entities here)
- Service Root -
https://TENANT_CODE-ENVIRONMENT_CODE.people-first.com/api/v1/socialfeed/odata
Custom cards - (Object model of all entities here)
- Service Root -
https://TENANT_CODE-ENVIRONMENT_CODE.people-first.com/api/v1/customcards/odata
Aggregate - (Object model of all entities here)
- Service Root -
https://TENANT_CODE-ENVIRONMENT_CODE.people-first.com/api/v1/aggregate/audit/odata
Payroll - (Object model of all entities here)
- Service Root -
https://TENANT_CODE-ENVIRONMENT_CODE.people-first.com/api/v1/payroll/odata
OData Requests
There are many ways to request data via the OData APIs ranging from simple requests to complex
requests containing queries with multiple conditions and actions, such as filter
,
orderby
, and expand
. There are often several ways to request the same
data.
A few example requests (based upon the above service and metadata documents) are outlined below. For a detailed treatment of the different request and query options, please refer to the OData documentation.
For each example, the raw request, response, and a sample cURL command are presented.
The following parameters are used throughout:
TENANT_CODE
is the tenant code that was provided by MHR.ENVIRONMENT_CODE
is the environment code that was provided by MHR. When accessing your default environment (typically your production environment) the -ENVIRONMENT_CODE
hostname segment, andEnvironmentCode
HTTP header field can be omitted.ACCESS_TOKEN
is the access token supplied by your System Administrator, or ID token obtained separately (see:OIDC ID Tokens).
Request a list of all applicants
GET /api/v1/recruitment/odata/applicants HTTP/1.1
Host: TENANT_CODE-ENVIRONMENT_CODE.people-first.com
Accept-Language: en-GB
Content-Type: application/json; charset=utf-8
TenantCode: TENANT_CODE
EnvironmentCode: ENVIRONMENT_CODE
Authorization: Bearer ACCESS_TOKEN
{
"@odata.context": "https://TENANT_CODE-ENVIRONMENT_CODE.people-first.com/api/v1/recruitment/odata/$metadata#applicants",
"value": [
{
"Forename": "Jimmy",
"Surname": "Jobseeker",
"Id": "aa96f4fd-9df3-4ef1-8fac-17ae30f07e60",
},
{
"Forename": "Dotty",
"Surname": "Net",
"Id": "c33b1258-fe25-4a03-8ada-17bf3cb15dd1",
}
]
}
curl --location --request GET "https://tpruk-dev.people-first.com/api/v1/recruitment/odata/applicants" \
--header "TenantCode: tpruk" \
--header "EnvironmentCode: dev" \
--header "Accept-Language: en-GB" \
--header "Content-Type: application/json; charset=utf-8" \
--header "Authorization: Bearer eyJ0eXAiOiJKVMsntWbLxWnNnRNZva2iueYc7KTFKP1Kz6Paog
Request an applicant by their primary key (ID)
GET /api/v1/recruitment/odata/applicants(aa96f4fd-9df3-4ef1-8fac-17ae30f07e60) HTTP/1.1
Host: TENANT_CODE-ENVIRONMENT_CODE.people-first.com
Accept-Language: en-GB
Content-Type: application/json; charset=utf-8
TenantCode: TENANT_CODE
EnvironmentCode: ENVIRONMENT_CODE
Authorization: Bearer ACCESS_TOKEN
{
"@odata.context": "https://TENANT_CODE-ENVIRONMENT_CODE.people-first.com/api/v1/recruitment/odata/$metadata#applicants/$entity",
"Forename": "Jimmy",
"Surname": "Jobseeker",
"Id": "aa96f4fd-9df3-4ef1-8fac-17ae30f07e60"
}
curl --location --request GET "https://tpruk-dev.people-first.com/api/v1/recruitment/odata/applicants(aa96f4fd-9df3-4ef1-8fac-17ae30f07e60)" \
--header "TenantCode: tpruk" \
--header "EnvironmentCode: dev" \
--header "Accept-Language: en-GB" \
--header "Content-Type: application/json; charset=utf-8" \
--header "Authorization: Bearer eyJ0eXAiOiJKVMsntWbLxWnNnRNZva2iueYc7KTFKP1Kz6Paog
Request an applicant by their name
GET /api/v1/recruitment/odata/applicants?$filter=(Forename eq 'Jimmy') and (Surname eq 'Jobseeker') HTTP/1.1
Host: TENANT_CODE-ENVIRONMENT_CODE.people-first.com
Accept-Language: en-GB
Content-Type: application/json; charset=utf-8
TenantCode: TENANT_CODE
EnvironmentCode: ENVIRONMENT_CODE
Authorization: Bearer ACCESS_TOKEN
{
"@odata.context": "https://TENANT_CODE-ENVIRONMENT_CODE.people-first.com/api/v1/recruitment/odata/$metadata#applicants",
"value": [
{
"Forename": "Jimmy",
"Surname": "Jobseeker",
"Id": "aa96f4fd-9df3-4ef1-8fac-17ae30f07e60",
}
]
}
curl --location --request GET "https://tpruk-dev.people-first.com/api/v1/recruitment/odata/applicants?$filter=(Forename eq 'Jimmy') and (Surname eq 'Jobseeker')" \
--header "TenantCode: tpruk" \
--header "EnvironmentCode: dev" \
--header "Accept-Language: en-GB" \
--header "Content-Type: application/json; charset=utf-8" \
--header "Authorization: Bearer eyJ0eXAiOiJKVMsntWbLxWnNnRNZva2iueYc7KTFKP1Kz6Paog
Count the number of applicants
GET /api/v1/recruitment/odata/applicants?$count=true HTTP/1.1
Host: TENANT_CODE-ENVIRONMENT_CODE.people-first.com
Accept-Language: en-GB
Content-Type: application/json; charset=utf-8
TenantCode: TENANT_CODE
EnvironmentCode: ENVIRONMENT_CODE
Authorization: Bearer ACCESS_TOKEN
{
"@odata.context": "https://TENANT_CODE-ENVIRONMENT_CODE.people-first.com/api/v1/recruitment/odata/$metadata#applicants",
"@odata.count": 2,
"value": [
{
"Forename": "Jimmy",
"Surname": "Jobseeker",
"Id": "aa96f4fd-9df3-4ef1-8fac-17ae30f07e60",
},
{
"Forename": "Dotty",
"Surname": "Net",
"Id": "c33b1258-fe25-4a03-8ada-17bf3cb15dd1",
}
]
}
curl --location --request GET "https://tpruk-dev.people-first.com/api/v1/recruitment/odata/applicants?$count=true" \
--header "TenantCode: tpruk" \
--header "EnvironmentCode: dev" \
--header "Accept-Language: en-GB" \
--header "Content-Type: application/json; charset=utf-8" \
--header "Authorization: Bearer eyJ0eXAiOiJKVMsntWbLxWnNnRNZva2iueYc7KTFKP1Kz6Paog
Request an ordered list of applicants
GET /api/v1/recruitment/odata/applicants?$orderby=Forename HTTP/1.1
Host: TENANT_CODE-ENVIRONMENT_CODE.people-first.com
Accept-Language: en-GB
Content-Type: application/json; charset=utf-8
TenantCode: TENANT_CODE
EnvironmentCode: ENVIRONMENT_CODE
Authorization: Bearer ACCESS_TOKEN
{
"@odata.context": "https://TENANT_CODE-ENVIRONMENT_CODE.people-first.com/api/v1/recruitment/odata/$metadata#applicants",
"value": [
{
"Forename": "Dotty",
"Surname": "Net",
"Id": "c33b1258-fe25-4a03-8ada-17bf3cb15dd1",
},
{
"Forename": "Jimmy",
"Surname": "Jobseeker",
"Id": "aa96f4fd-9df3-4ef1-8fac-17ae30f07e60",
}
]
}
curl --location --request GET "https://tpruk-dev.people-first.com/api/v1/recruitment/odata/applicants?$orderby=Forename" \
--header "TenantCode: tpruk" \
--header "EnvironmentCode: dev" \
--header "Accept-Language: en-GB" \
--header "Content-Type: application/json; charset=utf-8" \
--header "Authorization: Bearer eyJ0eXAiOiJKVMsntWbLxWnNnRNZva2iueYc7KTFKP1Kz6Paog
Request an applicant by their primary key (ID) and include all of their applications
GET /api/v1/recruitment/odata/applicants(aa96f4fd-9df3-4ef1-8fac-17ae30f07e60)?$expand=Applications HTTP/1.1
Host: TENANT_CODE-ENVIRONMENT_CODE.people-first.com
Accept-Language: en-GB
Content-Type: application/json; charset=utf-8
TenantCode: TENANT_CODE
EnvironmentCode: ENVIRONMENT_CODE
Authorization: Bearer ACCESS_TOKEN
{
"@odata.context": "https://TENANT_CODE-ENVIRONMENT_CODE.people-first.com/api/v1/recruitment/odata/$metadata#applicants/$entity",
"Forename": "Jimmy",
"Surname": "Jobseeker",
"Id": "aa96f4fd-9df3-4ef1-8fac-17ae30f07e60",
"Applications": [
{
"Id": "47aedb1b-a2e2-4c6d-9065-17ae722ae740",
"CurrentStateId": "f75c757c-8112-4847-9b0b-17ba06e338b0",
"Applicantid": "aa96f4fd-9df3-4ef1-8fac-17ae30f07e60",
},
{
"Id": "bbb0b87a-9401-4528-815f-17b9c2403e00",
"CurrentStateId": "5a1f8e17-c8a3-4a97-93d3-17b9d01d0ef0",
"Applicantid": "aa96f4fd-9df3-4ef1-8fac-17ae30f07e60",
}
]
}
curl --location --request GET "https://tpruk-dev.people-first.com/api/v1/recruitment/odata/applicants(aa96f4fd-9df3-4ef1-8fac-17ae30f07e60)?$expand=Applications" \
--header "TenantCode: tpruk" \
--header "EnvironmentCode: dev" \
--header "Accept-Language: en-GB" \
--header "Content-Type: application/json; charset=utf-8" \
--header "Authorization: Bearer eyJ0eXAiOiJKVMsntWbLxWnNnRNZva2iueYc7KTFKP1Kz6Paog
Configuring Authentication for Microsoft Power Query
Below are some instructions on how to configure Power Query applications to authenticate with the People First OData API.
- From the Data tab select the
Get Data
dropdown menu. From the dropdown, select theFrom Other Sources
and thenBlank Query
menu items. This will open the Power Query Editor.
- Select the query you want to configure from the list within the left-hand panel. Right-click and
select
Advanced Editor
from the context menu. This will display the Advanced Editor dialog.
- Paste the following query script into the Advanced Editor, substituting the placeholders with
values appropriate for your system and use case.
let Source = OData.Feed("https://TENANT_CODE-ENVIRONMENT_CODE.people-first.com/ODATA_REQUEST_URI_PATH" , null , [Headers=[TenantCode="TENANT_CODE", EnvironmentCode="ENVIRONMENT_CODE", Authorization="Bearer ACCESS_TOKEN"]]) in Source
Where:
TENANT_CODE
is the tenant code that was provided by MHR.ENVIRONMENT_CODE
is the environment code that was provided by MHR. When accessing your default environment (typically your production environment) the -ENVIRONMENT_CODE
hostname segment, andEnvironmentCode
HTTP header field can be omitted.ODATA_REQUEST_URI_PATH
is the URI path for the OData request you are making.ACCESS_TOKEN
is the access token supplied by your System Administrator, or ID token obtained separately (see:OIDC ID Tokens).
- You might be prompted to edit your credentials. If so, open the
Edit Credentials
dialog and choose anonymous access.
- You should now be presented with a preview of your OData query results.