---
title: "IntelliHR to Oracle Fusion Cloud HCM Migration: Technical Guide"
slug: intellihr-to-oracle-fusion-cloud-hcm-migration-technical-guide
date: 2026-07-30
author: Abdul
categories: [Migration Guide]
excerpt: "A technical guide for migrating from IntelliHR to Oracle Fusion Cloud HCM, covering API constraints, HDL loading, data mapping, and the edge cases that break HRIS migrations."
tldr: "Extract via IntelliHR REST API (250 req/60s), transform to Oracle HDL pipe-delimited .dat files, and load in dependency order. API-to-HDL is the only viable enterprise path."
canonical: https://clonepartner.com/blog/intellihr-to-oracle-fusion-cloud-hcm-migration-technical-guide/
---

# IntelliHR to Oracle Fusion Cloud HCM Migration: Technical Guide


# IntelliHR to Oracle Fusion Cloud HCM Migration: Technical Guide

Migrating from IntelliHR (now part of the Humanforce platform) to Oracle Fusion Cloud HCM is a data-model translation problem, not a spreadsheet copy job. IntelliHR uses a flat, people-centric model — `Person` and `Job` records connected by a simple parent-child relationship with date-effective job history. Oracle Fusion Cloud HCM uses a deeply hierarchical, enterprise-grade object model built around `Worker`, `WorkRelationship`, `WorkTerms`, `Assignment`, `Position`, and `Organization` business objects, each with its own effective-dating rules and strict referential integrity constraints.

If you need a fast decision: **IntelliHR's CSV exports give you flat snapshots, but they cannot preserve relational context or custom field metadata.** The only full-fidelity path at any real scale is API-based extraction from IntelliHR's REST API combined with Oracle HCM Data Loader (HDL) `.dat` files for bulk ingestion. HDL is the sanctioned bulk-load mechanism for Oracle HCM Cloud — Oracle's own REST docs explicitly say to use HDL and HCM Extracts for bulk operations, not the workers REST resource. ([docs.oracle.com](https://docs.oracle.com/en/cloud/saas/human-resources/farws/api-workers.html?utm_source=openai))

This guide covers every viable migration method, real API constraints on both sides, object-by-object mapping, and the edge cases that cause silent data corruption in HRIS migrations.

For a broader HRIS migration framework, see [The Ultimate HRIS Data Migration Checklist](https://clonepartner.com/blog/blog/hris-data-migration-checklist/). If you're handling sensitive payroll data, review [How to Safely Migrate Sensitive Employee & Payroll Data](https://clonepartner.com/blog/blog/payroll-data-migration-security-compliance/).

## IntelliHR vs Oracle Fusion Cloud HCM: Core Architecture Differences

**IntelliHR** is a people-analytics-focused HRIS designed for mid-market organizations. Its data model is deliberately simple: a `Person` record holds identity and contact data, while `Job` records attached to that person track positions, remuneration, business units, and locations. Custom fields extend both objects. The platform emphasizes workflows, onboarding, performance management, and analytics — not payroll processing or deep org-structure modeling. Native export is CSV-based and covers People Data, Job Data, Job Remuneration Data, Location Configuration, Business Unit Configuration, Training Data, and Qualifications. ([help.humanforce.com](https://help.humanforce.com/hc/en-au/articles/8534421806607-Export-Using-the-Data-Import-Export-Tool))

**Oracle Fusion Cloud HCM** is an enterprise human capital management suite. Its `Worker` business object alone spans five hierarchy levels — from the Worker component at the top to Assignment Work Measure, Assignment Manager, Assignment Grade Steps, and Assignment Extra Information at the bottom. Every record is effective-dated, and the system enforces strict referential integrity against foundation data (Legal Employers, Business Units, Departments, Locations, Jobs, Positions, Grades). Oracle's new-hire HDL pattern requires Worker, PersonName, WorkRelationship, WorkTerms, and Assignment components at minimum. ([docs.oracle.com](https://docs.oracle.com/en/cloud/saas/human-resources/fahdl/business-object-structure.html))

| Dimension | IntelliHR | Oracle Fusion Cloud HCM |
|---|---|---|
| **Data model** | Flat: Person → Job | Hierarchical: Worker → Work Relationship → Work Terms → Assignment |
| **Effective dating** | Date-effective jobs | Date-effective across all objects |
| **Custom data** | Custom fields on Person and Job | Extensible Flexfields (EFF), Descriptive Flexfields (DFF) |
| **Org structure** | Business Entities, Business Units, Locations | Legal Employer → Business Unit → Department → Location (strict hierarchy) |
| **API style** | REST, JSON, API key auth | REST + SOAP + HDL (.dat files) |
| **Bulk operations** | CSV Import/Export tool | HCM Data Loader (HDL) with .dat files in .zip archives |

### Why Companies Migrate

- **Enterprise consolidation**: Organizations scaling beyond IntelliHR's mid-market sweet spot need Oracle HCM's payroll, benefits, and workforce management modules in a single platform.
- **Compliance requirements**: Oracle HCM's legislative data groups, localization packs, and audit trails satisfy regulatory requirements (SOX, country-specific labor law reporting) IntelliHR was not designed to handle.
- **Integration ecosystem**: Oracle HCM integrates natively with Oracle ERP, EPM, and EBS — critical for organizations already running Oracle's finance stack.
- **Org complexity**: Multi-legal-employer structures, global assignments, and matrix reporting hierarchies exceed IntelliHR's modeling capabilities.

> [!WARNING]
> Decide early whether remuneration, recruiting, learning, documents, and user provisioning are in scope. Oracle handles these through different business objects, loaders, and module boundaries. That separation shows up directly in Oracle's endpoint and business-object structure.

## Migration Approaches: Every Viable Method Compared

### 1. Native CSV Export → HDL/HSDL Import

**How it works:** Export data from IntelliHR using its Data Import/Export tool or Analytics CSV exports. Transform the CSV files into Oracle HDL `.dat` format (pipe-delimited, with METADATA and MERGE instructions). Package as `.zip` and upload via Oracle's Data Exchange UI. For simple single-object loads, Oracle's HCM Spreadsheet Data Loader (HSDL) can process Excel-based templates — but HSDL loads one object per spreadsheet and expects Oracle lookup codes rather than display meanings. ([help.humanforce.com](https://help.humanforce.com/hc/en-au/articles/8534421806607-Export-Using-the-Data-Import-Export-Tool))

**When to use it:** Small datasets under 500 employees, one-time migration, no engineering team available.

**Pros:**
- No code required
- IntelliHR's export tool handles People, Jobs, and Remuneration data
- HDL templates are well-documented by Oracle

**Cons:**
- CSV exports flatten relational data — you lose the Person → Job → Remuneration hierarchy
- Manual transformation to `.dat` format is error-prone
- No attachment or document migration path
- Custom field mapping requires manual header-to-flexfield alignment
- HSDL is single-object and not attachment-friendly

**Scalability:** Small only. Manual transformation breaks down beyond ~500 records.

**Complexity:** Medium

### 2. API-Based Migration (IntelliHR REST → Oracle HDL)

**How it works:** Extract data programmatically via IntelliHR's REST API (`https://api.intellihr.io/v1/`). Transform JSON responses into HDL `.dat` file format. Upload `.dat` files to Oracle WebCenter Content and trigger HDL processing via the `dataLoadDataSets` REST resource or SOAP web service. ([developers.intellihr.io](https://developers.intellihr.io/?utm_source=openai))

**When to use it:** Any migration over 500 employees, when you need full relational fidelity, or when custom fields and attachments matter.

**Pros:**
- Full access to People, Jobs, Locations, Business Units, Training, Qualifications, and Custom Fields
- Preserves relational context (Person → Job chains)
- Supports incremental extraction via filters and pagination
- Repeatable and idempotent with source keys

**Cons:**
- IntelliHR API is rate-limited to 250 requests per 60 seconds (can be increased via Account Manager)
- Oracle HDL `.dat` file formatting is strict — wrong delimiters or missing METADATA lines cause silent failures
- Requires engineering effort to build and maintain the pipeline
- REST-to-REST writes to Oracle are not Oracle's preferred bulk path — worker create or update calls can take minutes due to post-processing

**Throughput estimate:** At 250 requests per 60 seconds with 100 records per page, extracting 10,000 person records requires ~100 API calls — roughly 25 seconds of request time plus network latency. Adding jobs, locations, and business units brings total extraction for a 10,000-worker org to approximately 5–10 minutes. HDL loading time varies by Oracle pod and load, but a 5,000-worker `.dat` file typically processes in 20–60 minutes depending on the number of components per worker and concurrent system load.

**Scalability:** Enterprise-grade. Pagination and batching handle large datasets.

**Complexity:** High

### 3. iPaaS / Middleware Platforms (Workato, Boomi, MuleSoft, Oracle Integration)

**How it works:** Use a pre-built or custom connector for IntelliHR and Oracle HCM Cloud. Configure extraction flows, field mapping, and transformation rules in the iPaaS designer. Oracle's own low-code option is Oracle Integration with the HCM Cloud Adapter, which supports CRUD against HCM resources, Atom feed subscriptions, file transfer to WebCenter, and HDL bulk import. ([docs.oracle.com](https://docs.oracle.com/en/cloud/paas/application-integration/hcm-adapter/using-oracle-hcm-cloud-adapter-oracle-integration-3.pdf?utm_source=openai))

**When to use it:** Organizations already licensed on an iPaaS platform, ongoing sync requirements, or when the migration is one phase of a larger integration project.

**Pros:**
- Visual mapping reduces development time
- Pre-built Oracle HCM connectors handle HDL formatting
- Error handling and retry logic are built in
- Supports ongoing sync after initial migration

**Cons:**
- IntelliHR connectors are not universally available — may require custom connector development
- iPaaS licensing adds cost
- Complex transformation logic (mapping IntelliHR's flat org model to Oracle's legal employer hierarchy) still requires custom scripting
- No connector removes the need for field mapping and hierarchy design

**Scalability:** Enterprise-grade with proper configuration.

**Complexity:** Medium

### 4. Custom ETL Pipeline

**How it works:** Build a dedicated pipeline using Python, Node.js, or a data engineering framework. Extract from IntelliHR API, transform using custom business logic, generate HDL `.dat` files plus `BlobFiles` or `ClobFiles` when needed, upload to Oracle WebCenter Content, then trigger and monitor the data set via HDL. Oracle recommends source keys over user keys because user-facing identifiers can change. ([docs.oracle.com](https://docs.oracle.com/en/cloud/saas/human-resources/25c/tutorial-hdl-load-files/index.html))

**When to use it:** Complex transformations, heavy custom field mapping, multi-source migrations (e.g., merging IntelliHR + payroll system into Oracle HCM), or when you need full control over error handling and logging.

**Pros:**
- Complete control over transformation logic
- Can handle edge cases that iPaaS tools cannot
- Reusable for future migrations or data corrections
- Highest fidelity and best control over retries, logging, and reconciliation

**Cons:**
- Highest engineering investment
- Must handle IntelliHR API pagination, rate limits, and error recovery
- Must generate valid HDL `.dat` format with correct METADATA lines, source keys, and file discriminators
- Ongoing maintenance burden

**Scalability:** Unlimited with proper architecture.

**Complexity:** High

### 5. Middleware Sync (Zapier, Make)

**How it works:** Use low-code HTTP orchestration to move events and small data sets between endpoints. A trigger in IntelliHR (e.g., "New Person") creates a record in Oracle.

**When to use it:** Only for downstream notifications, new-hire deltas, or post-cutover coexistence syncs. Not for first-load worker history. Oracle's bulk path is HDL, and these tools cannot handle effective dating, hierarchical record construction, or attachment migration.

**Pros:** Quick workflow assembly for simple triggers.

**Cons:**
- Shallow transaction control and limited file handling
- API timeout errors and payload size limits
- Cannot handle historical, relational data loads
- Partial failures and hidden drift

**Scalability:** Small ongoing syncs only.

**Complexity:** Low

### Migration Approach Comparison

| Method | Complexity | Scalability | Relational Fidelity | Custom Fields | Attachments | Best For |
|---|---|---|---|---|---|---|
| CSV Export → HDL/HSDL | Medium | Small (<500) | Low | Partial | No | Quick one-time loads |
| API → HDL | High | Enterprise | High | Full | Possible | Full-fidelity migrations |
| iPaaS | Medium | Enterprise | Medium–High | Full | Depends on connector | Ongoing sync + migration |
| Custom ETL → HDL | High | Unlimited | High | Full | Yes | Complex multi-source migrations |
| Middleware Sync | Low | Small ongoing | Low | Limited | No | Post-cutover deltas only |

### Scenario-Based Recommendations

- **< 500 employees, standard fields, no attachments**: CSV Export → HDL. Budget a day for transformation.
- **500–5,000 employees, active org with custom fields**: API-based migration or managed service.
- **5,000+ employees, multi-entity, ongoing sync needed**: iPaaS with custom connectors or managed service with continuous sync.
- **Low engineering bandwidth, any size**: Managed migration service (defined below).
- **One-time migration with rehearsals needed**: Custom ETL — repeatable dry runs matter.
- **Ongoing sync post-cutover**: Oracle Integration or equivalent with Atom feeds, HCM Extracts, and targeted APIs. ([docs.oracle.com](https://docs.oracle.com/en/cloud/saas/human-resources/fahdl/hcm-data-loader-and-implementation-scenarios.html?utm_source=openai))

## When NOT to Build In-House

DIY HRIS migrations fail in predictable ways:

- **Broken org hierarchies**: IntelliHR's flat Business Entity → Business Unit model doesn't map 1:1 to Oracle's Legal Employer → Business Unit → Department chain. Skipping a level silently breaks reporting lines.
- **Orphaned job records**: IntelliHR allows Jobs without full org-structure context. Oracle HCM's Worker.dat rejects records missing required Legal Employer or Assignment references.
- **Effective-date collisions**: Loading historical job changes without proper date sequencing creates overlapping effective-dated records that corrupt the Worker timeline.
- **The WorkTerms trap**: Oracle's HDL new-hire pattern requires a WorkTerms link record between WorkRelationship and Assignment. It's easy to overlook, but without it the entire logical object fails validation. The HDL log will show an error like `The work terms record is required` or simply reject the Worker object without loading any of its components. ([docs.oracle.com](https://docs.oracle.com/en/cloud/saas/tutorial-hdl-create-new-hires/))
- **Hidden engineering cost**: What looks like a 2-week project becomes 6–8 weeks when you account for HDL formatting, error debugging, UAT cycles, and rollback testing.

The hidden cost isn't HTTP code. It's crosswalk design, source-key strategy, target lookup alignment, security setup, WebCenter staging, reconciliation, UAT, and rollback planning. Oracle even exposes View Business Objects as the data dictionary for what can be loaded and which objects support rollback. ([docs.oracle.com](https://docs.oracle.com/en/cloud/saas/human-resources/25c/tutorial-hdl-load-files/index.html))

### What a Managed Migration Service Includes

A managed migration service for IntelliHR-to-Oracle HCM typically covers:

- **Source data audit and gap analysis** — inventory of IntelliHR objects, custom fields, and data quality issues before extraction begins
- **Org hierarchy reconstruction** — mapping IntelliHR's flat structure to Oracle's legal entity model, including creating the Legal Employer → Business Unit → Department crosswalk
- **Custom field translation** — IntelliHR custom fields to Oracle Descriptive Flexfields (DFF) or Extensible Flexfields (EFF), including flexfield configuration recommendations
- **Historical job data sequencing** — loading effective-dated job history in correct chronological order to preserve the Worker timeline without overlaps or gaps
- **HDL file generation and validation** — producing `.dat` files with correct METADATA lines, source keys, and file discriminators
- **Record-count reconciliation and field-level validation** — automated comparison between source extraction counts, HDL input counts, and Oracle HCM loaded counts
- **Tested rollback procedures** — DELETE `.dat` files verified in the test environment before go-live
- **Migration executed without disrupting active HR operations** — phased loads during off-peak hours with monitoring

## Pre-Migration Planning

### Data Audit Checklist

Before extracting anything, inventory what exists in IntelliHR:

| Object | What to Audit | Action |
|---|---|---|
| **People** | Active, inactive, terminated — total counts per status | Decide which statuses to migrate |
| **Jobs** | Current and historical job records per person | Determine historical depth to migrate |
| **Business Entities** | Legal entities and their structure | Map to Oracle Legal Employers |
| **Business Units** | Departments and teams | Map to Oracle Business Units/Departments |
| **Locations** | Physical office locations | Map to Oracle Locations |
| **Custom Fields** | Person-level and Job-level custom fields | Map to Oracle flexfields (see DFF vs. EFF below) |
| **Training Records** | Qualifications and training completions | Decide if migrating to Oracle Learning |
| **Documents/Attachments** | Uploaded files per person — total count and total size | Assess volume and migration path |
| **Performance Data** | Goals, reviews, check-ins | Map to Oracle Performance Management |
| **Onboarding Workflows** | Active workflow templates | Rebuild manually in Oracle |

### Define Migration Scope

- **Historical depth**: Do you need 10 years of job history or just current active records? Oracle HCM can load historical data, but every effective-dated row increases complexity. Bring as little historical baggage as compliance allows.
- **Terminated employees**: Required for compliance or audit? Load as terminated workers with proper end dates.
- **Custom fields**: Which are actively used vs. stale? Only migrate fields with business value.
- **Remuneration**: Clarify what belongs in Oracle HCM vs. a separate payroll workstream.

### Migration Strategy

- **Big bang**: All data migrated in a single cutover window. Works for <1,000 employees. Requires tested rollback plan.
- **Phased**: Foundation data first (Locations, Departments, Jobs, Positions), then Workers, then historical data. Reduces risk but extends timeline.
- **Incremental**: Initial load followed by delta syncs until cutover. Required when both systems must run in parallel during transition. Oracle positions HDL for periodic uploads and uses HCM Extracts or Atom feeds for delta detection.

> [!TIP]
> Always load Oracle HCM foundation data first. Legal Employers, Business Units, Departments, Locations, Jobs, and Grades **must** exist before loading Workers. HDL will reject Worker.dat records that reference non-existent foundation objects.

## Data Model & Object Mapping

This is where IntelliHR-to-Oracle migrations get complex. The two platforms think about employee data in fundamentally different ways.

The highest-risk translation: an IntelliHR Job is a person-held role record, but Oracle splits employment across WorkRelationship, WorkTerms, Assignment, and often a separately managed Job catalog. In Oracle's HDL new-hire pattern, WorkRelationship carries the legal employer, WorkTerms exists as a required link record, and Assignment carries the business unit and job reference. If you map IntelliHR Job directly to Oracle Job and stop there, you create structurally incomplete workers. ([developers.intellihr.io](https://developers.intellihr.io/?utm_source=openai))

### Object-Level Mapping

| IntelliHR Object | Oracle Fusion Cloud HCM Object | Notes |
|---|---|---|
| Person | Worker (Person component) | 1:1 mapping; PersonName, PersonAddress, PersonEmail are child components |
| Job | Assignment (under Work Relationship → Employment Terms) | Requires WorkRelationship and WorkTerms wrappers |
| Business Entity | Legal Employer | Must be pre-configured in Oracle HCM; cannot be loaded via HDL |
| Business Unit | Business Unit / Department | Oracle separates these — Business Units are org-level, Departments are assignment-level |
| Location | Location | Direct mapping; loaded via Location.dat |
| Pay Grade / Remuneration | Grade / Salary | Oracle uses Grade → Grade Rate; Salary is a separate business object |
| Custom Fields (Person) | Person DFF / EFF | Must configure flexfield segments in Oracle before loading |
| Custom Fields (Job) | Assignment DFF / EFF | Same — configure first, load second |
| Training Records | Learning Record (Oracle Learning) | Different module; may require separate migration |
| Qualifications | Person Qualification | Loaded via Worker.dat PersonQualification component |
| Documents / Attachments | Document of Record / Attached Documents | Separate upload process; not part of Worker.dat |
| Diary Notes | Person Note | Loaded via Worker.dat PersonNote component |

### DFF vs. EFF: When to Use Which

This decision trips up every IntelliHR migration. Oracle offers two flexfield mechanisms, and choosing wrong means reconfiguring mid-project:

- **Descriptive Flexfields (DFF)**: Use when you have a fixed set of additional attributes on an existing object. Example: a single "Employee T-Shirt Size" field on the Person object. DFFs are simpler to configure, support context-sensitive segments, and are available on most HCM business objects. They have a fixed number of available segments (typically 20–30 per context).
- **Extensible Flexfields (EFF)**: Use when you need repeatable rows of structured data or when you've exhausted DFF segments. Example: multiple certification records, each with a certification name, date, and expiry. EFFs support multiple rows per record and can be extended without limit, but they require more configuration effort (category, page, and usage registration) and are only available on specific business objects.
- **Decision rule**: If the IntelliHR custom field is a single-value attribute (one value per person or per job), map to a DFF. If it's a repeating set of related attributes (e.g., multiple qualifications with sub-fields), map to an EFF. If you're unsure, start with DFF — it's simpler, and you can always migrate to EFF later.

Both DFF and EFF segments must be configured and **deployed** in Oracle before HDL can load data into them. This is a setup step performed in the Setup and Maintenance work area, not a data loading step.

### Field-Level Mapping

| IntelliHR Field | Oracle HCM Field | Oracle Component | Transformation |
|---|---|---|---|
| `firstName` | `FirstName` | PersonName | Direct |
| `lastName` | `LastName` | PersonName | Direct |
| `displayName` | `DisplayName` | PersonName | Direct |
| `dateOfBirth` | `DateOfBirth` | Person | Format: YYYY/MM/DD |
| `primaryEmailAddress` | `EmailAddress` | PersonEmail | Map `EmailType` = `W1` for work |
| `phoneNumber` | `PhoneNumber` | PersonPhone | Map `PhoneType` = `W1` for work |
| `address` | `AddressLine1`, `TownOrCity`, `PostalCode` | PersonAddress | Decompose; set `AddressType` = `HOME` |
| `employeeNumber` | `PersonNumber` | Worker | Use as source key; load only if not auto-generated |
| `startDate` | `LegalEmployerSeniorityDate` | WorkRelationship | Format: YYYY/MM/DD |
| `endDate` | `ActualTerminationDate` | WorkRelationship | Null if active |
| `jobTitle` | `BusinessTitle` | Assignment | Map to Job.dat reference or BusinessTitle |
| `businessUnit` | `BusinessUnitName` | Assignment | Must match pre-loaded Business Unit |
| `location` | `LocationCode` | Assignment | Must match pre-loaded Location |
| `employmentType` | `AssignmentCategory` | Assignment | Map: Full-Time → `FR`, Part-Time → `PR` (verify against your Oracle lookup — values vary by legislation) |
| `reportsTo` | `ManagerPersonNumber` | AssignmentManager | Requires manager loaded first |
| `baseSalary` | `SalaryAmount` | Salary | Requires linked Salary Basis |

> [!WARNING]
> Oracle HDL dates must use `YYYY/MM/DD` format. IntelliHR API returns ISO 8601 (`YYYY-MM-DD`). This single-character difference (`/` vs `-`) causes silent HDL import failures — the record is skipped with no inline error. Note: Oracle REST examples may use `yyyy-MM-dd`, but HDL `.dat` files require the slash-delimited format.

> [!TIP]
> **Source keys:** Carry IntelliHR's immutable `person.id` and `job.id` into Oracle as source-system identifiers via `SourceSystemId` and set `SourceSystemOwner` to a consistent value like `INTELLIHR`. Oracle recommends source keys over user keys because user-facing identifiers can change. This makes reruns idempotent and relationship rebuilding practical. ([docs.oracle.com](https://docs.oracle.com/en/cloud/saas/human-resources/25c/tutorial-hdl-load-files/index.html))

### Handling Effective Dating

Oracle Fusion is an effective-dated system. Every record requires an `EffectiveStartDate` and `EffectiveEndDate`. If an employee in IntelliHR had three title changes, you must generate three distinct Assignment rows in your Oracle HDL file. The dates must not overlap, and they must fall within the boundaries of the employee's Work Relationship dates.

IntelliHR stores current job state with a start date. If a person had multiple role changes, you get multiple Job records. Oracle HCM requires non-overlapping effective-dated Assignment records. Sort by date ascending, set `EffectiveEndDate` on each prior record to one day before the next record's start date, and leave the final (current) record's `EffectiveEndDate` as `4712/12/31` (Oracle's standard end-of-time value).

### Handling Custom Fields

Oracle HCM does not support arbitrary custom objects. It uses Descriptive Flexfields (DFFs) and Extensible Flexfields (EFFs) on existing business objects. You must pre-configure these Flexfield segments in Oracle — including deployment — before attempting to map IntelliHR custom data into them. This is a configuration step, not a data step, and typically requires an Oracle HCM functional consultant. Complex, nested custom data from IntelliHR may need to be flattened to fit Oracle's Flexfield structure. See the DFF vs. EFF decision rule above.

### Required Oracle HCM Roles for HDL

Before starting any data load, ensure the migration service account has these Oracle HCM security roles:

- **Human Capital Management Integration Specialist** — required to submit and monitor HDL data sets
- **IT Security Manager** — required to configure security profiles if loading workers across multiple business units
- **Application Implementation Consultant** — required to access Setup and Maintenance for flexfield configuration

These roles must be assigned before the first test load. Missing role assignments cause access-denied errors that present as generic HDL failures without clear error messages.

## Migration Architecture

### Data Flow

```
IntelliHR REST API → JSON → Transform (Python/Node) → .dat files → .zip → Oracle WebCenter Content → HDL Processing → Oracle HCM Tables
```

### IntelliHR API Extraction

IntelliHR's REST API is organized around these key endpoints:

- `GET /v1/people` — All person records with contact details
- `GET /v1/jobs` — All job records with org, location, and remuneration
- `GET /v1/business-units` — Organizational units
- `GET /v1/locations` — Physical locations
- `GET /v1/trainings` — Training records
- `GET /v1/qualifications` — Qualification instances

**Authentication:** Bearer token (API key). Generated in IntelliHR Settings → API Keys. API tokens have full system administrator access with no permission scoping — treat extraction credentials as highly sensitive. ([developers.intellihr.io](https://developers.intellihr.io/?utm_source=openai))

**Rate Limits:** 250 requests per 60 seconds per tenant. Response headers `X-RateLimit-Remaining` and `X-RateLimit-Reset` track usage. HTTP 429 returned when exceeded.

**Pagination:** Supports `limit` and `page` query parameters. Maximum `limit` value is 100 per request. Iterate until no more pages are returned.

### Oracle HCM Data Loader (HDL)

HDL is Oracle's bulk data loading tool for HCM Cloud. Key constraints:

- **File format:** Pipe-delimited `.dat` files packaged in `.zip` archives
- **File naming:** Case-sensitive. `Worker.dat`, `Job.dat`, `Location.dat`, etc.
- **File size:** Documented as 2GB, but practical limits may be under 1GB in some environments — test with your specific Oracle pod
- **MERGE instruction:** Creates records if they don't exist, updates if they do
- **Source keys:** Strongly recommended for all records — enables re-running loads safely without creating duplicates
- **Foundation data must exist first:** Legal Employers, Business Units, Departments, Locations, Jobs, Grades must be loaded before Worker.dat
- **Staging tables:** Data imports to staging first, then loads to application tables. Default retention is 60 days but configurable — check the `Configure HCM Data Loader` page in Setup and Maintenance before starting
- **Logical object validation:** Oracle validates whole business objects together. If any component fails, the entire logical object is rejected

**HDL Automation via REST:**

The `dataLoadDataSets` REST resource supports:
- `uploadFile` (POST) — Upload Base64-encoded files (small files only; practical limit ~50MB before timeout)
- `createFileDataSet` (POST) — Trigger HDL processing for pre-uploaded files
- `getDataSets` (GET) — Monitor progress and status

For larger files, upload via WebCenter Content SOAP service (`GenericSoapPort`), then trigger HDL via REST.

## Step-by-Step Migration Process

### Step 1: Extract Foundation Data from IntelliHR

Extract Locations, Business Units, and organizational structure first. Then extract transactional data: People, Jobs, and Compensation.

```python
import requests
import time

BASE_URL = "https://api.intellihr.io/v1"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY"}  # Replace with actual key

def extract_paginated(endpoint):
    """Extract all records from a paginated IntelliHR endpoint.
    
    Note: Actual field names in responses should be verified against
    the IntelliHR API documentation for your tenant version.
    """
    results = []
    page = 1
    while True:
        resp = requests.get(
            f"{BASE_URL}/{endpoint}",
            headers=HEADERS,
            params={"page": page, "limit": 100}
        )
        if resp.status_code == 429:
            reset_after = int(resp.headers.get("X-RateLimit-Reset", 5))
            time.sleep(reset_after)
            continue
        resp.raise_for_status()
        data = resp.json()
        results.extend(data.get("data", []))
        if not data.get("links", {}).get("next"):
            break
        page += 1
    return results

locations = extract_paginated("locations")
business_units = extract_paginated("business-units")
people = extract_paginated("people")
jobs = extract_paginated("jobs")
```

### Step 2: Transform to HDL .dat Format

Generate Location.dat first, then Worker.dat. Each `.dat` file needs METADATA header lines defining the columns for each component.

**Important:** The field names below (e.g., `loc ['code']`, `person ['firstName']`) are illustrative placeholders. Verify actual field names against IntelliHR's API response schema for your tenant. The `LegislationCode` and `AssignmentStatusTypeCode` values must match your Oracle HCM configuration — do not use hardcoded values without verifying against your target environment's lookup tables.

```python
def convert_date(iso_date):
    """Convert ISO 8601 date (YYYY-MM-DD) to HDL format (YYYY/MM/DD).
    Returns None if input is None or empty."""
    if not iso_date:
        return None
    return iso_date.replace("-", "/")

def generate_location_dat(locations):
    lines = []
    lines.append("METADATA|Location|SourceSystemOwner|SourceSystemId|"
                 "LocationCode|LocationName|EffectiveStartDate|ActiveStatus")
    for loc in locations:
        eff_date = convert_date(loc.get("createdAt", "2020-01-01"))
        lines.append(
            f"MERGE|Location|INTELLIHR|LOC_{loc['id']}|"
            f"{loc['code']}|{loc['name']}|{eff_date}|A"
        )
    return "\n".join(lines)

def generate_worker_dat(people, jobs, legislation_code, legal_employer_name):
    """Generate Worker.dat HDL content.
    
    Args:
        people: List of person records from IntelliHR API
        jobs: List of job records from IntelliHR API
        legislation_code: Target Oracle legislation code (e.g., 'US', 'AU', 'GB')
        legal_employer_name: Name of Legal Employer as configured in Oracle HCM
    """
    lines = []
    # METADATA for each component in the Worker hierarchy
    lines.append("METADATA|Worker|SourceSystemOwner|SourceSystemId|"
                 "EffectiveStartDate|PersonNumber")
    lines.append("METADATA|PersonName|SourceSystemOwner|SourceSystemId|"
                 "EffectiveStartDate|LegislationCode|NameType|FirstName|LastName")
    lines.append("METADATA|WorkRelationship|SourceSystemOwner|SourceSystemId|"
                 "LegalEmployerName|WorkerType|StartDate")
    lines.append("METADATA|WorkTerms|SourceSystemOwner|SourceSystemId|"
                 "EffectiveStartDate|AssignmentStatusTypeCode")
    lines.append("METADATA|Assignment|SourceSystemOwner|SourceSystemId|"
                 "EffectiveStartDate|AssignmentStatusTypeCode|BusinessTitle|LocationCode")

    for person in people:
        person_jobs = [j for j in jobs if j.get("personId") == person["id"]]
        start = convert_date(
            person_jobs[0]["startDate"] if person_jobs else "2020-01-01"
        )

        lines.append(f"MERGE|Worker|INTELLIHR|PER_{person['id']}|"
                     f"{start}|{person.get('employeeNumber','')}")
        lines.append(f"MERGE|PersonName|INTELLIHR|PN_{person['id']}|"
                     f"{start}|{legislation_code}|GLOBAL|"
                     f"{person['firstName']}|{person['lastName']}")

        if person_jobs:
            job = person_jobs[0]  # Current/primary job
            job_start = convert_date(job["startDate"])
            lines.append(f"MERGE|WorkRelationship|INTELLIHR|WR_{person['id']}|"
                         f"{legal_employer_name}|E|{job_start}")
            lines.append(f"MERGE|WorkTerms|INTELLIHR|WT_{person['id']}|"
                         f"{job_start}|ACTIVE_PROCESS")
            lines.append(f"MERGE|Assignment|INTELLIHR|ASG_{person['id']}|"
                         f"{job_start}|ACTIVE|{job.get('title','')}|"
                         f"{job.get('locationCode','')}")

    return "\n".join(lines)
```

### Step 3: Load into Oracle HCM

Package `.dat` files into a `.zip` archive. Upload to Oracle WebCenter Content, then trigger HDL processing. Load files in the correct dependency order — Organization and Location data must be processed and validated before Worker.dat.

```python
import base64

def upload_and_trigger_hdl(zip_file_path, oracle_base_url, auth):
    with open(zip_file_path, "rb") as f:
        encoded = base64.b64encode(f.read()).decode()

    # Upload file
    upload_resp = requests.post(
        f"{oracle_base_url}/hcmRestApi/resources/latest/dataLoadDataSets",
        auth=auth,
        json={
            "ContentType": "application/zip",
            "FileName": "intellihr_migration.zip",
            "FileContent": encoded
        }
    )
    upload_resp.raise_for_status()

    # Monitor status
    dataset_id = upload_resp.json().get("DataSetId")
    while True:
        status = requests.get(
            f"{oracle_base_url}/hcmRestApi/resources/latest/"
            f"dataLoadDataSets/{dataset_id}",
            auth=auth
        ).json()
        load_status = status.get("LoadStatus")
        if load_status in ["COMPLETED", "COMPLETED_WITH_ERRORS", "ERROR"]:
            break
        time.sleep(30)
    
    if load_status == "COMPLETED_WITH_ERRORS":
        # Download error report - see "Inspecting HDL Errors" below
        print(f"Load completed with errors. Check dataset {dataset_id}")
    
    return status
```

### Step 4: Rebuild Relationships

Manager hierarchies must be loaded after all workers exist. Generate a second Worker.dat containing only AssignmentManager components:

```
METADATA|AssignmentManager|SourceSystemOwner|SourceSystemId|EffectiveStartDate|ManagerPersonNumber|ManagerAssignmentNumber|ManagerType
MERGE|AssignmentManager|INTELLIHR|MGR_001|2024/01/01|EMP-002|E-002|LINE_MANAGER
```

### Step 5: Validate Data

Run record-count comparisons and field-level spot checks against the source data. Always check both Import Status and Load Status separately — HDL can succeed at import (file accepted into staging) but fail at load (records rejected during application table commit).

## Inspecting HDL Errors

When an HDL load completes with errors, follow this procedure:

1. **Navigate to Data Exchange**: In Oracle HCM, go to **Navigator → Tools → Data Exchange → Import and Load Data**
2. **Find your data set**: Search by Data Set ID or file name. Open the data set.
3. **Check two status columns**: 
   - **Import Status** — did the file parse correctly into staging tables? Failures here mean formatting issues (wrong delimiters, missing METADATA lines, incorrect column counts).
   - **Load Status** — did records commit to application tables? Failures here mean validation issues (missing foundation data references, duplicate keys, invalid lookup values).
4. **Download the error report**: Click on the data set, then download the **Error Report** (CSV format). This file contains one row per failed record with columns including `OBJECT_NAME`, `LINE_NUMBER`, `ERROR_CODE`, and `ERROR_MESSAGE`.
5. **Common error codes**:
   - `ORA-20001` — usually a missing required field or invalid lookup value
   - `PER_ALL_PEOPLE_F: UNIQUE_CONSTRAINT_VIOLATED` — duplicate PersonNumber
   - `The work terms record is required` — missing WorkTerms component
   - `Invalid reference` on a Location, Business Unit, or Department field — foundation data not loaded or name mismatch
6. **Staging table query** (for Oracle HCM administrators with database access): Query `HRC_LOADER_STAGE_ERRORS` for detailed per-line error information. Filter by `DATA_SET_ID` to isolate your load.

## Edge Cases & Challenges

### Duplicate Records

IntelliHR allows multiple person records with the same email address. Oracle HCM enforces unique PersonNumber but not unique email. Humanforce recommends checking existing people by `id`, `employeeNumber`, `primaryEmailAddress`, or `displayName` before create operations. Deduplication must happen during transformation, not after loading. ([help.humanforce.com](https://help.humanforce.com/hc/en-au/articles/8533500629519-Creating-People-and-Jobs-via-the-Public-API))

### Effective-Date Conflicts

If a person had three role changes in IntelliHR, you get three Job records with potentially overlapping context. Oracle HCM requires non-overlapping effective-dated Assignment records. Sort by date ascending, set `EffectiveEndDate` on each prior record to one day before the next record's start date, ensure no gaps or overlaps in the timeline, and set the final record's `EffectiveEndDate` to `4712/12/31`.

### Missing Foundation Data

IntelliHR may reference a location or business unit that doesn't exist in Oracle HCM. HDL will reject the **entire Worker record**, not just the invalid field. Pre-validate all foreign key references before generating Worker.dat.

### Multiple Active Roles

IntelliHR allows a person to hold more than one job at a point in time. In Oracle, that usually becomes multiple assignments under one work relationship, or, less commonly, multiple work relationships depending on legal-employer rules. Map this explicitly during transformation — each concurrent assignment needs its own unique `SourceSystemId` and must share the same `WorkRelationship` parent.

### Custom Fields Without Flexfield Configuration

IntelliHR custom fields cannot be loaded until the corresponding Oracle DFF or EFF segments are configured and deployed. This requires an Oracle HCM functional consultant — it's a setup step that must happen before data loading begins.

### Attachments and Documents

IntelliHR documents are downloadable via the API, but Oracle HCM handles document migration through Document Records of Worker — a separate upload process. Binary files cannot be included in `.dat` files. HSDL also excludes document-record attachments. Use HDL's `DocumentOfRecord` object or attachment REST endpoints, and ensure document types exist in the target first. ([docs.oracle.com](https://docs.oracle.com/en/cloud/saas/human-resources/fahdl/spreadsheet-data-loaders.html))

### Terminated Employees

Historical data for terminated employees must be loaded with their termination dates accurately reflected in the Work Relationship object (`ActualTerminationDate`). If this is missing or incorrect, they appear as active headcount. Also set `NotifiedTerminationDate` and `TerminationReason` if available from IntelliHR.

### Multi-Level Relationship Chains

Mapping a worker to a position, which maps to a department, which maps to a legal entity — if any link in this chain is missing in Oracle, the worker load fails. Oracle validates the full referential chain at import time.

### Data Residency and Export Compliance

IntelliHR data is hosted in Australia (Humanforce infrastructure). If your Oracle HCM Cloud pod is in a different region (US, EU, UK), verify that extracting personal data from IntelliHR and loading it into a different-region Oracle pod complies with your data processing agreements and applicable privacy regulations (Privacy Act 1988, GDPR if EU employees are in scope). This is a legal assessment, not a technical one, but it must happen before extraction begins.

## Limitations & Constraints

### IntelliHR Side

- **No bulk export API**: Every record is retrieved via paginated REST calls at 250 req/60s
- **No permission scoping on API tokens**: Any token grants full admin access — treat extraction credentials as highly sensitive
- **Limited historical data**: Performance review history and workflow completion data may not be fully accessible via API
- **Rate limit ceiling**: Even with an Account Manager increase, extraction throughput is bounded — plan extraction windows accordingly

### Oracle HCM Side

- **HDL file size**: Documented at 2GB but practical limits may be under 1GB in some environments
- **No true custom objects**: All extensions must use flexfields on existing business objects
- **Foundation data ordering**: Legal Employers, Business Units, Departments, Locations, Jobs, and Grades must exist before any Worker load
- **Staging table limits**: Configurable but default limits can block large loads — check the `Configure HCM Data Loader` page in Setup and Maintenance before starting
- **No easy rollback**: Once data is committed via HDL, rolling back requires issuing DELETE instructions in `.dat` files or manual deletion via the UI
- **REST API pagination**: GET responses are limited to 500 records per page for some endpoints

> [!CAUTION]
> Oracle HDL silently skips records that fail validation instead of aborting the entire load. Always compare your input record count against the HDL `Total Objects Loaded` count. A "successful" HDL load with 4,800 of 5,000 records loaded means 200 employees are missing from your system. Download the error report CSV from the data set to identify which records failed and why.

## Validation & Testing

### Record Count Reconciliation

| Object | IntelliHR Count | HDL Input Count | Oracle HCM Count | Status |
|---|---|---|---|---|
| People / Workers | X | X | Must match | ✅ / ❌ |
| Jobs / Assignments | X | X | Must match | ✅ / ❌ |
| Locations | X | X | Must match | ✅ / ❌ |
| Custom Field Values | X | X | Spot check 10% | ✅ / ❌ |

### Field-Level Validation

- Sample 5–10% of records across each object type
- Verify name, email, phone, start date, job title, location, manager
- Check effective dates are non-overlapping for each Worker's Assignment history
- Spot-check high-risk fields: base salary, National ID, manager assignments
- Include `SourceSystemId` fields in HDL so loader status screens expose source-side values for faster reconciliation
- Run Oracle HCM's built-in **Diagnostic Reports** for person records to catch structural inconsistencies (e.g., assignments without work terms)

### UAT Process

1. Load into Oracle HCM **test environment** first — never production
2. Have HR team verify 20–30 representative employee records manually, covering: active employees, terminated employees, employees with multiple job history records, employees with custom field values
3. Test reporting — run headcount, org chart, and compensation reports
4. Test downstream integrations — payroll, benefits, time and attendance
5. Run a second test load to validate rollback and re-load capability

### Rollback Planning

Oracle HDL supports DELETE instructions in `.dat` files. The syntax mirrors MERGE but uses DELETE as the instruction keyword. Example:

```
METADATA|Worker|SourceSystemOwner|SourceSystemId|EffectiveStartDate|PersonNumber
DELETE|Worker|INTELLIHR|PER_12345|2024/01/01|EMP-001
```

```
METADATA|WorkRelationship|SourceSystemOwner|SourceSystemId|LegalEmployerName|WorkerType|StartDate
DELETE|WorkRelationship|INTELLIHR|WR_12345|YOUR_LEGAL_EMPLOYER|E|2024/01/01
```

**Rollback procedure:**
1. Generate DELETE `.dat` files for every MERGE instruction applied. Script this as part of your transformation pipeline — don't create rollback files manually.
2. Delete in reverse dependency order: AssignmentManager → Assignment → WorkTerms → WorkRelationship → Worker → Location
3. Test the full rollback cycle in the test environment before go-live
4. Verify rollback by checking Oracle HCM record counts return to pre-migration state

Oracle exposes View Business Objects as the data dictionary for which objects support rollback — not all objects support DELETE via HDL. Verify your target objects are covered before relying on this mechanism.

## Post-Migration Tasks

- **Rebuild workflows**: IntelliHR onboarding workflows, approval chains, and notifications don't migrate. Rebuild in Oracle HCM's Transaction Design Studio.
- **Reconfigure integrations**: Any payroll, ATS, or LMS integrations pointing at IntelliHR must be redirected to Oracle HCM. Prefer HCM Extracts and Atom feeds for ongoing delta detection instead of worker-REST polling. ([docs.oracle.com](https://docs.oracle.com/en/cloud/saas/human-resources/farws/Working_with_Atom.html?utm_source=openai))
- **User training**: Oracle HCM's navigation and terminology differ significantly from IntelliHR. Budget dedicated training sessions, particularly around the work-relationship and assignment model — that's where post-cutover tickets concentrate.
- **Monitor for data drift**: Run weekly reconciliation reports for the first 30 days to catch any records that slipped through or were modified incorrectly.
- **Decommission IntelliHR**: Keep the IntelliHR instance read-only for 90 days post-migration for reference, then archive and terminate.
- **Recruiting endpoints**: If recruiting is in scope, validate Oracle Recruiting Cloud API availability separately; some recruiting endpoints may have limited support. For recruiting-specific migration patterns, see [Taleo to Oracle Recruiting Cloud Migration: The CTO's Technical Guide](https://clonepartner.com/blog/blog/taleo-to-oracle-recruiting-cloud-migration-the-ctos-technical-guide/).

## Best Practices

1. **Back up everything before extraction.** Export IntelliHR data via both API and CSV to have two independent copies.
2. **Run at least two test migrations** in Oracle HCM's test environment before touching production — one full rehearsal and one delta rehearsal.
3. **Load foundation data separately and validate** before loading Workers. Trying to load everything in one `.zip` makes debugging impossible.
4. **Use source keys on every record.** This makes re-running loads idempotent — HDL will update existing records instead of creating duplicates.
5. **Automate validation.** Write scripts that compare IntelliHR source counts against Oracle HCM loaded counts after every load.
6. **Document every transformation decision.** When you map IntelliHR's "Full-Time" to Oracle's `FR` assignment category, write it down. You'll need this during UAT disputes.
7. **Lock down the source.** Implement a hard freeze on IntelliHR data entry 48 hours before the final cutover.
8. **Plan for a parallel-run period.** Keep both systems operational for 1–2 pay cycles if payroll is in scope.
9. **Pre-create and validate lookup values**, document types, jobs, departments, business units, and locations before any worker load.
10. **Automate repeatable steps.** File shaping, ZIP creation, dataset submission, status polling, and reconciliation should be scripted — not manual.

## Making the Right Call

The IntelliHR-to-Oracle Fusion Cloud HCM migration is not a lift-and-shift. It's a data-model translation between a flat, people-analytics platform and a deeply hierarchical enterprise HCM suite. The technical risk concentrates in three areas: org hierarchy mapping, effective-date sequencing, and HDL formatting compliance.

If your team has Oracle HCM implementation experience and available engineering bandwidth, an API-based custom ETL pipeline gives you full control. If you lack Oracle HDL experience — and most mid-market teams making this jump don't — a managed migration service compresses the timeline and eliminates the risk of silent data loss from HDL formatting errors, missing foundation references, or effective-date conflicts.

Successful migrations are boring on go-live day. The hard work happens earlier: choosing source keys, sequencing reference data before workers, deciding where custom fields and documents belong, testing effective-dated history, and using HDL for what Oracle designed HDL to do.

> Planning an IntelliHR to Oracle Fusion Cloud HCM migration? ClonePartner handles the extraction, transformation, HDL formatting, and validation — so your team can focus on the Oracle HCM implementation itself. Book a 30-minute call with our migration engineers.
>
> [Talk to us](https://cal.com/clonepartner/meet?duration=30)

## Frequently asked questions

### How do I migrate data from IntelliHR to Oracle Fusion Cloud HCM?

Extract data via IntelliHR's REST API (People, Jobs, Locations, Business Units), transform JSON to Oracle HDL pipe-delimited .dat format, package as .zip, and load through Oracle's HCM Data Loader. Foundation data (Locations, Departments, Legal Employers) must be loaded before Workers.

### What are IntelliHR's API rate limits for data extraction?

IntelliHR's public API limits requests to 250 per 60 seconds per tenant. When exceeded, the API returns HTTP 429. You can request an increase through your IntelliHR Account Manager. Implement exponential backoff using the X-RateLimit-Reset response header.

### Can I use CSV exports instead of APIs for this migration?

Yes, for small tenants under 500 employees with standard fields. But CSV exports flatten relational data, and Oracle's HSDL is single-object per spreadsheet and not attachment-friendly. For history-heavy or document-heavy migrations, API-based extraction into HDL is the safer path.

### How do IntelliHR custom fields map to Oracle Fusion Cloud HCM?

Oracle HCM does not support custom objects. IntelliHR custom fields must be mapped to Oracle's Descriptive Flexfields (DFF) or Extensible Flexfields (EFF) on existing business objects. The flexfield segments must be configured and deployed in Oracle before data can be loaded.

### Should I use Oracle REST APIs or HCM Data Loader for bulk employee data?

Use HCM Data Loader. Oracle explicitly recommends HDL and HCM Extracts for bulk operations. Worker create or update calls via REST can take minutes due to post-processing and are not designed for high-volume loads.
