Building a job board app with Job Board Hub

This article describes how to build a Job Board app that will integrate with the Job Board Hub in Talent App Store.

Job Board Hub is a central Job Advertisement creating app that allows customers to choose Job Boards that they have installed in Talent App Store and post, update or expire advertisements without having to navigate to all the different apps individually.

APIs

Producing

Below are the APIs that need to be produced by the Job Board app.

Method
API
SoT (Source of Truth)
POST
/tenant
No
GET
/appStatus
No
GET
/jobBoards/forApp
No
POST
/advertisements/byApp
No
GET
/advertisements/byID/{advertisementId}/byApp
No
PATCH
/advertisements/byID/{advertisementId}/byApp
No
POST
/advertisements/status/byApp
No

API flow to/from your app

API flow explaining the different calls between Job Board Hub, Talent App Store and your job posting app

Implementing the APIs

Before building a Job Board App, take a look over the App Install and Setup recipe and familiarise yourself with that. Once you are confident in building a basic TAS app that can be installed and show a necessary settings screens, it is time to move on.

A Job Board App does not need to consume any TAS Tenant APIs only produce them. To see more details about the APIs that need to be produced, see below in the "Produce APIs" section.

Once you have the basic App setup on Talent App Store, you will need to start implementing the APIs for the Job Board Hub to consume. The first thing the Job Board Hub does when your Job Board App is installed is call the /jobBoards/forApp API and create a record for your Job Board App where recruiters will be able to select your Job Board as one of the platforms to post their new Advertisement.

The Job Board Hub will produce the application url. The final URL will include the legacy source code and a tracker.

TAS APIs your app must expose

These are APIs that your app exposes for other apps to consume them.

Check that the value of the `tazzy-secret` header on all API calls matches the HMAC secret for your app.

The first API call incoming to your app is to tell you that a tenant has installed it.

Typically you might handle this API call by inserting into your customer table, sending an email to customer support team, etc. You might show the "setup required" icon and a settings page to facilitate this.

See installing and controlling setup and launch pages for more.

When apps are installed by a Tenant there are times where additional information is needed to get the app up and running properly for that tenant.

If this is required by the Job Board App, it will need to produce /appStatus.

This is an example response when TAS calls this API.

Response

-- CODE language-json --
{
   "landingPage": "https://example.url",
   "settingsPage": "https://settingsExample.url",
   "setupRequired": true,
   "domainsUsed": [
       "https://domain1.example",
       "https://domain2.example"
   ]
}

Returning information about your Job Board

See the Job Boards schema for a detailed description of the properties you need to populate when producing this API.

Immediately after your app is installed, the Job Board Hub, a separate app, consumes GET /jobBoards/forApp on your app to fetch information about your app and stores in the Job Board Hub database.

At present, Job Board Hub is incompatible with some ad blockers. If you get an error stating "Can't get data" when visiting the list of job ads posted on Job Board Hub, and you have an ad blocker plugin installed on your browser, try adding an exception to your ad blocker for the current URL.

When you refresh the page on the Developer ATS Jobs page, you will now see your app available to be selected as a Job Board to post a new advertisement to.

The Job Board Hub will ask the Job Board App for the rules that need to be applied when building and presenting the new Advertisement screen.

The API called is /jobBoards/forApp.

Response

-- CODE language-json --
{
   "label": "Super Job Board",
   "logo": "https://talentappstore.com/logo.png",
   "domain": "https://superjobboard.example",
   "defaultAdvertisementDuration": 30,
   "defaultLegacySourceCode": "SJB",
   "defaultSetupErrorMessage": "Missing required information",
   "applicationURLRules": {
       "type": "string",
       "minLength": 10,
       "maxLength": 200,
       "mandatory": true,
       "pattern": "regex"
   },
   "titleRules": {
       ...
   },
   "referenceCodeRules": {
       ...
   },
   "shortSummaryRules": {
       ...
   },
   "descriptionRules": {
       ...
   },
   "recruiterNameRules": {
       ...
   },
   "recruiterEmailRules": {
       ...
   },
   "advertisementRules": [
       {
           "title": "Section header 1",
           "instructions": "Some meaningful instructions",
           "advertisementFields": [
               {
                   "name": "question1",
                   "title": "Question 1",
                   "instructions": "Some text",
                   "format": "singleLine",
                   "minLength": 10,
                   "maxLength": 200,
                   "defaultValue": "Testing",
                   "mandatory": true,
                   "pattern": "some regex"
               },
               {
                   ...
               }
           ]
       }
   ]
}

If your app needs to be setup

If you have some required settings before the recruiter can use your app, populate the defaultSetupErrorMessage field with some useful message for the recruiter to understand. For example, "You need to finishing adding your credentials into the Super Job Board app in Talent App Store".

New advertisement posting

When a recruiter has selected your Job Board App in the Job Board Hub, the Job Board Hub will consume the API GET /jobBoards/forApp from your app and fetch the information that your app requires when creating a new Advertisement on your platform.

When building your Item Metas note that the Job Board Hub only supports the following:

  • StringMeta
  • NumberMeta
  • BooleanMeta
  • DateMeta
  • PicklistMeta
  • CascadeMeta

There are also some general fields that all Job Boards have access to. You may choose to ignore these fields if they are not relevant to your Job Board. If you have specific requirements on these, for example the title cannot be longer than 50 characters you can specify this. Take a look at StringValidationMeta schema.

Once the recruiter has completed the new advertisement through the Job Board Hub and hits submit, the Job Board Hub will POST to your app an AdvertisementWrite that will contain all the information from the General fields and the information from the fields that your app required to create a new Advertisement.

Your app will need to process this information real time, whether the data is stored in your app and processed shortly after or processed instantly as the Job Board Hub expects a response from your app to indicate if the AdvertisementWrite is valid or there are some errors that the recruiter needs to go back and fix.

If the AdvertisementWrite has some issue with it when the new Advertisement request comes in, it is important to make your error messages as friendly and readable as possible to non tech savvy users. For instance, if the user has put an invalid URL into a field, you will need to return a message that clearly indicates that the issue was and how they can resolve it, the returned result for error messages is an array of errors and you can also indicate what field it is for.

Make sure your error message provides enough information

Thumbs up icon
"The URL you have entered into the Terms and Conditions needs to follow the following format: www.talentappstore.com"
Thumbs down icon
"URL Field for Terms and Conditions is invalid"

When a recruiter has submitted their new advertisement through the Job Board hub, the Job Board Hub will call the selected Job Boards calling the /advertisements/byApp API.

The request will look similar to the example.

Request

-- CODE language-json --
{
   "applicationURL": "https://aotal.com",
   "title": "test title",
   "referenceCode": "C1234",
   "shortSummary": "My short Summary",
   "description": "My description",
   "recruiterName": "Joe Smith",
   "recruiterEmail": "joe.smith@example.com",
   "advertisementFields": [
       {
           "name": "birthdate",
           "type": "date",
           "value": "2015-11-05T13:15:30Z"
       },
       {
           "name": "keenworkerflag",
           "type": "boolean",
           "value": true
       }
   ]
}

When the Job Board App has completed processing the information, the app will return the following example if it was successful.

Response

-- CODE language-json --
{
   "advertisementId": "1234567",
   "status":  "open",
   "applicationURL": "https://aotal.com",
   "title": "test job",
   "referenceCode": "C1234",
   "shortSummary": "This is the short summary",
   "description": "Description is here!",
   "recruiterName": "Joe Smith",
   "recruiterEmail": "joe.smith@example.com",
   "advertisementFields": [
       {
           "meta": {
               ...
           },
           "item": {
               ...
           }
       },
       {
           "meta": {
               ...
           },
           "item": {
               ...
           }
       }
   ]
}

If, for some reason, the information coming into the Job Board App has some information missing or it failed for some reason, the Job Board App will need to return something like the following example.

When that is returned, the Job Board Hub will show the message to the user to let them know they may need to change something or to try sending it again.

Response

-- CODE language-json --
{
   "messages": [
       {
           "message": "Human readable message here",
           "name": "field the message it regarding"
       },
       {
           ...
       }
   ],
   "type": "Bad Request",
   "code": 400,
   "traceId": "123-432-123-145"
}

When editing an advertisement in the Job Board Hub, the Job Board Hub will ask the Job Board Apps for the advertisement information each of the specific Job Boards. Your app will need to produce an AdvertisementRead that contains all the information from the last time the Advertisement was updated. From this AdvertisementRead the fields will be pre-populated with the information from the existing Advertisement and allows the recruiter to easily make minor tweaks if required or change information as required.

It is up to your app whether it is stored in the Job Board App or fetched on demand from your Job Board.

The Job Board Hub does not store the advertisement data for each of the Job Board Apps, it instead calls the Job Board Apps for the advertisement information real time to display to the recruiter when they are editing an advertisement.

The Job Board App needs to produce the /advertisements/byId/{advertisementId}/byApp API and return the advertisement data. Below is an example of the response the Job Board App should return.

Response

-- CODE language-json --
{
   "advertisementId": "1234567",
   "status": "open",
   "applicationURL": "https://aotal.com",
   "title": "test job",
   "referenceCode": "C1234",
   "shortSummary": "This is the short summary",
   "description": "Description is here!",
   "recruiterName": "Joe Smith",
   "recruiterEmail": "joe.smith@example.com",
   "advertisementFields": [
       {
           "meta": {
               ...
           },
           "item": {
               ...
           }
       },
       {
           "meta": {
               ...
           },
           "item": {
               ...
           }
       }
   ]
}

The Job Board Hub updates and expires advertisements on the Job Boards consuming this API.

At times, the recruiter may miss some information or the job listing has been updated and needs to be updated within the Job Boards. This will prompt the recruiter to go an update the listing through the Job Board Hub. The information, in most cases, will be the same with a few minor adjustments.

The patch that is sent through to your Job Board App will include an action field with the value update. This field indicates that the Advertisement needs to be updated and your app will need to apply any changes on demand similar to that of the new Advertisement request and return any errors to the recruiter in an easy to read and understand format.

If the action field has the value expire, you can ignore all other fields on the AdvertisementWrite and expire / archive the advertisement from your Job Board.

From time to time, the user may need to update the advertisement posting on Job Boards to reflect any changes made from the Applicant Tracking System (ATS).

To do this, the Job Board Hub will send through an API call to /advertisement/byID/{advertisementId}/byApp where the Job Board App will need to process the request and update the relevant advertisement with the new details.

Request

-- CODE language-json --
{
   "action": "update",
   "applicationURL": "https://aotal.com",
   "title": "test title",
   "referenceCode": "C1234",
   "shortSummary": "My short Summary",
   "description": "My description",
   "recruiterName": "Joe Smith",
   "recruiterEmail": "joe.smith@example.com",
   "advertisementFields": [
       {
           "name": "birthdate",
           "type": "date",
           "value": "2015-11-05T13:15:30Z"
       },
       {
           "name": "keenworkerflag",
           "type": "boolean",
           "value": true
       }
   ]
}

Response

-- CODE language-json --
{
   "advertisementId": "1234567",
   "status": [
       "Open"
   ],
   "applicationURL": "https://aotal.com",
   "title": "test job",
   "referenceCode": "C1234",
   "shortSummary": "This is the short summary",
   "description": "Description is here!",
   "recruiterName": "Joe Smith",
   "recruiterEmail": "joe.smith@example.com",
   "advertisementFields": [
       {
           "meta": {
               ...
           },
           "item": {
               ...
           }
       },
       {
           "meta": {
               ...
           },
           "item": {
               ...
           }
       }
   ]
}

Similar to the new advertisement API, if there is an error, the Job Board App will need return an error response similar to the one below:

Response

-- CODE language-json --
{
   "messages": [
       {
           "message": "Human readable message here",
           "name": "field the message it regarding"
       },
       {
           ...
       }
   ],
   "type": "Bad Request",
   "code": 400,
   "traceId": "123-432-123-145"
}

Different Job Boards have different time lengths an Advertisement can be advertised. The ATS may have the Job Listing open longer on their end. The other scenario is that the recruiter will go into the Job Board directly and expire the advertisement. This API allows the Job Board Hub to ask your Job Board App if the advertisement is still open.

The Job Board Hub will poll your app periodically and send through an array of advertisement Ids and expects a response that contains an array of objects with the following data:

Frequently the Job Board Hub will poll all Job Board Apps to check that advertisements in the Job Board Hub that are still marked as "active" have not been expired from the Job Board.

When the Job Board Hub is requesting the status of advertisements, the Job Board Hub will send through a request which contains an array of the advertisement ids it is looking for.

Request

-- CODE language-json --
[
   {
       "id": "123-4324-23423"
   }
]

Status can be either open or expired.

Polling will happen every 30 minutes at *:00 and *:30.

Once the advertisement has expired, ideally the advertisement listing information will still be available for a period of time to allow the recruiter to repost the advertisement if required through the Job Board Hub. In this instance, the Job Board Hub will calling the GET /advertisements/byID/{advertisementId}/byApp API to fetching the information for the advertisement

Response

-- CODE language-json --
[
   {
       "advertisementId": "123-4324-23423",
       "status": "expired",
       "title": "Advert title",
       "referenceCode": "1234"
   }
]