Streamlining Employee Onboarding: Integrating ServiceNow with Greenhouse Recruiting
Integrating ServiceNow with Greenhouse streamlined tracking new hires, replacing error-prone spreadsheets. By leveraging the API, we eliminated duplicate entries, automated onboarding tasks, and delivered detailed reports, empowering teams to focus on welcoming new employees efficiently.
In today’s competitive job market, delivering a seamless onboarding experience is a crucial factor for employee retention and satisfaction. As a ServiceNow partner and implementation specialist, we recently tackled the challenge of integrating the onboarding process from Greenhouse, a leading recruiting platform with ServiceNow. The goal? To ensure that internal teams have a streamlined way to track new hires and manage their onboarding process effectively.
Starting Simple: An Email-Based Integration
When we first approached this project, we opted for a quick-win solution: using Greenhouse’s email notifications as the ingestion point for onboarding data. Every time a candidate accepted an offer, Greenhouse sent an email containing basic information about the candidate and their job. Our integration parsed these emails and used the extracted data to trigger onboarding workflows in ServiceNow.
While this approach helped us go live quickly, it wasn’t without its challenges:
- Email Format Variability: Greenhouse’s email templates occasionally changed, causing our parsing logic to fail.
- Limited Data Access: The emails didn’t include all the necessary details, such as job-specific onboarding requirements or candidate preferences, which meant that manual intervention was still required.
- Duplicate Issues: Multiple emails for the same candidate would often trigger duplicate new hire entries, leading to confusion and errors in the onboarding process.
- Not a Real Integration: This approach relies on infrastructure outside of the ServiceNow instance, since it's waiting for an email to be sent and then received. It also relies on asynchronous event handling in ServiceNow, which could be overloaded for other reasons.
- Data-enforcement: Since an email is just a big text field, no data can be enforced (or rejected).
Ultimately, we realized that email-based integration was not a sustainable or scalable solution. We needed a more robust approach that leveraged Greenhouse’s API.
Building a Robust API-Based Integration
To create a seamless integration, we transitioned to Greenhouse’s API. This allowed us to query detailed and consistent data directly from Greenhouse and eliminate reliance on email.
API Overview
Greenhouse's API is well documented here: https://developer.greenhouse.io/harvest.html#introduction
The integration requires an API Token, and authorizes via basic auth using the API token as the username with a blank password. The Greenhouse Dev Center also allows you to specify which endpoints are accessible for which API token. Best practices are to only allow access to the endpoints that are needed.
Querying the Offers Endpoint
Since the process begins once an offer is accepted, the integration begins by querying the GET /offers
endpoint periodically from Greenhouse’s API. This endpoint provides information about:
- Candidate ID
- Job ID
- Offer details, including the accepted status and start date
While the Offers API gives us a good starting point, the data it returns is incomplete for our onboarding purposes. For example, the offer information might include the candidate’s ID and job ID, but not their name, email, or job title—critical details for provisioning accounts, equipment, and training.
Supplementing Data with Additional Endpoints
To fill in the gaps, our integration makes additional calls to:
- Candidate Endpoint (
GET /candidates/{id}
):
- Retrieves the candidate’s full name and email
- Job Endpoint (
GET /jobs/{id}
):
- Provides job title, department, location, and other custom fields relevant to our onboarding workflows
By combining data from these three endpoints, we create a comprehensive onboarding profile for each new hire. This profile includes everything ServiceNow needs to automate onboarding tasks, from creating IT tickets for laptop provisioning to scheduling orientation sessions.
Data Source Details
Our Data Source loads the data by script, since we have to make these three calls to efficiently map and transform all of this data at once.
Our data source only look at Offers that are
- Status = Accepted (see screenshot above)
- Updated after last 14 days + 2 hours
- Starting After today
This also means that our Scheduled Import Set should run at an interval less that 14 days, to ensure we don't miss any accepted offers.
As detailed above, we can get all Offer details with one call, and get all Candidate details with only one call, but unfortunately, the Jobs endpoint doesn't allow for bulk queries. This means that if we have n new offers, we have to make n+ 2 REST Message calls.
(function loadData(import_set_table, data_source, import_log, last_success_import_time) {
var gdt = new GlideDateTime();
var startsAfter = gdt.getDate();
gdt.addDaysLocalTime(-14);
gdt.addSeconds(-2 * 60 * 60);
var updated_after = gdt.toString().replace(" ", "T") + ".000Z";
var message = new sn_ws.RESTMessageV2('Greenhouse', 'offers-recent');
message.setStringParameter("starts_after", startsAfter);
message.setStringParameter("updated_after", updated_after);
var arr = []
var resultStream = global.ukg_streamData(message);
var offerStream = resultStream.map(function(x) {
return {
"candidate_id": x["candidate_id"].toString(),
"starts_at": x["starts_at"],
"opening_id": x["opening"]["opening_id"],
"job_id": x["job_id"].toString()
}
}).chunk(50).flatMap(function(offers) {
var offersMap = offers.reduce(function(map, item) {
map[item.candidate_id] = item;
return map;
}, {});
var candidateIDs = Object.keys(offersMap);
var jobIDs = offers.map(function(x) {
return x.job_id;
})
offers.forEach(function(x){
var message = new sn_ws.RESTMessageV2('Greenhouse', 'job');
message.setStringParameter("id", x.job_id.toString());
var response = message.execute();
var responseBody = response.getBody();
var httpStatus = response.getStatusCode();
if(httpStatus == 200){
var jobResponse = JSON.parse(responseBody);
x["remote_office_location"] = jobResponse["custom_fields"]["remote_office_location"];
x["jobtitle"] = jobResponse["name"];
}
})
var message = new sn_ws.RESTMessageV2('Greenhouse', 'candidates_by_ids');
message.setStringParameter("candidate_ids", candidateIDs.toString());
var candidateStream = global.ukg_streamData(message);
return candidateStream.map(function(candidate) {
var offerData = offersMap[candidate.id];
var personalEmail = candidate.email_addresses.find(function(email) {
return email.type === "personal";
});
return global.GQ.merge(offerData, {
"name": candidate.first_name + " " + candidate.last_name,
"first_name": candidate.first_name,
"last_name": candidate.last_name,
"preferred_name": candidate.custom_fields["preferred_name"] || "",
"personal_email": personalEmail && personalEmail.value,
"end_date": candidate.custom_fields["end_date"] || "",
"location": candidate.custom_fields["office_location"] || ""
});
});
});
offerStream.forEach(function(result) {
import_set_table.insert(result);
});
})(import_set_table, data_source, import_log, last_success_import_time);
Automating Processes to Assist Internal Teams
The integration wasn’t just about gathering data—it was about making life easier for the internal team managing onboarding. In addition to streamlining data tracking, we implemented the following enhancements:
- Automated Email Reports: Weekly emailed reports detail upcoming new hires, providing the team with a clear overview of who’s starting and when.
- Automatic Case Creation: Cases are automatically created in ServiceNow two weeks and one week before each new hire’s start date. These cases ensure that key tasks—like equipment setup and access provisioning—are completed on time.
Benefits of the API-Based Approach
Switching to an API-based integration has delivered significant benefits:
- Data Consistency: By querying Greenhouse directly, we ensure that onboarding workflows always have the most up-to-date information.
- Scalability: The API handles varying volumes of data seamlessly, enabling us to scale as hiring increases.
- Improved Team Efficiency: Automated reports and cases reduce manual tracking and ensure nothing falls through the cracks.
Lessons Learned
Looking back, the shift from an email-based integration to an API-based solution has been transformative. However, this evolution taught us a few key lessons:
- Start Simple, But Plan for Growth: Email-based integrations can help you go live quickly, but they’re rarely sustainable for high-volume processes. Be ready to iterate.
- Understand the Data Model: Before building an API integration, familiarize yourself with the platform’s endpoints and data relationships to ensure you’re pulling all necessary information.
- Test for Edge Cases: Not all candidates or jobs are the same. Test your integration with a variety of scenarios to identify gaps in data or logic.
Conclusion
Integrating ServiceNow with Greenhouse Recruiting has not only streamlined our clients’ onboarding processes but also empowered internal teams to manage new hires effectively. By investing in a robust integration, we’ve eliminated manual tracking, automated critical tasks, and ensured a consistent, scalable process for future growth.
If your organization is looking to enhance its onboarding capabilities, we’d love to share more about how we can help. Reach out to us today to start the conversation!