Skip to content

PeopleForce to HR Cloud Migration: A Technical Guide

Technical guide to migrating from PeopleForce to HR Cloud — covering API extraction, field mapping, history entities, rate limits, and edge cases that cause silent data loss.

Roopendra Talekar Roopendra Talekar · · 24 min read
PeopleForce to HR Cloud Migration: A Technical 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,500+ migrations completed
  • Zero downtime guaranteed
  • Transparent, fixed pricing
  • Project success responsibility
  • Post-migration support included

PeopleForce to HR Cloud Migration: A Technical Guide

Migrating from PeopleForce to HR Cloud is a data-model alignment problem. PeopleForce is a mid-market HRIS organized around a flat Employee object linked to departments, divisions, positions, and compensation records — with a clean REST API (v2) that exposes these entities directly. HR Cloud is a modular HR platform built around a richer xEmployee object model that includes distinct history entities for salary, employment, position changes, bonuses, and rehires — all managed through a separate Core HR API (v1).

If you need a fast decision: PeopleForce's CSV exports produce flat snapshots that strip away historical context, effective-dated changes, and binary attachments. For any migration involving more than ~50 employees or requiring history data, the REST API is the only viable extraction path. On the target side, HR Cloud accepts data through both CSV import and its Core HR REST API, but only the API lets you load history entities programmatically and maintain referential integrity.

Verification note: Endpoint paths, field names, rate limits, and authentication schemes in this guide were validated against PeopleForce API v2 and HR Cloud Core HR API v1. API behavior can change; re-verify against /v1/Meta/xEmployee and PeopleForce's developer portal before building production scripts.

This guide covers extraction methods from PeopleForce, field-by-field mapping to HR Cloud, real API constraints on both sides, the specific load sequence that prevents silent failures, and the edge cases that break employee records during HRIS migrations.

For a broader migration framework, see The Ultimate HRIS Data Migration Checklist. If your migration scope includes sensitive compensation or payroll data, review How to Safely Migrate Sensitive Employee & Payroll Data.

Why Teams Move from PeopleForce to HR Cloud

PeopleForce is strong for companies with European roots — particularly Ukraine and Eastern Europe and those expanding globally. It handles employee lifecycle management, recruiting (PeopleRecruit), performance reviews, time tracking, e-signatures (PeopleSign), and workflows well for teams of roughly 50–2,000 employees. Its API is developer-friendly and well-documented.

HR Cloud serves a different profile. It consolidates HRIS, onboarding, ATS, time tracking, performance, engagement, surveys, and communication tools into one unified platform, and is a strong fit for HR teams that need better onboarding workflows, stronger engagement tooling, and easier employee data management. It works particularly well for organizations with multi-location teams, deskless employees, compliance-heavy processes, or growing operational complexity.

The typical trigger: a company needs stronger onboarding workflows, employee engagement tools (HR Cloud's Workmates module), or operates in US-based industries like healthcare, manufacturing, retail, education, or government where HR Cloud has deep workflow support — credentialing, shift management, PTO policies, compliance tracking, asset tracking, onboarding packets, and mobile communication.

PeopleForce vs HR Cloud: Data Model Comparison

Understanding where the data models diverge is the foundation of a clean migration. As with other flat-to-hierarchical HRIS migrations, you cannot simply map fields one-to-one.

PeopleForce's model is employee-centric and relatively flat. Its REST API exposes HR entities including employees, candidates, vacancies, leave requests, departments, divisions, and positions. Each employee record links to departments, divisions, positions, and compensation records. Custom fields attach directly to the employee profile. Custom tables allow structured data beyond flat fields. The platform explicitly recommends adding new salary or position records rather than overwriting existing ones when you want to preserve history.

HR Cloud's model is structurally richer. The Core HR API organizes data around an xEmployee entity with linked reference entities: Department, Division, Location, Position, Task, Time Off Request, Time Off Accrual, and Time Off Balance. HR Cloud maintains separate history entitiesBonus History, Employment History, Position History, Rehire History, and Salary History — each with its own API endpoints and record structure. This architectural shift requires splitting nested source data into distinct payloads, a pattern we also detail in our HeavenHR to Officient migration guide.

The biggest translation gap is job architecture. PeopleForce's Job Catalog supports job profiles, groups, levels, skills, custom profile data, and effective-dated assignment history. HR Cloud's public xPosition object is much leaner: code, title, status, and optional description. PeopleForce Job Group, Job Level, and skill metadata do not land cleanly in HR Cloud unless you flatten them into custom fields or keep them in an archive or reporting layer.

Concept PeopleForce HR Cloud
Core employee record Employee xEmployee
Organizational unit Department, Division Department, Division, Location
Job role Position (linked to employee) Position (with Position History)
Pay data Compensation (sub-resource on employee) Salary History (separate entity)
Employment changes Position records with dates Employment History, Rehire History
Time off Leave Requests Time Off Request, Time Off Accrual, Time Off Balance
Recruiting Candidates, Vacancies Applicant
Documents Attachments on profile Attachments via /xEmployee/:id/attachments
Custom fields Flat custom fields + custom tables Custom fields on employee object
Authentication API Key (X-API-KEY header) HTTP Basic Auth (Base64 credentials)
Warning

PeopleForce stores compensation as a sub-resource of the employee. HR Cloud stores salary data in a dedicated Salary History entity. If you flatten compensation records during extraction, you lose the change timeline — and rebuilding it in HR Cloud's history format requires careful date-sequencing logic.

How to Extract Data from PeopleForce

You have two extraction paths: the REST API and manual CSV/XLSX exports. For any migration requiring history data, documents, or relational integrity, the API is the only viable option.

The PeopleForce API follows REST conventions and allows retrieving information about all major HR entities stored in the system.

Authentication: A Company API key provides full access to the PeopleForce API and employee data with minimal restrictions. Include it in a header parameter called X-API-KEY. All API requests must be made over HTTPS — plain HTTP calls fail without exception.

Access tier requirement: PeopleForce gates API access and webhooks to the Professional tier. If your tenant is on a lower tier, you cannot run a full API-based extraction. Confirm your tier before scoping the migration — a CSV-only extraction cannot preserve compensation history or custom table data.

Rate limits: The rate limit is 300 requests per minute, enforced per requesting IP address. When exceeded, the API returns HTTP 429. Examine the Retry-After response header to determine when the limit resets, and implement a built-in delay to pause requests between bursts. Do not simply retry immediately on 429 — that compounds the problem.

Call volume estimate: A 500-employee org requiring per-employee profile pulls, compensation history, custom table data, and document metadata typically requires:

  • 10 paginated calls for the master employee list (50/page)
  • 500 calls for individual employee profiles
  • 500 calls for compensation sub-resources
  • 500 calls for custom table data (one per table per employee)
  • 500+ calls for document metadata and signed URLs

That's ~2,000–2,500 API calls for extraction alone, before any attachment downloads. At 300 req/min, budget 8–10 minutes of extraction time for core data. Document downloads are separate and depend on file sizes and network throughput.

Key endpoints for extraction:

GET /v2/employees                    # All employee records (paginated)
GET /v2/employees/{id}               # Single employee with custom table data
GET /v2/departments                  # Department list
GET /v2/divisions                    # Division list
GET /v2/positions                    # Position list
GET /v2/employees/{id}/compensations # Compensation records (all history)
GET /v2/leave_requests               # Leave/time-off requests
GET /v2/recruitment/candidates       # Candidate records
GET /v2/recruitment/vacancies        # Vacancy records
GET /v2/employee_tables              # Custom table definitions
GET /v2/employees/{id}/tables/{id}   # Custom table data per employee
GET /v2/time/timesheet_entries       # Timesheet records

Pagination: All list endpoints use unified pagination. Iterate through pages to extract complete datasets.

Warning

Stick to a page size of 50–100. Larger pages cause gateway timeouts, especially on the employees endpoint which carries a heavy payload of nested custom fields.

# Example PeopleForce extraction request
curl -X GET "https://app.peopleforce.io/api/public/v2/employees?page=1&limit=50" \
     -H "X-API-KEY: YOUR_API_KEY" \
     -H "Accept: application/json"

Extracting historical data: When you query the employees list endpoint, you receive current state only. To get job history, salary changes, or past reporting lines, you must query specific sub-endpoints per employee. This requires a nested extraction loop:

  1. Pull the master list of all Employee IDs via paginated GET /v2/employees.
  2. For each employee, pull compensations, position history, and leave requests from the per-employee sub-endpoints.
  3. Pull custom table data per employee via /employees/{id}/tables/{table_id}.
  4. Store everything in a staging database (PostgreSQL works well) or structured JSON files before transformation.
Tip

The GET /v2/employees/{id} endpoint returns custom table data inline when accessed for a single employee. Bulk list endpoints do not include this. Plan for per-employee API calls if custom table data is in scope — and budget your 300 req/min rate limit accordingly.

Webhooks for delta sync: The PeopleForce Webhooks API allows subscribing to events rather than polling for changes. Available events include employee_create, employee_update, employee_terminated, employee_first_day, employee_position_created, employee_position_updated, and compensation events. The employee list API also supports updated_at filters, enabling a repeatable delta extraction window:

GET /api/public/v3/employees?status=all&updated_at[gte]=2026-08-20T00:00:00Z&page=1

CSV/XLSX Export (Supplementary Only)

You can export comprehensive lists of employees in .xlsx or .csv formats. Administrator rights are required. Filters allow downloading specific subsets — terminated employees, a specific department, etc.

CSV exports produce flat snapshots. They don't capture:

  • Compensation change history (only current values)
  • Custom table row-level data
  • Document attachments
  • Leave request approval chains
  • Relational IDs needed for programmatic loading

Use CSV exports as a validation layer — good for baseline counts and spot-checking, not as your primary extraction method.

How to Load Data into HR Cloud

HR Cloud offers two ingestion paths: CSV import through the admin UI and the Core HR REST API.

HR Cloud's Employee API is a RESTful API that allows integration partners to create and update employee data — as well as associated entities such as departments, locations, and positions — in HR Cloud. It adheres to REST principles, using standard HTTP methods (GET, POST, PUT, DELETE) with data exchanged in JSON format.

Authentication: HR Cloud uses HTTP Basic Authentication. Base64-encode your credentials and pass the result as the Authorization header value in all API requests.

Base URL: https://corehr-api.hrcloud.com/v1/cloud/

Key endpoints for loading:

POST /xEmployee                      # Create employee
PUT  /xEmployee                      # Update employee
GET  /xEmployee                      # List employees (for validation)
POST /xEmployee/:id/attachments      # Upload documents (multipart/form-data)
GET  /xDepartment                    # Departments
GET  /xPosition                      # Positions
GET  /xLocation                      # Locations
GET  /xDivision                      # Divisions
GET  /xSalaryHistory                 # Salary history records
GET  /xPositionHistory               # Position history records
GET  /xEmploymentHistory             # Employment history records

The API supports bulk add and update operations using array payloads for POST and PUT on the employee endpoint.

HR Cloud's PUT /xEmployee endpoint supports flexible identifier resolution — you can update by internal Id or by a unique attribute like email, with mapping parameters specifying lookup behavior:

PUT /v1/cloud/xEmployee?Identifier=xEmail&mapping=xDepartmentLookup to xDepartmentCode,xManagerLookup to xEmail

This is the cleanest path for the second-pass manager relationship update (covered in Step 5 below).

History entities: History records are written through dedicated endpoints with their own request schemas. Each history entity requires:

Entity Required Fields Notes
Salary History employeeId, effectiveDate, amount, currency, payFrequency One record per compensation change
Position History employeeId, effectiveDate, positionId, department One record per role change
Employment History employeeId, effectiveDate, employmentStatus One record per status change
Bonus History employeeId, bonusDate, amount, bonusType One record per bonus event
Rehire History employeeId, rehireDate, reason Only for re-employed individuals
Warning

Critical caveat on history loading: HR Cloud's public docs are clearer on reading history than writing historical backfills. The xSalary and xBonus fields on the employee object cannot be updated through PUT /xEmployee. Historical backfill via API may be tenant-configured or require HR Cloud professional services engagement for large volumes. Before building history load scripts, request from HR Cloud support: (1) confirmation that your tenant has history write enabled via API, (2) the exact endpoint and payload schema for each history entity, and (3) whether bulk array writes are supported for history records.

Attachments: Documents are uploaded per-employee via multipart/form-data to /xEmployee/:id/attachments — there's no bulk document upload endpoint. For a company with 500 employees averaging 5 documents each, that's 2,500 individual API calls just for attachments. Plan this phase separately with its own time budget.

Info

HR Cloud's public API documentation does not specify a hard rate limit for the Core HR API. Implement exponential backoff on 429 or 5xx responses, start with conservative throughput (10–20 requests/second), and run bulk loads during off-peak hours. Contact HR Cloud support before starting a large migration to confirm current API throughput limits for your specific tenant.

Pre-Load Validation Checklist

Run these assertions against your transformed dataset before submitting any records to HR Cloud. Silent failures in HRIS migrations almost always trace back to skipping this step.

Check What to Verify Failure Mode
Unique email Every employee record has a non-null, unique email address HR Cloud creates a duplicate employee record for any missing email
Required fields firstName, lastName, email, hireDate, employmentStatus are populated for all records API returns 422; record not created
Enum whitelist gender, employmentStatus, country, payFrequency values match HR Cloud's exact picklist values Silent reject or wrong value stored
Salary history date order Compensation records per employee are in ascending effectiveDate order with no overlapping date ranges Incorrect current salary displayed
Referential integrity All department, division, location, position values exist in HR Cloud reference data Auto-creates misspelled/duplicate reference records (CSV path) or 422 error (API path)
Manager existence All reportsTo / xManagerLookup values reference employees already loaded in HR Cloud Manager field silently nulled or error
Date format consistency All dates in ISO 8601 format (YYYY-MM-DD); no ambiguous MM/DD/YYYY values One-day offset errors on hire/termination dates
Terminated employee completeness Terminated records include terminationDate and final employment status Incorrect status displayed; compliance audit gaps
Custom field names All custom field names match exactly what is pre-configured in HR Cloud tenant Field ignored or 422 error
Duplicate detection No employee appears twice by email + hire date combination Duplicate records in target system

HR Cloud CSV Import (Reference Data and Small Loads)

HR Cloud supports CSV import for bulk reference data — departments, locations, divisions, and positions. This is the fastest path for initial organizational skeleton setup.

The CSV import has a dangerous auto-creation behavior: when creating a record for an employee who works in a department (e.g., "HR"), if no matching record is found in the departments table, HR Cloud will automatically create one. This can generate duplicate or misspelled reference data if your CSV isn't perfectly clean. Validate reference data spelling before import; the auto-creation behavior does not warn you.

Use CSV import for initial reference data setup, then switch to API-based loading for employee records and history.

Danger

Validate HR Cloud's actual schema in your tenant before locking transforms. The public docs use xAddress in one employee PUT example but describe xAddress1 and xAddress2 in the employee object. They also describe xCountry as a number in one location while another official example validates a case-sensitive string like India. Do not build production transforms from the help center alone. Use GET /v1/Meta/xEmployee to retrieve the live schema for your tenant, then submit a sandbox payload to confirm field behavior before writing production transform code.

Field-by-Field Mapping: PeopleForce → HR Cloud

This mapping covers the core employee record. Adjust for your specific custom fields.

PeopleForce Field HR Cloud Field Transform Required Notes
id (external reference) Store as-is Retain as external ID for reconciliation and delta syncs
first_name firstName None Direct map
last_name lastName None Direct map
email email None Used as unique identifier in HR Cloud
personal_email personalEmail None Direct map
phone / mobile_number phone / xCellPhone None Direct map
date_of_birth dateOfBirth Verify ISO 8601 Check source format
hired_on / hire_date hireDate / xStartDate Verify ISO 8601 Check timezone handling
termination_date terminationDate Verify ISO 8601 Only for terminated employees
gender gender Enum transform maleMale, femaleFemale (case-sensitive)
department.name xDepartmentLookup Must match reference data Auto-creates if mismatch on CSV path
division.name division Must match reference data Same auto-creation risk
position.name xPositionLookup Must match reference data Map to HR Cloud Position entity
location xLocationLookup Must match reference data Must match HR Cloud Location entity
manager.email xManagerLookup Requires two-pass load Manager must already exist in HR Cloud
status xEmploymentStatusLookup Enum transform Map PeopleForce statuses to HR Cloud picklist values
compensation.amount Salary History amount Separate history record Do not flatten — load as history entity
compensation.currency Salary History currency None Pair with amount
compensation.effective_date Salary History effectiveDate Verify ISO 8601 Preserves the full change timeline
Custom fields Custom fields Name must match exactly HR Cloud custom field names must be pre-configured in tenant
Tip

Do not map by display label alone. Build a field catalog with source label, source internal name, data type, allowed values, target field, transform rule, and owner approval. That single artifact prevents most silent data corruption in HRIS migrations.

Job Architecture: Handling the PeopleForce → HR Cloud Structural Gap

This is the most analytically complex mapping problem in this migration. Use this decision framework for each PeopleForce Job Catalog attribute:

PeopleForce Job Catalog Attribute Recommended Treatment in HR Cloud Rationale
Job Title xPosition title field Direct equivalent
Job Code xPosition code field Direct equivalent
Job Level (e.g., L3, Senior) Custom field on xEmployee xPosition has no level field
Job Group / Family Custom field on xEmployee or xPosition description No direct equivalent
Skills / Competencies HR Cloud Skills module (if licensed) or archive Depends on whether Skills module is in scope
Effective-dated assignment history Position History entity Load each change as a history record
Custom Job Profile fields Custom fields on xEmployee Must be pre-configured in HR Cloud tenant
Job descriptions xPosition description field or attached document Truncate if description exceeds field length

Decision rule: If the attribute is used for active HR decision-making (compensation banding, promotion criteria, compliance reporting), configure it as a custom field in HR Cloud before migration. If it is historical context only, archive it as a document attachment or in a data warehouse and exclude it from the live HR Cloud record.

Migration Sequence: Step by Step

The order matters. HR Cloud enforces referential integrity — an employee cannot reference a department that doesn't exist yet.

Step 1: Audit PeopleForce Data

Before writing a single line of migration code:

  • Export the full employee list via CSV as a baseline count
  • Identify all active custom fields and custom tables in use
  • Count compensation records, position changes, and leave balances per employee
  • Document all department, division, and position values (exact spelling matters for reference data matching)
  • Flag terminated employees you need to migrate for compliance
  • Confirm your PeopleForce plan includes API and webhook access (Professional tier required)
  • Confirm with HR Cloud support whether your tenant has API-based history write enabled

Step 2: Load Reference Data into HR Cloud

Create the organizational skeleton in HR Cloud first:

  1. Departments — via CSV import or API
  2. Divisions — via CSV import or API
  3. Locations — via CSV import or API
  4. Positions — via CSV import or API
  5. Employment Status values — via HR Cloud admin configuration
  6. Custom fields — configure all target custom fields before loading any employee data

Validate each entity exists in HR Cloud before proceeding. Any mismatch between your employee data and reference data will either auto-create bad records (CSV path) or fail with a 422 validation error (API path).

Step 3: Extract Employee Data from PeopleForce via API

Build an extraction script that:

  1. Paginates through GET /v2/employees (page size 50–100) to get all employee IDs
  2. Calls GET /v2/employees/{id} per employee for full profile + custom table data
  3. Calls GET /v2/employees/{id}/compensations for all compensation records — not just current
  4. Extracts leave requests via GET /v2/leave_requests
  5. Downloads document metadata and signed URLs (download files immediately — signed URLs expire)
  6. Stores all extracted data in a staging database or structured JSON files

Step 4: Transform Data

This is where the real work happens:

  • Map PeopleForce status values to HR Cloud employment status codes — build an explicit lookup table, not inferred logic
  • Convert compensation records into HR Cloud Salary History format — each change as a separate history record with effective date, sorted ascending
  • Split position changes into Position History records with effective dates
  • Resolve manager references by email or external ID — flag any circular reporting relationships early
  • Normalize date formats to ISO 8601 (YYYY-MM-DD). PeopleForce often stores dates in UTC; validate how your tenant's HR Cloud configuration interprets timezone-naive dates. A one-day offset on hire dates has real payroll and compliance implications
  • Normalize enumsgender (maleMale), country (string vs. integer), and other picklist fields require explicit transforms verified against your live HR Cloud tenant
  • Map custom fields to pre-configured HR Cloud custom fields (names must match exactly)
  • Apply job architecture decision framework — determine what becomes a position, custom field, or archive-only data before starting this step

Run the pre-load validation checklist (above) against the transformed dataset before proceeding.

Step 5: Load Employees (Two-Pass Strategy)

Reporting structures present a chicken-and-egg problem. If Employee A reports to Manager B, and Manager B reports to Director C, you cannot assign Manager B as Employee A's manager until Manager B exists in HR Cloud with an assigned ID.

Pass 1: Insert core profiles. Create all employee records with demographic data, department assignments, and job titles. Leave the manager field null. HR Cloud supports bulk POST payloads as arrays, so you can batch the initial load.

// Pass 1: Create employee without manager
[
  {
    "firstName": "Jane",
    "lastName": "Smith",
    "email": "jane.smith@company.com",
    "hireDate": "2021-03-15",
    "xDepartmentLookup": "Engineering",
    "employmentStatus": "Active"
  }
]

Pass 2: Update reporting lines. Once all employees exist and have HR Cloud IDs, run a secondary PUT operation to update manager fields using xManagerLookup to xEmail as the resolution strategy:

PUT /v1/cloud/xEmployee?Identifier=xEmail&mapping=xManagerLookup to xEmail
// Pass 2: Update manager relationship
[
  {
    "xEmail": "jane.smith@company.com",
    "xManagerLookup": "director.jones@company.com"
  }
]

Step 6: Load History and Compensation

After core employee records exist, load in this order:

  1. Employment History records (status changes with effective dates)
  2. Position History records (role/title changes with effective dates)
  3. Salary History records — each compensation change as a separate record with effective date, in ascending chronological order per employee
  4. Bonus History records (if applicable)
  5. Rehire History records (if applicable)

Handling mid-year salary loads: For employees whose compensation changed mid-year, load every historical salary record with its original effective date. Do not consolidate. HR Cloud uses these records to determine current compensation display and reporting timelines.

As noted above: confirm with HR Cloud support before building history load scripts that your tenant supports programmatic history backfill. If it does not, the alternative approaches are: (1) HR Cloud professional services engagement for bulk history import, (2) manual entry for high-priority employees, or (3) archiving historical data as attached documents and loading only current-state compensation through the API.

Step 7: Migrate Time-Off and Leave Balances

Leave data is the most scrutinized part of any HRIS migration. Employees will notice immediately if their PTO balance is wrong by a single hour.

The recommended approach:

  1. Rebuild the leave policies (accrual rules, carryover limits, accrual frequencies) natively in HR Cloud.
  2. Extract the current, approved point-in-time balance for every employee from PeopleForce as of the cutover date.
  3. Load these balances into HR Cloud as a "Migration Adjustment" or initial balance entry — a single Time Off Accrual record per employee per leave type with the balance as of cutover.
  4. Archive historical, approved leave requests as read-only records or in a data warehouse.

Why not replay accrual history? The two systems calculate accruals differently — leap year handling, prorated months, carryover expiration windows, and rounding rules diverge. Replaying years of accrual math through HR Cloud's engine almost always produces discrepancies that require manual correction per employee. Loading the point-in-time balance is faster, more reliable, and easier to audit.

For mid-year migrations: Calculate the accrued-but-not-yet-processed balance separately from the already-approved balance. Load both components into HR Cloud to produce the correct starting balance without double-counting.

Step 8: Migrate Documents and Attachments

PeopleForce stores documents on employee profiles — contracts, signed documents via PeopleSign, compliance forms. PeopleForce provides signed download URLs via the API. These URLs expire quickly after generation.

The extraction script must:

  1. Call the PeopleForce API to get document metadata and the signed download URL.
  2. Immediately download the binary file to a secure, encrypted staging location.
  3. Upload to HR Cloud via multipart/form-data request to /xEmployee/:id/attachments.
  4. Verify the upload responded with 200/201 before scrubbing the local copy.
Danger

Never log signed URLs or download PII-laden documents to an unencrypted drive. Ensure your staging environment is SOC 2 compliant and that binary files are scrubbed immediately after the HR Cloud upload is confirmed successful.

For legacy PeopleForce forms, approval chains, and preboarding workflow state: HR Cloud's form API is retrieval-focused, not a general form-creation or import surface. Archive legacy forms as PDF attachments. Future onboarding and HR workflows get rebuilt natively in HR Cloud.

Step 9: Delta Sync and Cutover

A migration of this scale takes weeks. By the time you finish loading, source data in PeopleForce will have changed — new PTO requests, promotions, address updates.

Build your migration scripts to support a delta sync:

  1. Record the updated_at timestamp of your initial extraction.
  2. During the cutover window, query PeopleForce using the updated_at filter for records modified since that timestamp.
  3. Apply changes to HR Cloud using PUT or PATCH requests.
GET /api/public/v3/employees?status=all&updated_at[gte]=2026-08-20T00:00:00Z&page=1

PeopleForce webhooks can also provide real-time change capture during the cutover window. A full-pull-plus-delta-sync pattern is safer than a one-time export taken days before go-live.

Step 10: Validate

  • Compare total employee counts: PeopleForce export vs. HR Cloud
  • Spot-check 10–15% of records across departments, including at least 3–5 terminated employees
  • Verify manager reporting chains are intact (check at least 2 levels deep)
  • Confirm salary history timelines match source data — verify both current value and number of historical records per employee
  • Validate leave balances against PeopleForce export (per-employee, not just aggregate)
  • Test document attachment downloads for a sample of employees
  • Compare counts by status, department, and location

Edge Cases and Failure Modes

These are the issues that cause silent data corruption in HRIS migrations—a risk that scales with complexity, as seen in enterprise moves like SuccessFactors to Workday.

Compensation History Flattening

PeopleForce stores multiple compensation records per employee with effective dates. If your extraction only pulls the current compensation value (common when using the employee list endpoint rather than the compensations sub-endpoint), you lose the salary change timeline. HR Cloud's Salary History entity expects the full sequence. Always call GET /v2/employees/{id}/compensations explicitly — never infer compensation history from the employee object alone.

Custom Table Data Loss

PeopleForce's custom tables (training records, certifications, equipment assignments) have no direct equivalent in HR Cloud unless you've pre-configured matching custom fields or use HR Cloud's Assets module for equipment. Map each custom table to a specific HR Cloud feature before migration — or accept the data will need to live in attached documents or an external archive. There is no generic "import custom table" path in HR Cloud.

Terminated Employee Handling

PeopleForce retains terminated employee records with full history. If you migrate terminated employees, load them with terminationDate populated and include their full employment history. Skipping terminated employees can break compliance audit trails. Skipping terminationDate on terminated records causes them to display as active in HR Cloud. Decide on terminated employee scope before building extraction scripts — this is a binary choice, not a cleanup task.

Email as Identifier

HR Cloud uses email as a key identifier for employees. If an employee's email address is not specified in an import record, the system will create a duplicate employee record. Ensure every employee record has a unique, populated email. For extra safety, reconcile by employee number + email + hire date, not email alone — shared email addresses occur in family businesses and contractor setups.

Timezone and Date Format Mismatches

PeopleForce often stores dates in UTC. HR Cloud may interpret timezone-naive dates differently depending on tenant configuration. A one-day offset on hire dates or termination dates has real compliance implications — off-by-one on a termination date can affect final paycheck timing, benefits continuation, and COBRA eligibility windows. Validate date handling with explicit test cases in your sandbox before running production loads.

Job Architecture Flattening

PeopleForce Job Profiles carry levels, skills, custom profile data, and effective-dated assignment history. HR Cloud's xPosition model doesn't support this richness natively. Use the decision framework in the Job Architecture section above to make explicit choices before UAT — do not leave this to the validation phase.

HR Cloud Schema Inconsistencies

The public HR Cloud docs contain inconsistencies that will break production transforms if taken at face value. Known examples:

  • xAddress appears in one PUT example but the employee object overview lists xAddress1 and xAddress2
  • xCountry is described as a number in one location and shown as a case-sensitive string (e.g., India) in another

Always validate against GET /v1/Meta/xEmployee for your specific tenant and submit a sandbox payload to confirm field behavior before writing production transforms. The help center is a starting point, not a source of truth.

HR Cloud History Write Confirmation

Before finalizing your migration plan, get written answers from HR Cloud to these specific questions:

  1. Does your tenant support API-based writes to Salary History, Position History, and Employment History?
  2. What is the exact endpoint URL and required payload schema for each history entity write?
  3. Are bulk array writes supported for history entities, or must each record be submitted individually?
  4. What is the API throughput limit for your tenant?

If the answer to (1) is "not via API," your options are HR Cloud professional services for bulk import, manual entry, or archiving history as documents.

Compliance: Moving Employee PII Between Platforms

PeopleForce serves European clients with strong GDPR compliance. HR Cloud is US-based. If you're moving EU employee data into a US-hosted platform, account for:

  • Data Processing Agreements (DPAs) with both vendors — obtain and review before any data extraction begins
  • Transfer mechanisms — Standard Contractual Clauses (SCCs) or adequacy decisions must be in place before cross-border transfer
  • Data minimization — only migrate PII that HR Cloud actually needs for active HR operations
  • Right to erasure — ensure you can delete migrated data from both systems post-cutover; test this before go-live
  • Consent records — if any data was collected under consent rather than legitimate interest, verify the consent scope covers the new processor

Treat migration credentials as production secrets. Create migration-specific API accounts with the smallest workable permission scope. Rotate or disable them immediately after cutover is confirmed. Do not use your personal admin credentials for automated extraction scripts.

For a deep dive on GDPR and CCPA compliance during HR data migrations, see How to Safely Migrate Sensitive Employee & Payroll Data.

Recruiting Data: Handle Separately

PeopleForce's PeopleRecruit module stores candidates, vacancies, and application pipelines with customizable pipeline stages per vacancy. HR Cloud's Applicant entity is simpler — linked to Job records with basic status tracking. The data models don't map 1:1 and the pipeline stage metadata from PeopleForce has no direct equivalent in HR Cloud.

If you're actively recruiting during migration, run both systems in parallel for the recruiting module and only migrate historical applicant data once hiring pipelines settle. Migrating mid-pipeline candidates between ATS systems almost always results in lost interview notes, stage history, and evaluator feedback — this is contextual data that doesn't fit in structured fields.

For more on ATS migration pitfalls, see 5 "Gotchas" in ATS Migration.

Migration Timeline Estimate

Phase Duration Key Dependencies
Data audit & field mapping 3–5 days Access to both systems; HR Cloud history write confirmation
Reference data load 1–2 days HR Cloud admin access
Extraction script development 3–5 days PeopleForce API key (Professional tier)
Transformation logic 3–7 days Complexity of custom fields, tables, job architecture decisions
Pre-load validation 1–2 days Transformed dataset complete
Test load (sandbox) 2–3 days HR Cloud sandbox environment
Validation & reconciliation 2–3 days Stakeholder review
Production cutover 1 day Scheduled maintenance window
Post-migration validation 2–3 days Parallel access to both systems
Total ~3–5 weeks

Complex migrations with heavy custom table data, document attachments, unresolved history write mechanics, and recruiting pipelines can push this to 6–8 weeks.

When to Bring in a Migration Partner

Handle in-house if:

  • Employee count is under ~200
  • Minimal custom fields/tables; no custom table data in scope
  • No requirement to migrate compensation history
  • Engineering resources with REST API integration experience are available
  • Single jurisdiction (no EU → US data transfer complexity)

Bring in help if:

  • 500+ employees with complex history data
  • Custom tables, documents, and recruiting data are in scope
  • HR Cloud history write API behavior is unconfirmed and requires professional services engagement
  • You need zero-downtime cutover with parallel validation
  • Your team doesn't have bandwidth to build, test, and debug extraction and load scripts
  • You're crossing jurisdictional boundaries (EU → US) and need compliance guidance

At ClonePartner, we've handled HRIS migrations across dozens of source and target platform combinations. Our typical PeopleForce extraction includes full API-based extraction with history preservation, custom table mapping, and document migration — delivered in days, not weeks. If this migration is on your roadmap, we're happy to scope it.

Frequently Asked Questions

Can I use CSV exports to migrate from PeopleForce to HR Cloud?
CSV works for small, current-state employee moves with no history requirements. PeopleForce CSV exports produce flat snapshots that drop compensation change history, custom table data, document attachments, leave request approval chains, and relational IDs. For any migration involving history, documents, or more than ~50 employees, the PeopleForce REST API is the only viable extraction path.
How do I handle reporting lines when migrating to HR Cloud?
Use a two-pass load strategy. First, create all employee records with basic demographic and job data, leaving the manager field null. Once all records exist in HR Cloud, run a second PUT operation to update manager relationships. HR Cloud's PUT /xEmployee supports xManagerLookup to xEmail mapping for clean resolution.
How long does a PeopleForce to HR Cloud migration take?
A typical migration takes 3–4 weeks including data audit, field mapping, script development, test loads, validation, and production cutover. Complex migrations with heavy custom tables, document attachments, and recruiting data can extend to 5–6 weeks.
Does HR Cloud auto-create departments during CSV import?
Yes. If an employee record references a department that doesn't exist in HR Cloud, the system automatically creates it. This can lead to duplicate or misspelled reference data if your CSV isn't perfectly clean. Load reference data separately via API or validated CSV before importing employees.
Can HR Cloud load historical compensation data from PeopleForce?
HR Cloud has dedicated Salary History endpoints, but the public documentation is clearer on reading history than writing historical backfills. Current-state compensation is straightforward, but programmatic historical backfill may be tenant-specific. Get written confirmation from HR Cloud before promising full salary history reconstruction.

More from our Blog