Careers sites
An app can host one or more careers sites, e.g. one for graduate recruitment, one for a specific country, etc.
Each site might support:
- Static content and employment branding
- Browsing and searching for jobs
- Viewing details for a specific job
- On a specific job, displaying buttons for other apps, e.g. apply, share, refer, etc.
- On the site as a whole, displaying buttons for other apps, e.g. register
A tenant can designate (via some settings app) any site as the "primary", i.e. the main careers site.
Other apps will typically target the primary board when they create links to jobs (or to the site itself), e.g. links in:
- The main menu of the tenant's web site (i.e. leading to the "careers" section)
- Job alert emails
- Job board postings
- Social media shares
Implementing the APIs
Produced APIs
These are APIs that your app exposes for other apps to consume them.
-- CODE language-json --
[
{
"id": 12,
"label": "Graduate site",
"homePage": "http://example.com"
}
]
User Interface
Header /common area
Most sites have some kind of header or common area at the top of the page where the candidate's login status etc. is displayed.
Your site should inject HTML for the general buttons in this area, by consuming:
-- CODE language-json --
[
{
"app": "myapp",
"actions": [
{
"name": "refer",
"uri": "https://referrals.com/jobs/1022?tracker=106645",
"type": "button",
"label": "Refer a friend",
"textColor": "dddddd",
"backgroundColor": "010203",
"disabled": false
},
{
"name": "share",
"uri": "https://sharing.com/jobs/1022?tracker=106645",
"type": "button",
"label": "Share this job",
"textColor": "dddddd",
"backgroundColor": "010203",
"disabled": false
}
]
}
]
Job details page
Your site likely serves a "job details page" where the candidate can read the job description and click to apply.
LoggedIn filter
If your site supports login (a site that doesn't should only display publicly visible jobs), then this page should sit behind a loggedIn filter (as per our defined conventions).
This way a candidate who was logged in at another app (e.g. UberApply) and then linked to here (e.g. by clicking "View job details"), will be asked to log in, which should happen invisibly, and can then (for example) see internal details for the job if they are an internal.
Fetch details for job
Your site should parse the job's ID from the URL, then use it to consume APIs to get details about the job.
-- CODE language-json --
{
"id": 10334355,
"status": "active",
"org": 102234,
"availability": {
"availableInternally": true,
"availableExternally": false,
"applicationCloseDates": {
"closeDate": "2015-11-05T13:15:30Z",
"internalCloseDate": "2015-11-05T13:15:30Z",
"externalCloseDate": "2015-11-05T13:15:30Z"
},
"jobPublishDates": {
"publishDate": "2015-11-05T13:15:30Z"
}
},
"code": "1022NH",
"externalId": "SAP-1022",
"title": "Creative Director",
"shortSummary": "One of the most exciting positions ever offered",
"country": "AU",
"categories": [
{
"category": 1022,
"values": [
10024
]
},
{
"category": 1026,
"values": [
10044,
10025,
10029
]
}
]
}
-- CODE language-js --
if (`your site supports login`)
if (`the candidate is logged in`)
if (`the candidate is internal`)
if (`the job is visible internally`)
return the job, with its internal details
else
return "sorry, this job is not available to internal candidates"
else (`public job seeker`)
if (`the job is visible externally`)
return the job, with its external details
else
return "sorry, this job is not visible to external candidates"
else
if (`the job is visible externally`)
return the job, with its external details
else (`if the job is visible internally`)
redirect to self with loggedIn param // they may be internal
the loggedIn filter fires and forces login
else // not visible at all
return "sorry, this job is no longer available"
-- CODE language-json --
[
{
"app": "myapp",
"actions": [
{
"name": "refer",
"uri": "https://referrals.com/jobs/1022?tracker=106645",
"type": "button",
"label": "Refer a friend",
"textColor": "dddddd",
"backgroundColor": "010203",
"disabled": false
},
{
"name": "share",
"uri": "https://sharing.com/jobs/1022?tracker=106645",
"type": "button",
"label": "Share this job",
"textColor": "dddddd",
"backgroundColor": "010203",
"disabled": false
}
]
}
]
Job search UI
Most sites will display a keyword search box and a number of different filters such as location or expertise to allow the user to search for jobs.
To populate a search UI like that, your board can consume the category APIs.
-- CODE language-json --
[
{
"id": 10022,
"name": "Classification",
"jobRules": {
"canMultiSelect": true,
"leafSelectionOnly": false,
"mandatory": true
},
"candidateRules": {
"canMultiSelect": true,
"leafSelectionOnly": false,
"message": "Please choose carefully",
"mandatory": true
}
},
{
"id": 10032,
"key": "LOCATION",
"name": "Location",
"jobRules": {
"canMultiSelect": true,
"leafSelectionOnly": false,
"mandatory": true
},
"candidateRules": {
"canMultiSelect": true,
"leafSelectionOnly": false,
"message": "Please choose carefully",
"mandatory": true
}
},
{
"id": 10034,
"name": "Nursing specialization",
"jobRules": {
"canMultiSelect": true,
"leafSelectionOnly": false,
"mandatory": true
},
"candidateRules": {
"canMultiSelect": true,
"leafSelectionOnly": false,
"message": "Please choose carefully",
"mandatory": true
}
}
]
-- CODE language-json --
[
{
"id": 10034,
"name": "Wellington",
"available": true
},
{
"id": 10032,
"name": "Auckland",
"available": true,
"values": [
{
"id": 10036,
"name": "North Shore",
"available": true,
"values": [
{
"id": 10037,
"name": "Takapuna",
"available": true
}
]
}
]
}
]
Job list/search results pages
To search / fetch lists of jobs, your site consumes one of:
GET /jobs
POST /jobs/searches
-- CODE language-json --
{
"total": 2,
"results": [
{
"id": 10334355,
"status": "active",
"availability": {
"availableInternally": true,
"availableExternally": false,
"applicationCloseDates": {
"closeDate": "2015-11-05T13:15:30Z",
"internalCloseDate": "2015-11-05T13:15:30Z",
"externalCloseDate": "2015-11-05T13:15:30Z"
}
},
"code": "1022NH",
"title": "Creative Director",
"country": "AU",
"shortSummary": "An amazing opportunity",
"categories": [
{
"category": 1022,
"values": [
10024
]
},
{
"category": 1026,
"values": [
10044,
10025,
10029
]
}
]
},
{
"id": 10334356,
"status": "active",
"availability": {
"availableInternally": true,
"availableExternally": false,
"applicationCloseDates": {
"closeDate": "2015-11-05T13:15:30Z",
"internalCloseDate": "2015-11-05T13:15:30Z",
"externalCloseDate": "2015-11-05T13:15:30Z"
}
},
"code": "1024NH",
"title": "Creative Lackey",
"country": "US",
"shortSummary": "An amazing opportunity, unrivalled for enjoyment",
"categories": [
{
"category": 1022,
"values": [
10024
]
},
{
"category": 1026,
"values": [
10044,
10025,
10029
]
}
]
}
]
}
Your site should make sure not to display the wrong jobs to the wrong candidates by restricting for availableInternally or availableExternally depending on whether a candidate is logged in and if so whether they are internal or not. This restriction could be done:
- by passing availableInternally = true to the search
- by fetching all jobs then filtering out based on the value of availableInternally
Obviously for security reasons it must not be done client-side.
Handling trackers
Normally your site should handle trackers as described in Trackers.
This means:
- creating session trackers
- attaching the session tracker to all links your board emits
- passing the session tracker to all tracker-aware APIs that your board consumes
Add
- Keyword spec for search
- Entry with a job code
- Displaying the logged in candidate's name.
- Handling internals - grabbing role from incoming SAML assertion - checking IP address - using login - restricting jobs