Sync new Greenhouse hires into SAP SuccessFactors daily

By General Input

Once a day, new hires from Greenhouse are set up in SuccessFactors automatically, with anyone missing key details flagged for your recruiters instead.

Integrations

  • SAP SuccessFactors
  • Greenhouse
  • Slack Bot

Type

Agentic Task

Categories

  • HR & People
  • Operations

Once a day, sync newly hired candidates from Greenhouse into SAP SuccessFactors so recruiters stop rekeying the same person into two systems. Run this on a daily schedule rather than off a Greenhouse webhook: a bounded daily query is simpler and keeps the workflow idempotent.

Start in Greenhouse with List Applications, filtered to applications whose status is hired and whose activity falls within the last 24 hours. For each hired application, call Get Candidate to pull the full candidate record, including start date, offer details and custom fields. Read custom fields from keyed_custom_fields rather than custom_fields, so the keys stay stable if someone renames a field in Greenhouse.

Before writing anything, check that each candidate has everything required: legal first and last name, a confirmed start date, a department and a manager. This needs judgement rather than a fixed field mapping, because different Greenhouse setups store these in different places, including custom fields and offer details. If a candidate is missing any required value, do not write a partial record. Skip that candidate entirely and collect them into a list of people needing recruiter attention, noting exactly which fields were missing.

For each complete candidate, map the Greenhouse record onto SuccessFactors and write a pre-hire record using Upsert Records. Writes go through the single upsert endpoint rather than per-entity creates, and each object in the payload carries a __metadata.uri naming its entity set, so send one object for the person entity set and one for the employment entity set. Specify purgeType incremental explicitly, so the write only touches the fields sent and updates or inserts rather than replacing a whole associated collection.

Upsert by a stable business key so that a rerun updates the existing record instead of duplicating it. Use personIdExternal for the person record and userId for the employment record, and derive both deterministically from the Greenhouse candidate so the same person always maps to the same key. The start date is load bearing rather than cosmetic: effective dated entities include startDate in their key, so a wrong or missing start date writes the wrong record. That is exactly why a missing start date is a skip rather than a best guess.

When the writes are done, post one confirmation to Slack with Send a Message into the recruiting operations channel. Summarize who was created in SuccessFactors and with what start date, then list separately every candidate that was skipped along with what each one was missing, so a recruiter can fix the record in Greenhouse and let the next run pick them up. If nobody was hired in the last 24 hours, skip the Slack message rather than posting an empty summary.

This workflow writes into the HR system of record, so stay conservative throughout. Never invent a value to satisfy a required field, never guess at a manager or department, and always prefer skipping and flagging over a best effort write.

Related prompts

Explore more prompts
A brand asset library your marketing team actually searchesTurn Mailjet email clicks into ranked HubSpot follow-upsClean out the Looker dashboards and Looks nobody opensLiveKit live operations console for room moderationWake up dormant Keap leads with a researched reasonLiveChat coverage board for planning next week's shiftsPhone routing control panel for LiveKit voice agentsLinkedIn Ads budget pacing dashboard for every client accountGive your team Looker numbers without buying more seatsPause marketing emails to escalated customers, then restore them