Overview

The Applicant Tracking System (ATS) flow allows external ATS to push new hire information to Bob so newly hired candidates can be imported into Bob as employees .

Integration flow

  1. The Bob integration administrator configures the ATS integration.

  2. A new hire is performed in the ATS.

  3. The ATS performs a callback to Bob to notify the details of the new hire.

  4. Bob processes the new hire information and notifies the recipients of the ATS flow about the new hire.

  5. The adminesponsible for new hires clicks the new hire notification, which opens up the Bob employee New Hire Wizard.
    The New Hire Wizard is already filled in with the information from the new hire callback.

  6. If required, additional information is filled in and the employee is created.

New hire notifications

After a new hire callback event is processed, Bob will send both email and in-app notifications.

The recipients of the notifications can be configured in Settings > Integrations > Recruitment Integration in the Who Should be Notified? section.

Below is a sample email notification for a new hire:

New Hire Wizard

After the user clicks the new hire notification, the New Hire Wizard will open

617ba7a3c00d5

The new employee information received from the new hire callback event will be automatically filled in the new hire form.

617ba7a4a1fb9

 

How to develop a Hire API webhook

Webhook URL & Secret

Before you start, please connect to bob to set up a new HireAPI integration token for the specific bob platform. You can configure the token under Settings --> Integrations --> Hire API. As an example:

617ba7a57968f

Authentication

All API calls made to bob's webhook URL need to be authenticated. For this, we expect a HMAC-SHA256  signature in the X-Bob-HireAPI-Signature  header. More details can be found in the How to compute signature section below.

Replay attack protection

Within the X-Bob-HireAPI-Timestamp  header, each request must contain an epoch value (in seconds) that is no older than 5 minutes from the current time. 

How to compute a signature

Each request made to the webhook endpoint must be authenticated using a HMAC-SHA256  signature. The signature is computed as follows:

message = epochValue + requestBodysignature = HAMC-SHA256(message, SecretKey)

Note: There is no character between the epochValue  and the requestBody . The above +  sign represents concatenation. In the above signature,

  • epochValue  is the value received in X-Bob-HireAPI-Timestamp  header

  • requestBody  is the request body that will be sent to bob

  • SecretKey  is the secret obtained when setting-up the HireAPI integration

See the below example:

617ba7a61d763

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

A request JSON

The payload you send to bob should comply with the following JSON structure:

{ "email": "joe.doe@sample.com", "firstName": "Joe", "lastName": "Doe", "recruiterEmails": [ "recruiter1@sample.com", "recruiter2@sample.com" ], "work": { "title": "Account Manager", "department": "Distribution", "site": "Cluj-Napoca", "reportsTo": "finley.day_39028@samplebob.com", "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 }, { "id": "currency_field_1", "displayName": "poker - best win", "fieldType": "currency", "value": { "value": 12.33, "currency": "USD" } }, { "id": "date_field_1", "displayName": "Birthday", "fieldType": "date", "value": "2019-11-15" }, { "id": "timestamp_field_1", "displayName": "Favorite Moment", "fieldType": "timestamp", "value": "2019-10-15T22:49:14Z" }, { "id": "boolean_field_1", "displayName": "Boolean Field", "fieldType": "boolean", "value": true }, { "id": "multi_list_field_1", "displayName": "Favorite Sports", "fieldType": "multilist", "values": [ "Football", "Handball", "value3" ] }, { "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" } ] ] } ]}

Request Fields

617ba7a6daca0

Note: None of the JSON fields are mandatory, so it’s up to the integration developer to decide which information to send into bob. For best results, we recommend providing values for as many fields as you can.

Custom Fields

Custom fields are fields that are not known at development time. There are two benefits to adding custom fields:

  • If a custom field has the same exact display name as an existing bob field, the two fields will be mapped automatically and the value will be populated in the bob new hire wizard.

  • Through manual mapping, these custom fields can be mapped to the desired bob field. Please contact bob support if manual mapping is required.

Field types

617ba7a7aaee7

Webhook status codes

Successful request

If a request is successful, then the bob webhook will reply with a status code of 200.

Error in request

If there is an error, Bob will return an appropriate error response such as:

{ "message": "The requested resource could not be found!", "error": "The requested resource could not be found!"}

One of the following status codes will also be returned:

  • 400 - if the request is missing any of the required headers. Solution: provide the X-Bob-HireAPI-Signature  and X-Bob-HireAPI-Timestamp  headers
  • 401 - if the difference between the current time and supplied epoch value is greater than 5 minutes, or if the signature provided doesn’t match the computed one. Solution: provide correct values for epoch and signature
  • 404 - if the token parameter value from the webhook URL can’t be found in bob. Solution: make sure the webhook URL is correct

Example

Please find below an example of a valid request made using cURL:

curl -X POST \ 'https://app.hibob.com/api/provisioning/api/integrations/ats/hire?token=70512D2AFAB9C0F4A46111459847269E28E1FEE0' \ -H 'Content-Length: 3654' \ -H 'Content-Type: application/json' \ -H 'X-Bob-HireAPI-Signature: 3ab5b0fedbc7cd18ce20d0d3408cc1f2582ec0df264da5bcf63bba36d3ee88fe' \ -H 'X-Bob-HireAPI-Timestamp: 1576763272' \ -d '{ "email": "joe.doe@sample.com", "firstName": "Joe", "lastName": "Doe", "recruiterEmails": [ "recruiter1@sample.com", "recruiter2@sample.com" ], "work": { "title": "Account Manager", "department": "Distribution", "site": "Cluj-Napoca", "reportsTo": "finley.day_39028@samplebob.com", "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 }, { "id": "currency_field_1", "displayName": "poker - best win", "fieldType": "currency", "value": { "value": 12.33, "currency": "USD" } }, { "id": "date_field_1", "displayName": "Birthday", "fieldType": "date", "value": "2019-11-15" }, { "id": "timestamp_field_1", "displayName": "Favorite Moment", "fieldType": "timestamp", "value": "2019-10-15T22:49:14Z" }, { "id": "boolean_field_1", "displayName": "Boolean Field", "fieldType": "boolean", "value": true }, { "id": "multi_list_field_1", "displayName": "Favorite Sports", "fieldType": "multilist", "values": [ "Football", "Handball", "value3" ] }, { "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" } ] ] } ]}'