Considering we are retaining BambooHR for team member data, we need to make sure that applicants are created in BambooHR once they are hired. We created a custom sync between Greenhouse and BambooHR to avoid manual work adding the right data from one system to the other.
Whenever a candidate is marked as hired, a webhook is send to the conservatory app.
Our current implementation of this for Workday, is handled by the Platypus project.
The sync is a one-way sync. We take the data from Greenhouse and add it to BambooHR. Some fields on BambooHR are calculated fields by using data from Greenhouse.
Greenhouse Data | BambooHR Data |
---|---|
first_name (Applicant data) - the preferred name |
firstName |
last_name (Applicant data) |
lastName |
the part in first_name that's between quotes (Applicant data) |
preferredName |
the part in last_name that's between quotes (Applicant data) |
customPreferredLastName |
candidate_country (Offer data) |
country |
state_of_team_member (Offer data) |
state |
starts_at (Offer data) |
hireDate |
email_addresses.personal (Applicant data) |
homeEmail |
department (Offer data) |
department |
division (Offer data) |
division |
employment_type (Offer data) |
customFullOrPartTime |
id (Greenhouse Applicant) |
customCandidateID |
Mapped through candidate_country to the right value |
customPayFrequency |
Mapped through candidate_country to the right value |
customRegion |
Copied from the hiring_manager |
customCostCenter |
locality (Offer data) |
customLocality |
specialty (Offer data) |
customJobTitleSpeciality |
level_of_role (Offer data) |
customRole |
Mapped by Greenhouse entity using this file | customEmployeeCorptoCorp |
starts_at (Offer data) |
customHireDate |
stock_options (Offer data) |
customShares1 |
stock_options (Offer data) |
customTotal |
rsu_$_value (Offer data) |
customRSUValue |
entity (Offer data) |
customInc/BV |
"Hired" (Hardcoded value - not from Greenhouse) | customNotes |
starts_at (Offer data) |
date |
job_title (Offer data, can only be synced if the title exists on BambooHR) |
jobTitle |
hiring_manager (Offer data) |
reportsTo |
starts_at (Offer data) |
startDate |
Mapped by Greenhouse entity using this file | location |
salary (Offer data) / pay_frequency |
rate |
If contractor -> Contract, else -> Salary | type |
"Exempt" (Hardcoded value - not from Greenhouse) | exempt |
"Hire" (Hardcoded value - not from Greenhouse) | reason |
Depends on contractor or pay frequency | paidPer |
Mapped through candidate_country to the right value |
paySchedule |
Mapped by using the local currency to the USD rate | customCurrencyConversionFactor |
Latest revision date of the currency conversion file | customConversionEffectiveDate |
starts_at (Offer data) |
customEffectiveDate2 |
starts_at (Offer data) |
customEffectiveDate3 |
salary * customCurrencyConversionFactor |
customUSDAnnualSalary |
salary with currency |
customLocalAnnualSalary |
starts_at (Offer data) |
customDate |
Mapped by Greenhouse offer entity using this file | customType |
Hardcoded to RSU , ISO , or International |
customType1 |
Hardcoded to Stock Options or Restricted Stock Units |
customShareVehicle |
(Hardcoded value - not from Greenhouse) | customReason |
Yes | customVariablePay |
bonus_currency_&_amount_(amount_per_year_as_defined_by_previous_field) (Offer data) |
customAnnualAmountLocal |
customAnnualAmountLocal * customCurrencyConversionFactor |
customAnnualAmountUSD |
customAnnualAmountUSD * customUSDAnnualSalary |
customOTEUSD |
customVariablePay * salary |
customOTELocal |
job_code (Offer data, can only be synced if the job code exists on BambooHR |
customJobCode |
job_grade (Offer data) |
customJobGrade |
sales_geo_differential (Offer data) |
customSalesGeoDifferential |
ghp_id (Offer data) |
customNumber |
starts_at (Offer data) |
customBonusdate |
signing_bonus_currency_&_amount (Offer data) |
customBonusAmount |
"Signing Bonus" (Hardcoded value - not from Greenhouse) | customBonustype |
"Paid Signing Bonus" (Hardcoded value - not from Greenhouse) | customBonuscomments |
family_relationship (Offer data) |
customRelationship |
A new employment status row is added and the value is set to Active |
employmentStatus |
starts_at (Offer data) |
customEffectiveDate6 |
Mapped through candidate_country to the right value |
customPayFrequency2 |
job_code (Offer data, can only be synced if the job code exists on BambooHR |
customJobCode2 |
job_grade (Offer data) |
customJobGrade2 |
Besides syncing the above fields, we also sync:
attachments
on the
candidate itself. We only sync the signed offer letter and the resume. The signed offer letter is
synced to the Contracts & Changes
and the resume is synced to the Resumes and Applications
folder on BambooHR. They are set to be shared with the new team member.country
and state
listed on Greenhouse.When required data is missing, the system is set up to send a Slack message about this applicant. Currently these candidates will need to be synced manually.
Currently the sync went through two iterations and has replaced most (but not all) manual work for the People Connect and Total Rewards teams. Open issues can be found here. If you want to add another field to the sync, feel free to create a new issue.
In case a hire wasn't synced an alert will be sent to the #peopleops-alerts
Slack channel, in which a People Group Engineer will be able to manually re-sync the new team member after correcting malformed fields.