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.
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/xEmployeeand 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 entities — Bonus 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) |
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.
PeopleForce REST API (Recommended)
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.
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:
- Pull the master list of all Employee IDs via paginated
GET /v2/employees. - For each employee, pull
compensations, position history, and leave requests from the per-employee sub-endpoints. - Pull custom table data per employee via
/employees/{id}/tables/{table_id}. - Store everything in a staging database (PostgreSQL works well) or structured JSON files before transformation.
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=1CSV/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 Core HR API (Recommended)
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 xEmailThis 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 |
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.
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.
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 | male → Male, female → Female (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 |
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:
- Departments — via CSV import or API
- Divisions — via CSV import or API
- Locations — via CSV import or API
- Positions — via CSV import or API
- Employment Status values — via HR Cloud admin configuration
- 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:
- Paginates through
GET /v2/employees(page size 50–100) to get all employee IDs - Calls
GET /v2/employees/{id}per employee for full profile + custom table data - Calls
GET /v2/employees/{id}/compensationsfor all compensation records — not just current - Extracts leave requests via
GET /v2/leave_requests - Downloads document metadata and signed URLs (download files immediately — signed URLs expire)
- 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 enums —
gender(male→Male),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:
- Employment History records (status changes with effective dates)
- Position History records (role/title changes with effective dates)
- Salary History records — each compensation change as a separate record with effective date, in ascending chronological order per employee
- Bonus History records (if applicable)
- 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:
- Rebuild the leave policies (accrual rules, carryover limits, accrual frequencies) natively in HR Cloud.
- Extract the current, approved point-in-time balance for every employee from PeopleForce as of the cutover date.
- Load these balances into HR Cloud as a "Migration Adjustment" or initial balance entry — a single
Time Off Accrualrecord per employee per leave type with the balance as of cutover. - 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:
- Call the PeopleForce API to get document metadata and the signed download URL.
- Immediately download the binary file to a secure, encrypted staging location.
- Upload to HR Cloud via
multipart/form-datarequest to/xEmployee/:id/attachments. - Verify the upload responded with 200/201 before scrubbing the local copy.
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:
- Record the
updated_attimestamp of your initial extraction. - During the cutover window, query PeopleForce using the
updated_atfilter for records modified since that timestamp. - Apply changes to HR Cloud using
PUTorPATCHrequests.
GET /api/public/v3/employees?status=all&updated_at[gte]=2026-08-20T00:00:00Z&page=1PeopleForce 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:
xAddressappears in onePUTexample but the employee object overview listsxAddress1andxAddress2xCountryis 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:
- Does your tenant support API-based writes to
Salary History,Position History, andEmployment History? - What is the exact endpoint URL and required payload schema for each history entity write?
- Are bulk array writes supported for history entities, or must each record be submitted individually?
- 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.