How to integrate with ATS (Hire API)

The HireAPI integration is based on events Bob receives from an ATS - usually when the candidate is marked as Hired in the ATS.

The event is an HTTP POST request sent to Bob. Bob will provide an endpoint to the end user (the Bob Admin) in Bob’s UI.

  • The event is authenticated within the headers, according to the mechanism you choose to use; either Token or Service Users.
  • The body of the event is a JSON file containing the data Bob will use to create an applicant in Bob. This applicant will be used during the hiring flow in Bob.

Note: For full details about the end user’s flow, see How a Bob admin sets up a Hire API integration.

How a Hire API integration works

Once the Hire API integration is developed, the following flow occurs:

  1. The ATS triggers an event by issuing POST requests.
  2. Bob stores the event as is, so if anything goes wrong end users will be able to check the payload.
  3. Bob parses the payload, and pulls the attachments if there are any. The parsed payload is an applicant in Bob.
  4. Bob notifies the end-user that there is a new hire from this ATS, as defined by the end user in the notification section in Bob.
  5. The user clicks on the link in the email or the notification in Bob and picks the New hire flow which will be used to create a new employee in Bob.
  6. Mapping is used to prepopulate the new hire's profile with the applicant’s data from the ATS. End users can create and edit the schema of mapping within BobI.

Developing the Hire API integration

In order to develop the Hire API integration you’ll need to develop the payload and then authenticate the API calls made to Bob’s webhook URL by using either a Token or a Service user.

Develop the payload

First, you need to develop the payload. You can use any of the supported fields, document fields plus custom fields, if required.

Supported fields

The following fields are supported.

Note: None of the fields are mandatory, Bob will only parse exact matches of the fields paths. Upon the first hire event, or if any demo hire event is triggered by the user, Bob automatically matches out-of-the-box fields that are sent in the same structure as shown below. The fields are then added to the data-mapping component in the Hire API connections page in Bob.

FieldType
emailtextThe employee email
firstNametextThe employee first name
lastNametextThe employee last name
recruiterEmailsList of textThe list of recruiter emails that will receive the bob new hire notification email
work/titletextThe employee work title
work/departmenttextThe employee work department
work/sitetextThe employee work site
work/reportsTotextThe name or email of the employee manager
work/startDatedateThe employee work start date
financial/employmentContracttextThe employee employment contract
financial/employmentTypetextThe employee employment type
financial/payPeriodtextThe employee pay period
financial/salarynumberThe employee salary
financial/salaryCurrencytextThe employee salary currency
about/privatePhonetextThe employee personal phone
about/mobilePhonetextThe employee personal mobile
about/linkedinProfiletextThe employee LinkedIn profile URL
about/facebookProfiletextThe employee Facebook profile URL
about/twitterProfiletextThe employee Twitter profile URL

Fields for sending documents from the ATS to Bob

For Bob to receive documents from the ATS you will need to include the following fields:

FieldType
documents/nametextThe filename of the employee document
documents/urltextThe URL of the employee document (must be unsecured)

See the below example:

"documents": [  
{  
"name": "CV.pdf",  
"url": "https://www.bellevue.edu/student-support/career-services/pdfs/resume-samples.pdf"  
},  
{  
"name": "cover_letter.pdf",  
"url": "http://skcnedu.in/uploads/files/document43.pdf"  
}  
]

Custom fields

In addition to the default list of fields, Bob can accept custom fields. Each custom field must contain following properties:

  • ID - the unique identifier in your ATS.
  • Display name - will be shown in bob’s UI during mapping.
  • Field type - Text/ Number/ Date/ Currency/ Timestamp/ Boolean/ Multilist/ Table.
  • The value which matches the field type.

See the below field types with sample usage:

Text:

{  
"id": "text_field_1”,  
"displayName": "moto",  
"fieldType": "text",  
"value": "Blue, Yellow and Red"  
}

Number

{  
"id": "number_field_1",  
"displayName": "Favorite Number",  
"fieldType": "number",  
"value": 123.56  
}

Date

date  
{  
"id": "date_field_1",  
"displayName": "Birthday",  
"fieldType": "date",  
"value": "2019-11-15"  
}

Currency

{  
"id": "currency_field_1",  
"displayName": "poker - best win",  
"fieldType": "currency",  
"value": {  
"value": 12.33,  
"currency": "USD"  
}  
} 

Timestamp

{  
"id": "timestamp_field_1",  
"displayName": "Favorite Moment",  
"fieldType": "timestamp",  
"value": "2019-10-15T22:49:14Z"  
}

Boolean

{  
"id": "boolean_field_1",  
"displayName": "Boolean Field",  
"fieldType": "boolean",  
“value": true  
} 

Multilist

 {  
"id": "multi_list_field_1",  
"displayName": "Favorite Sports",  
"fieldType": "multilist",  
"values": [  
"Football",  
"Handball",  
"value3"  
]  
}

Table

 {  
"id": "table_type_list_field_1",  
"displayName": "Table Type Field",  
"fieldType": "tableType",  
"values":  
\[  
[  
{  
"id": "c11",  
"displayName": "C 11",  
"fieldType": "text",  
"value": "1"  
},  
{  
"id": "c12",  
"displayName": "C 12",  
"fieldType": "text",  
"value": "2"  
}  
],  
[  
{  
"id": "c21",  
"displayName": "C 21",  
"fieldType": "text",  
"value": "3"  
},  
{  
"id": "c22",  
"displayName": "C 22",  
"fieldType": "text",  
"value": "4”  
}  
]  
]  
}

Payload examples

The following is a list of examples of different types of payloads.

Basic, with just email, firstName, lastName and recruiteEmails fields

 {  
"email": "[[email protected]](mailto:[email protected])",  
"firstName": "Joe",  
"lastName": "Doe",  
"recruiterEmails": [  
"[email protected]",  
"[email protected]"  
]  
}

Example with work, financial and about categories populated along with documents

 {  
"email": "[[email protected]](mailto:[email protected])",  
"firstName": "Joe",  
"lastName": "Doe",  
"recruiterEmails": [  
"[email protected]",  
"[email protected]"  
],  
"work": {  
"title": "Account Manager",  
"department": "Distribution",  
"site": "Cluj-Napoca",  
"reportsTo": "[[email protected]](mailto:[email protected])",  
"startDate": "2019-10-21"  
},  
"financial": {  
"employmentContract": "Full Time",  
"employmentType": "Permanent",  
"payPeriod": "Annual",  
"salary": 12500.5,  
"salaryCurrency": "USD"  
},  
"about": {  
"privatePhone": "021343536",  
"mobilePhone": "021444555",  
"linkedinProfile": "<http://linkedin.com/in/joe-doe">,  
"facebookProfile": "<http://facebook.com/joedoe2">,  
"twitterProfile": "<http://twitter.com/jd2">  
},  
"documents": [  
{  
"name": "CV.pdf",  
"url": "https://www.bellevue.edu/student-support/career-services/pdfs/resume-samples.pdf"  
},  
{  
"name": "cover_letter.pdf",  
"url": "http://skcnedu.in/uploads/files/document43.pdf"  
}  
]  
}

An example of custom fields

 {  
"email": "[[email protected]](mailto:[email protected])",  
"firstName": "Joe",  
"lastName": "Doe",  
"recruiterEmails": [  
"[email protected]",  
"[email protected]"  
],  
"work": {  
"title": "Account Manager",  
"department": "Distribution",  
"site": "Cluj-Napoca",  
"reportsTo": "[[email protected]](mailto:[email protected])",  
"startDate": "2019-10-21"  
},  
"financial": {  
"employmentContract": "Full Time",  
"employmentType": "Permanent",  
"payPeriod": "Annual",  
"salary": 12500.5,  
"salaryCurrency": "USD"  
},  
"about": {  
"privatePhone": "021343536",  
"mobilePhone": "021444555",  
"linkedinProfile": "<http://linkedin.com/in/joe-doe">,  
"facebookProfile": "<http://facebook.com/joedoe2">,  
"twitterProfile": "<http://twitter.com/jd2">  
},  
"documents": [  
{  
"name": "CV.pdf",  
"url": "https://www.bellevue.edu/student-support/career-services/pdfs/resume-samples.pdf"  
},  
{  
"name": "cover_letter.pdf",  
"url": "http://skcnedu.in/uploads/files/document43.pdf"  
}  
],  
"customFields": [  
{  
"id": "text_field_1",  
"displayName": "moto",  
"fieldType": "text",  
“value": "Blue, Yellow and Red"  
},  
{  
"id": "number_field_1",  
"displayName": "Favorite Number",  
"fieldType": "number",  
"value": 123.56  
}  
]  
}

Authentication

All API calls made to Bob's webhook URL need to be authenticated.

Bob supports two authentication methods which you can use for your integration with Bob:

  • Token
  • Service user.

End users (Bob Admins) will be able to configure the integration based on the method you choose to implement.

Note: For full details about the end user’s flow, see How a Bob admin sets up a Hire API integration.

Token

Bob expects the following http headers to be present in a request:

  • X-Bob-HireAPI-Timestamp - epochValue (utc timestamp) in seconds. It must be no older than 5 minutes from the current time.
  • X-Bob-HireAPI-Signature - HMAC-SHA256 signature of the payload, in order to do it you will need to use epochValue and SecretKey which end users will get in Bob UI during Hire API integration creation

How to compute a signature

The signature is computed as follows:

message = epochValue+requestBody

signature* = HMAC-SHA256(message,SecretKey).

Explanation of the elements within the signature:
  • epochValue: the value received in X-Bob-HireAPI-Timestamp header
  • requestBody: the request body that will be sent to Bob
  • SecretKey: the secret obtained when setting-up the HireAPI integration.

The following is an example of a signature computation

Given

  • epochValue = 1676691263
  • requestBody = {
    “email”: “[email protected]”,
    “firstName: “Joe”,
    “lastName”: “Doe”
    }
  • SecretKey = 4BBE2E0E43D0FC230870E760E11FE19789AA535A
  1. Store epochValue in request header X-Bob-HireAPI-Timestamp
  2. Prepend requestBody with epochValue resulting in following:
    message = 1676691263{ “email”: “[email protected]”, “firstName: “Joe”, “lastName”: “Doe”}
  3. signature* = Calculate HMAC-SHA256 using message from previous step
    HMAC_SHA256(signature, SecretKey)
  4. Store signature in request header X-Bob-HireAPI-Signature

You can use https://codebeautify.org/hmac-generator for debugging signature-related problems.

Note: There must be no character between the epochValue and the requestBody. The above + sign represents concatenation in the above signature.

Service User

Bob expects an Authorization header with service user credentials encoded in base64.

The Service user credentials will be provided to the end users in the Bob UI during the setup of the Hire API integration.

The request should contain a header field in the form of Authorization: Basic, where credentials is the Base64 encoding of ID and token joined by a single colon :

Header computation

ID - SERVICE-202
Token - Qe8q89RwbzeS7mmhMcAsN1crM73m6MdbjewGCCUY

  1. Concatenate id and token with a single colon
    SERVICE-202:Qe8q89RwbzeS7mmhMcAsN1crM73m6MdbjewGCCUY
  2. Base64 encode value from previous step
    base64encode(SERVICE-202:Qe8q89RwbzeS7mmhMcAsN1crM73m6MdbjewGCCUY)
    resulting value is **
    U0VSVklDRS0yMDI6UWU4cTg5UndiemVTN21taE1jQXNOMWNyTTczbTZNZGJqZXdHQ0NVWQ==
  3. The final header that needs to be sent to Bob, not that you need to put Basic in front of encoded value
    Authorization: Basic U0VSVklDRS0yMDI6UWU4cTg5UndiemVTN21taE1jQXNOMWNyTTczbTZNZGJqZXdHQ0NVWQ==

To learn more about service users in Bob, see API service users.