Skip to content

Greenhouse to Workday Recruiting Migration: The CTO's Guide

A CTO-level guide to migrating from Greenhouse to Workday Recruiting: data model mapping, API rate limits, scorecard handling, and cutover strategy.

Raaj Raaj · · 22 min read
Greenhouse to Workday Recruiting Migration: The CTO's Guide
TALK TO AN ENGINEER

Planning a migration?

Get a free 30-min call with our engineers. We'll review your setup and map out a custom migration plan — no obligation.

Schedule a free call
  • 1,200+ migrations completed
  • Zero downtime guaranteed
  • Transparent, fixed pricing
  • Project success responsibility
  • Post-migration support included

Migrating from Greenhouse to Workday Recruiting is not a vendor swap — it is a data-model translation from a specialized ATS into an enterprise HCM suite where recruiting is one module among many. You are moving from an application-centric system with high flexibility into a rigid, requisition-centric platform where every job must tie to a Requisition, which ties to a Position, which belongs to a Supervisory Organization. If that hierarchy does not exist in your Workday tenant before you start loading candidate data, every write will fail.

A naive CSV export from Greenhouse flattens this relational structure. It drops scorecards, collapses multi-application candidate histories, strips attachment URLs (which are ephemeral signed S3 links), and leaves you with no way to reconstruct the Candidate → Application → Job → Scorecard chain in Workday's schema.

The hard part is not extraction. The hard part is deciding what history should become a native Workday object, what should be serialized into notes, and what should stay in an external archive. This guide covers the data-model differences, every viable migration method with trade-offs, API constraints on both sides, the object-mapping decisions you need to make, and the edge cases that break most DIY attempts.

For adjacent migration patterns, see our Greenhouse to Lever migration guide, Taleo to Workday migration guide, and SuccessFactors to Workday migration guide.

Warning

Greenhouse Harvest API v1 and v2 will be deprecated and unavailable after August 31, 2026. Build your extraction pipeline against Harvest v3 (OAuth 2.0, cursor-based pagination) from day one. Do not build on v1/v2 only to rewrite months later. (support.greenhouse.io)

Why Companies Migrate from Greenhouse to Workday Recruiting

The drivers typically fall into three categories:

  • HCM consolidation. Organizations already running Workday for core HR, payroll, and finance want recruiting in the same platform to eliminate data silos. A unified system of record means a single employee lifecycle — from candidate to retiree — without integration middleware.
  • Position management alignment. Workday's position-based staffing model enforces strict alignment between Requisitions, Positions, and Supervisory Organizations. Companies with complex organizational structures (multi-entity, multi-country) need this level of control, which Greenhouse does not natively provide.
  • Compliance and reporting. Workday's built-in audit trails, configurable business process approvals, and unified reporting across HR, payroll, and recruiting can simplify SOX, GDPR, and EEO compliance for large enterprises.

Workday implementations are significantly more complex than Greenhouse deployments. Greenhouse typically takes weeks to a few months. Workday implementations frequently span six months to over a year because they involve core HR, payroll, and financial data alongside recruiting.

Core Differences: ATS-First vs HCM-First Data Models

Understanding the structural mismatch is the single most important pre-migration task.

Greenhouse data model (ATS-first):

  • Candidate — the person. Stays constant across applications.
  • Application — the candidacy for a specific Job. A Candidate can have multiple Applications.
  • Job — the role being filled. Contains an interview plan, scorecards, hiring team, and one or more Openings.
  • Scorecard — structured evaluation tied to an Application and interview step, with attribute ratings and recommendations.
  • Offer — compensation and start-date details tied to an Application.
  • Custom Fields — flexible fields at the candidate, application, job, and offer level.

Workday Recruiting data model (HCM-first):

  • Supervisory Organization — the management hierarchy. Workers are hired into positions within a Supervisory Organization.
  • Position — a specific seat in the org structure. Must exist before a requisition can reference it (in position management orgs).
  • Job Requisition — the hiring request. Linked to a Position and Supervisory Organization. Has types: Standard, Confidential, and Evergreen.
  • Candidate — the applicant. Created via Put_Candidate SOAP operation or REST API.
  • Job Application — the candidate's application to a specific requisition, governed by a configurable business process.
Info

In Workday, a Job Requisition requires a Supervisory Organization and typically a Position before it can be created. Greenhouse Jobs have no such dependency — they are standalone entities with flexible department and office associations. This hierarchy requirement is the single biggest source of mapping complexity.

A single Greenhouse Job with multiple Openings often needs to become one Workday Requisition with multiple Positions — not one flat row. Greenhouse's own Workday position-management guidance confirms this: when Workday requisitions are imported into Greenhouse, one Workday requisition maps to one Greenhouse job with multiple openings. Reverse migrations hit the same structural problem in the opposite direction. (support.greenhouse.io)

Key Structural Gaps

Greenhouse Concept Workday Equivalent Migration Challenge
Job (standalone) Job Requisition (tied to Position + Sup Org) Must pre-create Positions and Sup Orgs
Opening (per-job headcount) Position (org-level seat) 1:1 mapping only if position management is enabled
Scorecard (structured ratings) No direct equivalent Serialize to notes or custom assessment fields
Prospect (pre-pipeline contact) No equivalent Prospect pools have no Workday analog
Custom Fields (flexible, any object) Limited custom fields + calculated fields Must map to existing Workday fields or accept data loss
Activity Feed (notes, emails) Comments / attachments on Job Application Lossy — activity context is often lost

Greenhouse to Workday Migration Methods

Method 1: CSV Export → Workday EIB Import

How it works: Export Greenhouse data via built-in CSV reports (candidates, applications, jobs). Transform the CSVs to match Workday's Enterprise Interface Builder (EIB) spreadsheet templates. Upload via inbound EIB. Greenhouse supports XLS-style candidate report exports and recommends exporting rather than browsing in-app when the candidate list exceeds 1,000 applications. (support.greenhouse.io)

When to use: Small datasets (under 5,000 candidates), one-time migration, no engineering bandwidth.

Pros:

  • No API development required
  • Workday EIB is a no-code tool built into the platform
  • Good for simple data (names, emails, basic job info)

Cons:

  • Greenhouse CSV exports exclude attachment files — you get metadata, not actual resumes
  • Scorecards, interview feedback, and activity feed data are not available in standard CSV exports
  • EIB templates are rigid and error messages are cryptic
  • No way to preserve relational links (Candidate → Application → Scorecard chain)
  • Manual and error-prone at scale

Complexity: Low | Scalability: Small datasets only

Method 2: API-Based Custom ETL (Greenhouse Harvest → Workday SOAP/REST)

How it works: Extract data from Greenhouse via the Harvest v3 API. Stage raw objects. Transform to match Workday's schema. Load into Workday via Recruiting SOAP API operations (Put_Candidate, Create_Job_Requisition) or REST endpoints. New custom integrations should use Harvest v3 with OAuth 2.0 client credentials, cursor-based pagination, and header-driven throttling. Harvest v3 stops embedding every child resource in parent payloads, so your extractor must pull related resources explicitly and join them in staging. (harvestdocs.greenhouse.io)

When to use: Enterprise migrations with complex data (scorecards, attachments, multi-application histories). Teams with dedicated engineering capacity and Workday admin access.

Pros:

  • Full control over data extraction, transformation, and loading
  • Can preserve relational data, scorecards, and attachments
  • Handles deduplication logic and custom field mapping
  • Best auditability and fit for phased loads and retries

Cons:

  • Requires deep knowledge of both APIs
  • Workday's SOAP API has complex XML schemas and strict security configuration (ISU setup, ISSG permissions, domain security)
  • Requires maintaining two code paths (REST for some operations, SOAP for others)
  • 4–12 weeks of engineering time for a custom integration, plus ongoing maintenance

Complexity: High | Scalability: Enterprise

Method 3: iPaaS / Middleware (Workato, MuleSoft, Dell Boomi)

How it works: Use enterprise middleware with pre-built Workday and Greenhouse connectors. Configure extraction from Greenhouse, transformation rules, and loading into Workday. Can handle event-driven triggers or scheduled batch sync.

When to use: Organizations already invested in an iPaaS platform. Ongoing sync requirements beyond a one-time migration.

Pros:

  • Pre-built connectors reduce API plumbing work
  • Visual workflow builders for non-developers
  • Built-in error handling, retry logic, and monitoring
  • Can support ongoing sync post-migration

Cons:

  • Connectors abstract complexity but do not eliminate it — you still need to understand both data models
  • Task-based pricing can spike during large migrations
  • Limited support for complex transformations (scorecard serialization, attachment base64 encoding)
  • Historical data backfill is often a manual process even with iPaaS
  • Connector version lag is a real risk — Workato's current Greenhouse connector docs still reference Harvest v1, and Zapier uses polling-based triggers for some Greenhouse events (zapier.com)

Complexity: Medium | Scalability: Strong for ongoing sync, poor for bulk historical loads

Method 4: Managed Migration Service

How it works: A specialist team handles the full extraction, transformation, loading, and validation cycle. They manage API rate limits, data mapping, edge cases, and rollback planning.

When to use: When the migration is complex, engineering bandwidth is limited, and the cost of failure (data loss, broken relationships, compliance gaps) is high.

Pros:

  • Fastest time-to-completion
  • Risk transferred to the service provider
  • Handles edge cases (attachments, scorecards, deduplication) that DIY approaches drop
  • Built-in rate limit management and retry logic

Cons:

  • External dependency
  • Requires clear scope definition and communication
  • Quality varies sharply by vendor — ask how they handle scorecards, attachments, custom fields, retries, and rollback, not just candidates and jobs

Complexity: Low (for the customer) | Scalability: Any size

Migration Methods Comparison

CSV + EIB Custom API ETL iPaaS Managed Service
Engineering effort Low Very High Medium Minimal
Scorecard migration Partial
Attachment migration Partial
Relational integrity Partial
Rate limit handling N/A Manual Built-in Built-in
Time to complete Days (small) 4–12 weeks 2–6 weeks Days to 2 weeks
Ongoing sync Custom build Optional
Best for < 5K records Dedicated dev team iPaaS-invested orgs Complex, time-sensitive migrations

Handling API Rate Limits and Throttling

Both systems enforce rate limits that will bottleneck your migration if not handled properly.

Greenhouse Harvest API

  • v1/v2 (deprecated August 31, 2026): 50 requests per 10-second rolling window. Returns HTTP 429 when exceeded with X-RateLimit-Limit and X-RateLimit-Remaining headers.
  • v3 (current): Uses a 30-second fixed window. OAuth 2.0 (client credentials or authorization code flow). Cursor-based pagination returning up to 500 results per page.
  • Attachment URLs are ephemeral: Resumes and documents are hosted on AWS S3 with signed, temporary URLs that expire in 7 days. Download them immediately during extraction — do not defer. (developers.greenhouse.io)
  • Write operations require On-Behalf-Of header: Every POST, PATCH, DELETE must include a valid Greenhouse user ID for the audit trail.
Warning

Do not hard-code a single throttle value. v1/v2 uses a 10-second rolling window, while v3 uses a 30-second fixed window. Build a central rate-limit controller that reads X-RateLimit-* and Retry-After on every response. (developers.greenhouse.io)

Workday API

  • Rate limits are not fully public. Most details are available only to customers or partners. Implementation partners report approximately 10 calls per second, with some endpoints limited to 5 requests per second. Workday's Strategic Sourcing APIs explicitly document 429 handling and 5 requests per second for many services, plus 1 request per second for reporting. (community-content.workday.com)
  • SOAP and REST coexist. Critical Recruiting operations (Put_Candidate, Create_Job_Requisition, Get_Candidates) use SOAP (XML). REST covers a growing range but does not yet replace SOAP for all recruiting workflows.
  • ISU (Integration System User) required. Each integration needs a dedicated ISU with its own security profile and domain permissions. Budget time for this configuration — it is not trivial.
  • No native webhook support. Workday does not push real-time change events to external endpoints. The standard alternative is polling every 15–60 minutes.
Tip

Implement exponential backoff with jitter on all retry logic for both APIs. A simple linear retry will cause cascading failures when hitting Workday's concurrency limits. For Workday background sync jobs, avoid polling intervals shorter than 5 minutes.

Data Mapping: Objects, Fields, and Dependencies

This is the core translation layer. Get this wrong and everything downstream breaks.

Field-Level Mapping

Greenhouse Object.Field Workday Equivalent Transformation Notes
Candidate.first_name Candidate.Legal_Name.First_Name Direct map
Candidate.last_name Candidate.Legal_Name.Last_Name Direct map
Candidate.email_addresses [] Candidate.Email_Address_Data Map primary email; handle multiple
Candidate.phone_numbers [] Candidate.Phone_Data Map type (mobile, home, work)
Candidate.custom_fields Workday custom fields (if configured) Lossy — Workday custom field options are limited
Application.id Job_Application.Reference_ID Store as external reference for traceability
Application.status Job_Application.Status Map: active → In Progress, rejected → Declined, hired → Filled
Application.current_stage Job_Application.Recruiting_Stage Must pre-configure matching stages in Workday
Application.source Job_Application.Source Map to Workday Recruiting Source reference IDs
Job.name Job_Requisition.Job_Posting_Title Workday requires title to match Job Profile
Job.departments [] Supervisory Organization Must map to existing Workday Sup Org hierarchy
Job.offices [] Job_Requisition.Primary_Location Map to Workday Location reference IDs
Scorecard.overall_recommendation No direct field Serialize to note/comment on Job Application
Scorecard.attributes [] No direct field Serialize to structured text in comments
Offer.starts_at Job_Offer.Start_Date Direct map
Offer.salary Job_Offer.Compensation Requires Compensation Plan alignment
Attachment (resume) Candidate.Attachment_Data Download from ephemeral S3 URL, base64 encode, re-upload

Keep two things separate from day one: native target data and archived source truth. Not every Greenhouse artifact deserves a first-class Workday home, but every loadable artifact should keep a source key and every non-loadable artifact should have an archive policy.

Danger

Never flatten away Greenhouse candidate_id, application_id, job_id, opening_id, offer_id, or scorecard_id. Store them as external reference IDs in Workday. These become your crosswalk for traceability, debugging, and rollback.

Load Order Dependencies

Workday enforces referential integrity. The load order is non-negotiable:

  1. Supervisory Organizations — must exist first
  2. Job Profiles — must exist and match requisition criteria
  3. Positions — must be created or exist within the correct Sup Org
  4. Job Requisitions — created against a Position in a Sup Org
  5. Candidates — created via Put_Candidate
  6. Job Applications — link Candidate to Requisition
  7. Attachments and Notes — attached to Candidate or Job Application

If you try to create a Job Application before the Requisition and Candidate exist, Workday will reject the request.

Handling Custom Fields and Scorecards

Workday's custom field model is far more constrained than Greenhouse's. Greenhouse allows arbitrary custom fields at the candidate, application, job, and offer level with types including short text, long text, single-select, multi-select, date, URL, and user. Workday supports custom fields but they must be pre-configured by a Workday admin, and the available types and locations are limited.

You must audit all Greenhouse custom fields, discard the unused ones, and pre-configure the required ones in Workday before any data load begins. Map by immutable key and normalized option IDs, not by label text — labels change more often than keys.

Greenhouse Scorecards — structured attribute ratings per interview step — have no direct equivalent in Workday Recruiting. The recommended approach:

  • Serialize each scorecard as a structured text block: interviewer name, overall recommendation, attribute ratings, and notes
  • Attach as a comment or note on the corresponding Job Application in Workday
  • Preserve the raw scorecard JSON in your staging archive for compliance
  • Accept that this is a lossy transformation — you lose queryability but preserve the historical record

Picklist Reconciliation

Map every Greenhouse picklist value (sources, rejection reasons, pipeline stages, custom field options) to Workday reference IDs before loading. Unmapped values will silently default to null in Workday. Greenhouse's custom option sync documentation shows that some lists — such as Supervisory Organization — often require RaaS retrieval instead of a direct web-service list, and the web-service option-sync path cannot filter inactive values or control display ordering. (support.greenhouse.io)

Pre-Migration Planning

Before writing a single line of extraction code, freeze scope. Most over-budget ATS migrations happen because teams start with "move everything" and only later discover that closed requisitions, merged candidates, archived attachments, and stale custom fields have no operational value. Use our HRIS data migration checklist as the planning companion.

Data Audit

  • Count candidates by status: active, hired, rejected, prospects
  • Count applications and stage histories
  • Count jobs, openings, scorecards, offers, attachments, custom fields
  • Identify unused or test data that should not migrate
  • Most enterprises only migrate candidates active in the last 24 months — decide your cutoff early

Scope Definition

  • What must become native Workday data?
  • What can live in a searchable archive with source IDs?
  • What can be dropped because it has no business or compliance value?
  • Are you moving full interview scorecards or just final hiring decisions?

Workday Organizational Setup

Supervisory Organizations, Positions, Job Profiles, and Locations must exist in Workday before you can create Requisitions or Applications. Map and validate these first. Greenhouse's Workday sync docs are a good reminder that these reference lists often control whether a requisition or position can even be created. (support.greenhouse.io)

Migration Strategy

  • Big bang: Single cutover weekend. Fastest, but highest coordination risk.
  • Phased: By department or entity. Better for enterprise recruiting teams with regional rollouts.
  • Incremental: Ongoing sync during a transition period. Best when both systems must coexist.

A phased approach often works best in practice: migrate historical, closed jobs first, then run a delta sync for active pipelines over a cutover weekend.

Risk Mitigation

  • Freeze Greenhouse configuration (no new custom fields, no new pipeline stages) two weeks before cutover
  • Rehearse on production-like volume in a Workday sandbox tenant
  • Keep a rollback point for every batch — tag all migrated records with a consistent identifier
  • Disable automated notifications to prevent Workday from emailing candidates or flooding hiring managers' inboxes during bulk loading
  • Define who approves source cleanup, target cleanup, and go-live

Step-by-Step Migration Process

A safe architecture is extract → raw stage → normalized stage → dependency-ordered load → validation. Do not transform directly from Greenhouse into Workday. You need raw payload retention for replay, audit, and re-mapping.

Phase 1: Extract from Greenhouse

Use Harvest v3 API with cursor-based pagination. Extract all records into a local staging database (PostgreSQL, for example) or cloud storage bucket. Do not transform data in memory during extraction.

Harvest v3 intentionally stops embedding every child resource inside parent payloads, so you must pull candidates, applications, scorecards, attachments, and custom fields with separate API calls and join them in staging. (harvestdocs.greenhouse.io)

import requests
import time
import json
 
BASE_URL = "https://harvest.greenhouse.io/v3"
TOKEN = "your_oauth_token"
 
def fetch_all(endpoint, params=None):
    """Cursor-based pagination for Harvest v3."""
    results = []
    url = f"{BASE_URL}/{endpoint}"
    headers = {"Authorization": f"Bearer {TOKEN}"}
    
    while url:
        resp = requests.get(url, headers=headers, params=params)
        if resp.status_code == 429:
            retry_after = int(resp.headers.get("Retry-After", 30))
            time.sleep(retry_after)
            continue
        resp.raise_for_status()
        results.extend(resp.json())
        
        # Cursor-based: get next URL from Link header
        url = resp.links.get("next", {}).get("url")
        params = None  # Cursor URL includes all params
    
    return results
 
# Extract in dependency order
jobs = fetch_all("jobs")
candidates = fetch_all("candidates")
applications = fetch_all("applications")
scorecards = fetch_all("scorecards")
offers = fetch_all("offers")
 
# Download attachments immediately — URLs expire in 7 days
for candidate in candidates:
    for attachment in candidate.get("attachments", []):
        download_file(attachment["url"], attachment["filename"])
Warning

Greenhouse attachment URLs are signed S3 links that expire in 7 days. Download all resumes and documents synchronously during extraction. If you defer downloads, URLs will return 403 errors. Keep a file manifest with checksums for every download. (developers.greenhouse.io)

Phase 2: Transform

The transformation layer handles:

  1. ID mapping — Create crosswalk tables: Greenhouse integer IDs → Workday Reference IDs. Build these before the first write to Workday.
  2. Schema translation — Map Greenhouse objects to Workday equivalents per the field mapping table.
  3. Scorecard serialization — Convert structured scorecard data (attribute ratings, recommendations, Q&A) to text blocks. Scorecard answers can include basic HTML — sanitize it. Preserve raw JSON in the staging archive.
  4. Picklist reconciliation — Map Greenhouse picklist values (sources, rejection reasons, stages) to Workday reference IDs.
  5. Deduplication — Identify candidates who exist in both systems (common when Greenhouse and Workday have been running in parallel). Create a canonical-person map before load so historical applications do not fork into multiple Workday candidates. Greenhouse emits candidate-merge events — use them to build this map. (developers.greenhouse.io)
  6. Data cleaning — Remove or flag records with missing required fields. Workday will reject candidates without legal names or valid email addresses. Convert Greenhouse Markdown notes to plain text or Workday-supported rich text.
  7. Attachment preparation — Convert downloaded files to Base64 strings for Workday API payload compatibility. Implement file size checks — Workday restricts attachment sizes and file types. A 50MB design portfolio from Greenhouse will fail to load.

Phase 3: Load into Workday

Push normalized data into Workday using SOAP Web Services in strict dependency order. Process records in small batches (50–100 records) to avoid SOAP timeout errors.

import zeep
 
WSDL_URL = "https://wd2-impl.workday.com/ccx/service/{tenant}/Recruiting/v46.0?wsdl"
client = zeep.Client(wsdl=WSDL_URL, wsse=UsernameToken(isu_user, isu_pass))
 
def create_candidate(candidate_data):
    """Create or update a candidate in Workday via Put_Candidate."""
    request = {
        "Candidate_Data": {
            "Legal_Name_Data": {
                "Name_Detail_Data": {
                    "First_Name": candidate_data["first_name"],
                    "Last_Name": candidate_data["last_name"],
                }
            },
            "Email_Address_Data": [{
                "Email_Address": candidate_data["email"],
                "Usage_Data": {"Public": True}
            }],
            "External_Integration_ID_Data": {
                "ID": f"GH-{candidate_data['greenhouse_id']}"
            }
        }
    }
    
    try:
        response = client.service.Put_Candidate(request)
        return response.Candidate_Reference
    except zeep.exceptions.Fault as e:
        log_error(candidate_data["greenhouse_id"], str(e))
        return None

A high-level migration loop that makes dependency ordering explicit:

for job in greenhouse.jobs():
    wd_req = ensure_requisition(map_job(job))
 
    for opening in greenhouse.openings(job.id):
        ensure_position(wd_req, map_opening(opening))
 
    for app in greenhouse.applications(job_ids=[job.id]):
        candidate = greenhouse.candidate(app.candidate_id)
        scorecards = greenhouse.scorecards(application_ids=[app.id])
        attachments = greenhouse.download_attachments(app.id)
        load_candidacy(wd_req, candidate, app, scorecards, attachments)

Keep this as an outline, not copy-paste code — Workday service names, WSDL versions, and writeable fields vary by tenant and update cycle.

During bulk migration, configure Workday to use automatic processing that bypasses manual business process approvals. Otherwise every migrated application generates inbox tasks for hiring managers.

Error handling essentials:

  • Log batch ID, source ID, target ID, request payload hash, response code, and retry count
  • Make requisition and position creation idempotent
  • Send failed writes to a dead-letter queue, not a silent log
  • Keep a manifest for every attachment download and upload
  • Checkpoint every phase so you can resume without double-creating data

Phase 4: Validate

Run validation in the Workday Implementation (Impl) tenant before touching production. Execute a minimum of two full test migrations.

  • Record counts: Compare totals per object type between Greenhouse exports and Workday imports. A mismatch of even 1% on 50,000 candidates means 500 missing records.
  • Field-level sampling: For a random 10% sample, compare every mapped field value. Pay special attention to date formats (Greenhouse uses ISO 8601; Workday may expect different formats per locale), phone number formatting, email case sensitivity, and custom field picklist values.
  • Relationship verification: Confirm that Job Applications in Workday are linked to the correct Requisitions and Candidates.
  • Attachment spot-check: Open 20+ migrated resumes in Workday to confirm files are not corrupted and open correctly.
  • UAT with recruiting team: Have recruiters log into the Workday Impl tenant and verify candidate profiles, application histories, and serialized scorecard data. They will catch UI-level issues that API validation misses. Schedule 2–3 days for this.

Sampling strategy:

  • 100% of requisitions (low volume, high impact)
  • 100% of offers (compliance-critical)
  • 10% of candidates (random sample across departments)
  • 20+ attachment spot-checks
  • Edge-case sample for merged candidates, multi-opening jobs, and custom-field-heavy records

Rollback plan: If validation fails, you need a documented process to remove all migrated records from Workday. This is why tagging every record with a migration identifier (e.g., source: greenhouse-migration-2026) is non-negotiable. Never start final cutover without cleanup scripts prepared in advance.

Edge Cases That Break Migrations

Do not underestimate these. They routinely derail in-house projects.

Multi-application candidates. A single Greenhouse candidate with 5 applications across different jobs needs 5 separate Job Application records in Workday, each linked to a different Requisition. If those Requisitions do not exist yet, the applications fail silently.

Duplicate candidates. Greenhouse allows multiple candidate records with the same email (merged records, reapplications). Workday's Put_Candidate will match on email by default. Decide ahead of time: merge or skip? For one-time migrations, create a canonical-person map before load using Greenhouse's candidate-merge events. (developers.greenhouse.io)

Orphaned records. Greenhouse allows users to delete jobs while leaving candidates orphaned in the system. Workday requires applications to be linked to a Requisition. You must create a "Legacy Migration" Requisition in Workday to house these orphaned applications.

Prospects without jobs. Greenhouse Prospects can be associated with zero, one, or multiple jobs. Workday has no prospect pool concept. You need to either create these as candidates in a generic talent pipeline or drop them.

GDPR consent data. Greenhouse stores GDPR consent status per candidate. Workday has its own consent management framework. These do not map 1:1, and getting it wrong creates compliance risk.

Attachment size limits. Workday restricts attachment sizes and file types. Large portfolio files from Greenhouse will fail to load. Implement file size checks and truncation logic during the transform phase.

Workday business process enforcement. Creating a Job Application in Workday triggers a business process (approval chain). If you do not configure automatic processing during bulk migration, every migrated application generates inbox tasks.

Scorecard attribute ratings. Greenhouse scorecards contain structured data: focus attributes, overall recommendation (yes/no/definitely not), per-attribute ratings, and Q&A content. None of this maps to native Workday fields. Every scorecard must be serialized. If you do not plan for this early, months of interview feedback is lost.

Missing or inconsistent reference data. opening_id may be blank, picklists may have deleted options, and labels change more often than keys. Default to immutable IDs and explicit null handling. (developers.greenhouse.io)

Potential Data Loss Scenarios

Data Type Risk Level Mitigation
Candidate PII Low Direct mapping available
Application history Medium Requires correct load order and pre-existing requisitions
Scorecards High Must serialize — queryability lost
Prospect pools High No Workday equivalent
Activity feed High Partial migration to comments only
Custom fields Medium Pre-configure matching fields in Workday
Attachment files Medium Download immediately; do not defer

Post-Migration Tasks

  • Rebuild interview plans and scorecards in Workday. These do not migrate — they must be recreated natively in Workday's interview framework.
  • Reconfigure automations. Greenhouse's stage-transition automations, email sequences, and approval workflows do not transfer. Rebuild them as Workday business processes.
  • Update integrations. Any third-party tool (background check, assessment, HRIS sync) connected to Greenhouse needs to be reconnected to Workday.
  • Train the recruiting team. Workday's recruiter workflow is fundamentally different from Greenhouse. Budget for dedicated training time — not just documentation. Pay special attention to requisition vs. position behavior.
  • Update reporting. Rebuild dashboards and audit queries to use Workday IDs plus preserved source IDs.
  • Monitor for 30 days. Watch for data inconsistencies, missing records, and broken relationships that surface during real usage — especially for files, status history, and requisition links across at least one full hiring cycle.
  • Decommission Greenhouse gradually. Do not shut it down immediately. Keep read-only access for 90+ days as a reference while the team transitions. Shut down legacy syncs in order, not all at once.

Best Practices for a Clean Cutover

  • Back up everything before migration. Export all Greenhouse data to a local archive (JSON + attachments) before starting. This is your safety net.
  • Run test migrations in Workday sandbox. Never load directly into production. Validate in a non-production tenant first. EIB errors in production are painful to unwind.
  • Preserve source IDs. Store greenhouse_candidate_id and greenhouse_application_id as external reference IDs in Workday. You will need these for traceability and debugging.
  • Tag migrated records. Use a consistent label on every migrated record so you can filter, audit, and rollback if needed.
  • Download attachments synchronously. Do not defer. Greenhouse's signed S3 URLs expire in 7 days.
  • Disable notifications during bulk load. Prevent Workday from emailing thousands of candidates or flooding hiring managers' inboxes.
  • Run delta syncs. Complete the bulk historical migration weeks in advance. During cutover weekend, only migrate the delta (records changed in the last 14 days).
  • Maintain crosswalk tables permanently. Keep a strict ID mapping table in your staging database linking Greenhouse IDs to Workday IDs. This is mandatory for rollback, delta syncs, and post-go-live audit.
  • Document every compromise. If a Greenhouse field becomes a Workday note or is dropped entirely, make that decision explicit before UAT. No surprises for the recruiting team.
  • Validate in the Workday UI, not just via API. What the API returns and what the recruiter sees can differ.
  • Validate incrementally. Check after each object family is loaded, not only at the end.

Realistic Migration Timelines

Scenario Records Recommended Method Timeline
Small org, candidates only < 5,000 CSV + EIB 1–2 weeks
Mid-market, full data 5,000–50,000 API ETL or managed service 2–6 weeks
Enterprise, multi-entity 50,000+ Managed service 4–8 weeks
Ongoing sync (parallel run) Any iPaaS or custom Continuous

When to Use a Managed Migration Service

The most common failure modes in DIY migrations:

  1. Underestimating Workday's SOAP complexity. Teams budget 2 weeks for API integration and spend 8. The ISU setup, ISSG permissions, domain security configuration, and XML schema debugging alone can consume a sprint.
  2. Ignoring load order. Attempting to create Job Applications before Requisitions and Positions exist produces silent failures or cryptic EIB errors.
  3. Deferring attachment downloads. Greenhouse's S3 URLs expire. By the time the team gets to the load phase, half the resume links are dead.
  4. No rollback plan. Data loaded into Workday without consistent tagging cannot be cleanly removed if validation fails.
  5. Scorecard data dropped entirely. Teams discover too late that there is no Workday equivalent, and months of interview feedback is lost.

Outsource when any two of these are true:

  • Your engineering team does not have Workday SOAP API experience
  • You have more than 10,000 candidate records with attachments
  • Scorecards and interview feedback must be preserved
  • The migration must complete within a fixed cutover window
  • Both systems must coexist during cutover with live data changing
  • The cost of failure (compliance gaps, lost recruiting data) exceeds the cost of the service

ClonePartner specializes in complex ATS-to-HCM migrations. For Greenhouse-to-Workday projects, that means preserving relations across jobs, openings, candidates, applications, offers, and files; mapping custom fields without losing auditability; scaling batches safely through both APIs' rate limits; and reducing the amount of Workday-specific plumbing your internal team has to own. Your engineering team stays focused on product work — we handle the migration. For a case study on ATS migration, see how Highsnobiety completed a multi-month ATS migration in days.

What a Good Migration Looks Like

A good Greenhouse to Workday Recruiting migration has three outputs: clean live data in Workday, a searchable archive of anything that does not belong in the target model, and a crosswalk that explains every ID translation. If you cannot produce all three, you are not ready for cutover.

For broader context on HRIS migration planning, see our SuccessFactors to Workday migration guide and our guide on GDPR/CCPA compliance during candidate data transfers.

Frequently Asked Questions

Can you migrate Greenhouse scorecards to Workday Recruiting?
Not natively. Workday Recruiting has no structured scorecard equivalent. The recommended approach is to serialize each scorecard (interviewer, recommendation, attribute ratings) as a text block and attach it as a comment or note on the corresponding Workday Job Application. This preserves the historical record but loses queryability.
What are the Greenhouse Harvest API rate limits?
Harvest v1/v2 allows 50 requests per 10-second rolling window. Harvest v3 uses a 30-second fixed window. Both return HTTP 429 when exceeded. v1/v2 is being deprecated on August 31, 2026 — build on v3 with OAuth 2.0 and cursor-based pagination.
What are Workday Recruiting API rate limits?
Workday does not publish comprehensive rate limit documentation. Implementation partners report approximately 10 calls per second, with some endpoints limited to 5 requests per second. Implement exponential backoff and avoid polling intervals shorter than 5 minutes.
How long does a Greenhouse to Workday Recruiting migration take?
Small orgs (under 5,000 candidates) with CSV+EIB can finish in 1–2 weeks. Mid-market full-data migrations take 2–6 weeks via API ETL or managed service. Enterprise multi-entity migrations typically require 4–8 weeks.
What data is lost when migrating from Greenhouse to Workday?
Scorecards lose structured queryability (serialized to text). Prospect pools have no Workday equivalent. Activity feed context is partially preserved as comments. Custom fields may not map 1:1 due to Workday's more constrained model. Attachments are lost if not downloaded before Greenhouse's signed S3 URLs expire.

More from our Blog