Integrate with ATS (Hire API)

How to develop an integration with Applicant Tracking Systems (ATS) and push new hires into Bob seamlessly

Bob's Hire API simplifies the people onboarding process by seamlessly integrating an Applicant Tracking System (ATS) with Bob, effortlessly adding new hires as employees in Bob. This integration eliminates the need for manual export of hired candidates from ATS systems, as they are automatically created as employees in Bob.

Bob’s Hire API workflow:

ATS
Candidate becomes a hire
Send an HTTP POST request to Bob with the candidate details
Bob
Hire API extracts the details from the payload and creates a new hire notification
Notifies subscribed users about the new hire
User click the notification and start a new hire flow in Bob and creates the employee

The following sections detail how to implement the integration on the ATS side and are aimed at ATS developers who want to integrate with Bob and push new candidates as Hires in Bob.

Note: This is the developer’s guide for implementing a new Hire API integration for an ATS. If you want to set up an existing integration, refer to How to set up Hire API integration in Bob ↗.

Endpoint URL and Authorization Header

The Bob Hire API endpoint URL and authentication details are dynamically generated when the user installs the integration in Bob.

During installation, the user selects an authentication method. Based on the chosen method, the endpoint URL and authentication details are generated on-the-fly. The Hire API has a base URL, and the authentication method is appended to this URL as a service user ID or a token id. These details are essential for securely accessing and interacting with the Bob Hire API, allowing users to send and receive data as part of the integration process.

To learn more, see Endpoint URL and Authorization header.

First, let's go into the steps.

Implementing the Integration

Implementing the integration consists of the following development steps:

  • Step 1: Setup.
    In order to integrate with Bob's Hire API, you need to call the endpoint when you have a new Hire in the ATS. When developing the integration setup on the ATS side, you should obtain the endpoint's URL and authentication details which are dynamically generated in Bob.
  • Step 2: Prepare payload.
    Develop the code that creates the new candidate’s payload.
  • Step 3: Call the Hire API.
    Develop the code that calls the Hire API endpoint with the candidate’s details when there is a new hire in the ATS.
  • Step 4: Provide field mapping instructions.
    If you pass custom fields in your payload, you need to instruct the end-user to manually map these fields after the first time they pass a new hire through the integration.
  • Step 5: Error handling.
    Test the integration and handle errors.

Step 1: Setup

In this step you should develop a user interface to obtain the endpoint URL and the authentication details from Bob during the integration setup.

The following details are required in order to call the Hire API integration:

  • Endpoint URL: The Bob Hire API endpoint URL is generated when the user activates the integration in Bob.You should provide the user a way to copy and paste it into your ATS integration configuration, so you can use it in the HTTP POST requests. To learn more, see Endpoint URL.
  • Authentication details: The authentication details (service user ID or Token ID) are generated when the user activates the integration in Bob. You should provide the user a way to copy and paste the authentication details into your ATS integration configuration. To learn more, see Authorization header.

Step 2: Prepare payload

In this step, you should prepare the payload that you will send to the POST request. The payload will contain the candidate’s details.

As best practice, we advise using the default fields that Bob supports in the default Hire API field mapping. Matching your field names with Bob’s defaults ensures that candidate details are automatically populated into the correct fields within Bob.

📘

Notes:

Payload format

The payload with the candidate details in the request body should be a JSON file.

Ensure that the payload includes all relevant information about the candidate. There are no mandatory fields.

The payload can include any of the following fields:

  • Employee fields that are mapped automatically by Bob. Ensure you send the correct field IDs in the payload, as listed in the Candidate fields.
  • Document fields (for attachments). To learn how to send documents, see Document fields.
  • Custom Fields. To send additional fields, you need to instruct the end-user to manually map these fields after the first time they pass a new hire through the integration. To learn more about sending custom fields, see Mapping custom fields.

Payload example

An example of a candidate’s name with an attachment of a CV file:

{  
"email": "[email protected]",  
"firstName": "Joe",  
"lastName": "Doe",  
"documents": [
{  
 "name": "CV.pdf",  
 "url": "https://www.bellevue.edu/student-support/career-services/pdfs/resume-samples.pdf"  
},
{  
 "name": "cover_letter.pdf",  
 "url": "https://www.shu.edu/documents/Cover-Letter-Samples.pdf"  
 }  
]  
}

For more examples, see Payload Examples.

Step 3: Call the Hire API

In this step you should develop the code that actually calls the Hire API endpoint and sends the payload with the candidate details.

Calling the Hire API can be done in two ways:

  • Automatically (Using a Webhook): Create a webhook event in the ATS which sends the POST request to the Hire API endpoint whenever a new candidate is hired.
  • Manually using a user action in the UI: Provide the user a way to manually push the new candidate from the ATS into Bob using a button, and call the Hire API.

Endpoint URL

The Bob Hire API endpoint URL is dynamically generated when the user installs the integration in Bob.

Note: The Hire API endpoint is a unique endpoint which is not included in Bob's Public API reference guide. The endpoint's URL and parameters are explained only in this guide.

This is the automatically generated endpoint URL to which you should send your HTTPS POST request with the new candidate details.

The base URL for the API endpoint is:

https://app.hibob.com/api/integrations/ats/hire

To this base URL, Bob appends the details as follows:

  • Service user authentication:
    https://app.hibob.com/api/integrations/ats/hire/<integration id>
    The integration id is generated automatically when setting up the service user for this integration.
  • Token authentication:
    https://app.hibob.com/api/integrations/ats/hire?token=<token id>
    The token id is generated automatically when setting up the token id for this integration.
    In addition, Bob generates a secret key that should be used in the Authorization header.

Authorization header

Each time you call the Hire API with an HTTP POST request, it must include the HTTP Authorization header with the API authentication details.

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

  • Service user
    When your authentication method is based on a service user, you need to include the service user credentials encoded in base64 in the request's authorization header. In order to create the authorization header, you will need to obtain the service user id and token from Bob when setting up the integration.
    To learn more about using service users to access the Bob API, see API Service users.
  • Token
    When your authentication method is based on a token, use the secret key generated by Bob in the integration setup stage, to generate a signature for your request's authorization header. This involves creating a hash or encoded signature that validates your request's authenticity.
    To learn more about using the token to access the Hire API, see How to use the Token in the authentication header.

How to use the Token in the authentication header

When your authentication method is based on a token, you need to sign your request using a secret key and include the calculated signature in the request header.

Token based authentication requires you to include the following HTTP headers in a request:

  • X-Bob-HireAPI-Timestamp - epochValue (utc timestamp) in seconds. It must be at most 5 minutes from the current time.
  • X-Bob-HireAPI-Signature - HMAC-SHA256 signature of the payload. To create the signature you will need to use the epochValue, and the Secret Key obtained from HiBob.

How to compute a signature

The signature is computed as follows:
message = epochValue+requestBody
signature\* = HMAC-SHA256(message,SecretKey)

Where:

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

Example:

  • epochValue = 1676691263
  • requestBody = { “email”: “[email protected]”, “firstName: “Joe”, “lastName”: “Doe” }
  • SecretKey = 4BBE2E0E43D0FC230870E760E11FE19789AA535A

How to compute:

  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”}


signature* = Calculate HMAC-SHA256 using message from previous step
HMAC_SHA256(signature, SecretKey)

  1. Store signature in request header X-Bob-HireAPI-Signature

Notes:

  • You can use https://codebeautify.org/hmac-generator for debugging signature-related problems.
  • There must be no character between the epochValue and the requestBody. The above + sign represents concatenation in the above signature.

Using the URL as a Webhook

Webhooks are a powerful tool for enabling real-time communication and event-driven interactions between systems.

When using the Hire API endpoint, you'll send an HTTPS POST request to Bob's endpoint, including candidate details.

When developing the integration on the ATS side, you may consider implementing it using a webhook event in your ATS system, which means you will call the Hire API as a webhook endpoint, whenever a new hire event occurs in your system.

HTTP POST request example

POST /api/integrations/ats/hire/<service user/token> HTTP/1.1
Host: app.hibob.com
Content-Type: application/json
Authorization: ••••••
Content-Length: 162

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

Step 4: Provide field mapping instructions

If you pass custom fields in your payload, you need to instruct the end-user to manually map these fields after the first time they pass a new hire through the integration. Custom fields are not part of the default data mapping of the Hire API.

As part of your setup instructions, instruct users to follow Bob’s Hire API setup instructions for manually mapping the fields after receiving a new hire in Bob for the first time. This ensures that the custom fields will be recognized and properly mapped within Bob.

Your instructions should include details of the fields that should be mapped to the equivalent fields in Bob.

To learn more, see Custom fields.

Step 5: Error Handling

Your implementation should deal with scenarios where things don't work as expected:

  1. deal with a scenario where the endpoint URL is unreachable or returns errors.
  2. Implement retry mechanisms for failed deliveries to ensure the reliability and resilience of the integration.
  3. When anything goes wrong, instruct end-users to check the payload in Bob's UI. Bob stores the payload that is received as-is, so users can track the events that were received.

Hire API field mapping

The Hire API field mapping includes the following steps:

  1. Rely on default field mapping When you begin using the Hire API, Bob automatically maps standard fields by matching out-of-the-box field names in the payload with the fields in Bob. This default field mapping ensures that core candidate information is transferred accurately, as long as the field names are exact matches.
  2. Enable custom field mapping
    If your payload contains additional fields that don’t align with Bob’s default mappings, you’ll need to set up custom mappings. Once the first Hire event is triggered, manual field mapping becomes available in Bob, allowing you to modify mappings for any fields that aren’t included in the standard setup.
  3. Customize mapping with the data-mapping component
    Using the data-mapping component in the Hire API connections page, you can instruct users how to fine-tune the mapping process by linking unique fields in your payload with their corresponding fields in Bob. This customization helps ensure that all relevant details, even those unique to your organization, are accurately captured and synchronized in Bob.

See Payload examples to learn how to structure your payload.

📘

Notes:

  • None of the fields are mandatory.
  • Manual field mapping will be enabled once the first Hire event is triggered.
  • If the payload includes fields that are not mapped with Bob’s default field mapping, you will need to tell the user to use the custom field mapping when setting up the integration.

Candidate's fields (default mapping)

The fields listed below will be automatically mapped when sending them in the new candidate’s details payload.

📘

Notes:

  • Field mapping occurs automatically only the first time you send the payload. If you add new fields after this initial setup, they must be manually mapped, even if they are part of the default mapping.
  • For fields with a "path" structure (e.g., "work/title"), ensure they are formatted as objects in the payload. For example, use:
    "work": { "title": "Designer" }
  • The final payload received into Bob is processed by the system to adjust to the way Bob keeps the data. To learn more, see Synced payload.
Field nameTypeBob fieldDescription
emailtextEmailThe employee email
firstNametextFirst nameThe employee first name
lastNametextLast nameThe employee last name
recruiterEmailsList of text-The list of recruiter emails that will receive the bob new hire notification email
work/titletextJob titleThe employee work title
work/departmenttextDepartmentThe employee work department
work/sitetextSiteThe employee work site
work/reportsTotextReports toThe work email of the employee's manager
work/startDatedateStart dateThe employee work start date
financial/employmentContracttextEmployment contractThe employee employment contract
financial/employmentTypetextEmployment typeThe employee employment type
financial/payPeriodtextPay periodThe employee pay period
financial/salarynumberBase salaryThe employee salary
financial/salaryCurrencytextBase salaryThe employee salary currency
about/privatePhonetextPersonal phoneThe employee personal phone
about/mobilePhonetextWork mobileThe employee personal mobile
about/linkedinProfiletextSocial - LinkedInThe employee LinkedIn profile URL
about/facebookProfiletextSocial - FacebookThe employee Facebook profile URL
about/twitterProfiletextSocial - TwitterThe employee Twitter profile UR
about/avatarUrltext-Url to retrieve avatar image

Synced payload

The payload that you will see when viewing synced records in Bob's UI ↗ are actually already processed by the system to adjust to the data structure in Bob.

For example, when you send the 'financial' fields in the payload, these fields are imported into Bob as separate objects: 'salary' and 'payroll'. The final payload will look different than the fields you send in the default mapping in the following cases:

Applicant fields:

Fields: email, firstName, lastName, work/ (all work fields are part of the applicant)

 "applicant": {  
    "atsSystem": "custom_ats_xxxxxx",  // added by the System
    "email": "[email protected]",  
    "firstName": "Joe",  
    "surname": "Doe",  
    "work": {  
      "title": "Account Manager" 
    }
  • Financial fields:
Fields: financial/employmentContract, financial/employmentType

"payroll": {
  "employment": {
    "contract": "Full Time",
    "employmentType": "Permanent"
  },
Fields:financial/salary, financial/salaryCurrency

"salary": {
    "payPeriod": "Annual",
    "payment": { // mapped to the 'Base salary' in Bob
      "value": 12500.5,
      "currency": "USD"
    }
  • About fields:
Fields:about/linkedinProfile, about/facebookProfile, about/twitterProfile

"about": {
  "socialData": {
    "linkedin": "http://linkedin.com/in/joe-doe",
    "facebook": "http://facebook.com/joedoe2",
    "twitter": "http://twitter.com/jd2"
  }
Fields:about/privatePhone, about/mobilePhone

"home": {
  "privatePhone": "021343536",
  "mobilePhone": "021444555"
},

Documents fields

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

FieldTypeDescription
documents/nametextThe name for the document that will be attached to the employee in Bob.
Be sure to include the correct file extension, as the system uses it to process and attach the document.
documents/urltextThe URL of the employee document (must be unsecured)

Note: Documents that are attached to the request are automatically pulled from the ATS and saved in the employee's Docs > Confidential docs folder in Bob.

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 out-of-the-box fields included in the Hire API, Bob can accept additional custom fields. Custom fields must include a unique identifier in the ATS to ensure proper integration and field mapping.

Custom fields should be mapped manually in Bob’s system after the initial setup and the first time a new hire is passed through the integration. Ensure that the custom fields are mapped accurately during the integration setup to prevent any data mismatches or integration errors

Each custom field in the payload must contain the following properties:

  • ID: A unique identifier of the field in the ATS. Ensure this field has a unique ID to maintain data integrity.
  • Display Name: The name that will be shown in Bob’s UI during field mapping
  • Field Type: The type of the field, which can be one of the following: Text, Number, Date, Currency, Timestamp, Boolean, Multilist, Table
  • Field Value: The value that matches the field type.

Custom field examples

See the following examples of custom fields that can be included in your request:

Text:

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

Number

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

Date

"customFields": [    
{  
	"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

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

Multilist

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

Table

"customFields": [  
{  
"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”  
}  
]  
]  
}
]

Linking with fields in Bob (e.g. position id)

"customFields": [  
{
  "id": "number_field_3",  
	"displayName": "Position ATS",  
	"fieldType": "text",  
	"value": "P-1678797" 
}  
]

Payload examples

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

Basic, with just email, firstName and lastName fields

 {  
"email": "[email protected]",  
"firstName": "Joe",  
"lastName": "Doe",  
}

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

 {  
"email": "[email protected]",  
"firstName": "Joe",  
"lastName": "Doe",  
"recruiterEmails": [  
	"[email protected]",  
	"[email protected]"  
],  
"work": {  
	"title": "Account Manager",  
	"department": "Distribution",  
	"site": "Cluj-Napoca",  
	"reportsTo": "[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]",  
	"firstName": "Joe",  
	"lastName": "Doe",  
	"recruiterEmails": [  
	"[email protected]",  
	"[email protected]"  
],  
"work": {  
	"title": "Account Manager",  
	"department": "Distribution",  
	"site": "Cluj-Napoca",  
	"reportsTo": "[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  
}  
]  
}