Oracle HCM Cloud API Capabilities — REST, HDL, HCM Extracts, Payroll, Workers

Type: ERP Integration System: Oracle Fusion Cloud HCM (24B) Confidence: 0.85 Sources: 6 Verified: 2026-03-09 Freshness: 2026-03-09

TL;DR

System Profile

Oracle Fusion Cloud HCM is Oracle's SaaS human capital management suite. The REST API covers Core HR (workers, assignments, employment), Workforce Management, Compensation, Benefits, Talent, Learning, and Payroll (separate license). HDL handles bulk inbound via structured .dat files. HCM Extracts provide configurable outbound extraction. This card covers Oracle Fusion Cloud HCM only — not EBS HRMS, Taleo, or PeopleSoft.

PropertyValue
VendorOracle
SystemOracle Fusion Cloud HCM (Release 24B)
API SurfaceREST (primary), HDL (bulk inbound), HCM Extracts (bulk outbound), BIP (reports), SOAP (legacy)
Current API Version11.13.18.05 (resource version, stable across releases)
Editions CoveredEnterprise (single edition for cloud)
DeploymentCloud (Oracle Cloud Infrastructure)
API DocsOracle Fusion Cloud HCM REST API
StatusGA — quarterly feature releases

API Surfaces & Capabilities

API SurfaceProtocolBest ForMax Records/RequestRate LimitReal-time?Bulk?
REST APIHTTPS/JSONIndividual worker CRUD, queries500/pageFair-use ~60 req/s (429)YesNo
HDL (HCM Data Loader).dat files via REST or UCMBulk inbound: hires, mass updates250 MB/file20 threads/podNoYes
HCM ExtractsXML/CSV via UCM or FTPBulk outbound: scheduled feedsExtract-dependentESS schedulerNoYes
BI Publisher (BIP)HTTPS/XML or CSVReporting, ad-hoc extractionReport-dependentESS schedulerNoYes
SOAP Web ServicesHTTPS/XMLLegacy integrationsVariesShared with RESTYesNo
HCM Atom FeedsHTTPS/Atom XMLChange tracking, event-drivenN/AConfigurableYesN/A

Rate Limits & Quotas

Per-Request Limits

Limit TypeValueApplies ToNotes
Max records per REST page500REST API (all HCM resources)Default page size is 25; use limit param
Max HDL file size250 MB.dat file uploadSplit larger data sets into multiple files
Max concurrent HDL threads20Per podAll HDL imports share the thread pool
Max attachment size2 GBREST API attachmentsPer-file limit

Rolling / Daily Limits

Limit TypeValueWindowEdition Differences
REST API callsNo published hard limitFair-useDynamic throttling — ~60 req/s, returns 429
HDL import submissionsNo published hard limitPer podConcurrent up to 20 threads
HCM Extract runsNo published hard limitPer podSubject to ESS scheduler capacity

Authentication

FlowUse WhenToken LifetimeRefresh?Notes
OAuth 2.0 JWT BearerServer-to-server (recommended)3600 secondsNo (re-authenticate)Register in Oracle IDCS
OAuth 2.0 Client CredentialsAutomated batch processes3600 secondsNo (re-authenticate)Same IDCS registration
Basic Auth over SSLTesting onlySession-basedN/ANot recommended for production
SAML 2.0 Bearer TokenSSO-federated operationsSession timeoutN/ASAML assertion in HTTP header

Authentication Gotchas

Constraints

Integration Pattern Decision Tree

START — User needs to integrate with Oracle HCM Cloud
├── What's the data direction?
│   ├── Inbound (writing to HCM)
│   │   ├── Volume < 500 records? → REST API
│   │   │   ├── Hire → POST /workers
│   │   │   ├── Update assignment → PATCH /workers/{id}/child/assignments/{id}
│   │   │   └── Terminate → POST /workers/{id}/child/workRelationships/{id}/action/terminate
│   │   ├── Volume 500-50,000? → HDL (.dat file via hcmImportAndLoadData)
│   │   └── Volume > 50,000? → HDL — split into multiple files (<250 MB each)
│   ├── Outbound (reading from HCM)
│   │   ├── Real-time queries → REST API: GET /workers
│   │   ├── Scheduled bulk extraction → HCM Extracts
│   │   └── Change tracking → HCM Atom Feeds
│   └── Bidirectional → REST + HCM Extracts + HDL
├── Error tolerance?
│   ├── Zero-loss → HDL with error file download + reconciliation
│   └── Best-effort → REST with retry on 429/5xx

Quick Reference

ModuleResourceEndpoint PathOperationsNotes
Core HR — Workersworkers/hcmRestApi/resources/11.13.18.05/workersGET, POSTHire, query; child: assignments, names, emails
Core HR — Assignmentsassignments (child)/hcmRestApi/.../workers/{id}/child/assignmentsGET, PATCHEffective-dated
Compensation — Salarysalaries/hcmRestApi/resources/11.13.18.05/salariesGET, POST, PATCHIndividual salary management
Absenceabsences/hcmRestApi/resources/11.13.18.05/absencesGET, POST, PATCHLeave requests and balances
Payroll — RelationshipspayrollRelationships/hcmRestApi/resources/11.13.18.05/payrollRelationshipsGETRequires Payroll license
Payroll — Payslipspayslips/hcmRestApi/resources/11.13.18.05/payslipsGETRequires Payroll license
Talent — Goalsgoals/hcmRestApi/resources/11.13.18.05/goalsGET, POST, PATCHGoal management
LearninglearningRecordEnrollments/hcmRestApi/resources/11.13.18.05/learningRecordEnrollmentsGET, POSTTraining enrollment
HDL ImporthcmImportAndLoadData/hcmRestApi/resources/11.13.18.05/hcmImportAndLoadDataPOSTHDL file upload + import trigger
Atom FeedsatomFeeds/hcmRestApi/resources/11.13.18.05/atomFeeds/{feedId}GETChange tracking

Step-by-Step Integration Guide

1. Authenticate via OAuth 2.0 JWT Bearer

Register a Confidential Application in Oracle IDCS, obtain Client ID and Client Secret. [src6]

curl -X POST \
  "https://{identity-domain}.identity.oraclecloud.com/oauth2/v1/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -u "{client_id}:{client_secret}" \
  -d "grant_type=client_credentials&scope=urn:opc:resource:consumer::all"

Verify: Response contains "access_token" field and "expires_in": 3600

2. Query Workers via REST

Retrieve worker records with expanded child objects. [src1]

curl -X GET \
  "https://{host}.fa.{dc}.oraclecloud.com/hcmRestApi/resources/11.13.18.05/workers?q=PersonNumber=12345&expand=assignments,names,emails&onlyData=true" \
  -H "Authorization: Bearer {access_token}"

Verify: Response contains "items" array with worker details

3. Hire a New Worker via REST

POST with the required hierarchy: Person > WorkRelationship > Assignment. [src1]

curl -X POST \
  "https://{host}.fa.{dc}.oraclecloud.com/hcmRestApi/resources/11.13.18.05/workers" \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/vnd.oracle.adf.resourceitem+json" \
  -d '{ "names": [{"FirstName":"Jane","LastName":"Smith","LegislationCode":"US"}],
        "workRelationships": [{"LegalEmployerName":"US Legal Entity","WorkerType":"E",
        "StartDate":"2026-04-01","assignments":[{"BusinessUnitName":"US BU",
        "JobName":"Software Engineer","ActionCode":"HIRE"}]}] }'

Verify: Response HTTP 201 with PersonId populated

4. Upload HDL File for Bulk Import

Prepare .dat file, ZIP, base64-encode, upload via hcmImportAndLoadData. [src2]

curl -X POST \
  "https://{host}.fa.{dc}.oraclecloud.com/hcmRestApi/resources/11.13.18.05/hcmImportAndLoadData" \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/vnd.oracle.adf.resourceitem+json" \
  -d '{"ContentType":"zip","FileName":"Worker.zip","DocumentContent":"{base64_encoded_zip}"}'

Verify: Poll GET /hcmImportAndLoadData/{FlowId} until status = COMPLETED

Code Examples

Python: Hire Worker with Error Handling

# Input:  Oracle HCM host, OAuth token, hire data dict
# Output: Created PersonId or error details

import requests  # requests==2.31.0

def hire_worker(host, token, hire_data):
    url = f"https://{host}/hcmRestApi/resources/11.13.18.05/workers"
    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/vnd.oracle.adf.resourceitem+json"
    }
    resp = requests.post(url, headers=headers, json=hire_data)
    if resp.status_code == 201:
        return {"success": True, "person_id": resp.json().get("PersonId")}
    elif resp.status_code == 429:
        return {"success": False, "error": "throttled",
                "retry_after": resp.headers.get("Retry-After", "60")}
    else:
        return {"success": False, "status": resp.status_code, "detail": resp.text}

JavaScript/Node.js: Query Workers by Department

// Input:  Oracle host URL, OAuth token, department name
// Output: Array of worker objects

import fetch from 'node-fetch'; // [email protected]

async function getWorkersByDepartment(host, token, department) {
  const url = new URL(`https://${host}/hcmRestApi/resources/11.13.18.05/workers`);
  url.searchParams.set('q', `assignments.DepartmentName=${department}`);
  url.searchParams.set('expand', 'names,assignments,emails');
  url.searchParams.set('onlyData', 'true');
  url.searchParams.set('limit', '500');
  const resp = await fetch(url.toString(), {
    headers: { 'Authorization': `Bearer ${token}` }
  });
  if (!resp.ok) throw new Error(`Query failed: ${resp.status}`);
  return (await resp.json()).items || [];
}

cURL: Test Authentication

# Step 1: Get token
curl -s -X POST \
  "https://{idcs}.identity.oraclecloud.com/oauth2/v1/token" \
  -u "{client_id}:{client_secret}" \
  -d "grant_type=client_credentials&scope=urn:opc:resource:consumer::all" \
  | python -m json.tool

# Step 2: Test against workers endpoint
curl -s -X GET \
  "https://{host}.fa.{dc}.oraclecloud.com/hcmRestApi/resources/11.13.18.05/workers?limit=5&onlyData=true" \
  -H "Authorization: Bearer {access_token}" \
  | python -m json.tool

Data Mapping

HDL Worker Business Object — Key Fields

HDL ColumnFieldTypeRequiredNotes
PersonNumberPERSON_NUMBERStringYes (MERGE)Unique person identifier
DateOfBirthDATE_OF_BIRTHDateNoFormat: YYYY/MM/DD
LegislationCodeLEGISLATION_CODEStringYesCountry code (US, GB, DE)
LegalEmployerNameLEGAL_EMPLOYER_NAMEStringYesMust match configured legal employer
WorkerTypeWORKER_TYPEStringYesE=Employee, C=Contingent
ActionCodeACTION_CODEStringYesHIRE, REHIRE, TRANSFER, etc.

Data Type Gotchas

Error Handling & Failure Points

Common Error Codes

CodeMeaningCauseResolution
400Bad RequestInvalid payload, missing hierarchyCheck required fields and Person > WorkRelationship > Assignment structure
401UnauthorizedInvalid/expired tokenRe-authenticate via OAuth
403ForbiddenMissing HCM roles or Payroll licenseAssign HCM duty roles; verify Payroll license
404Not FoundInvalid endpoint or PersonIdVerify resource version (11.13.18.05)
409ConflictDuplicate PersonNumberCheck for existing records; retry with jitter
429Too Many RequestsFair-use throttling (~60 req/s)Exponential backoff with Retry-After header
500Internal Server ErrorTransient server issueRetry after 30-60 seconds
HDL-001Validation ErrorInvalid .dat formatValidate METADATA/MERGE/END structure

Failure Points in Production

Anti-Patterns

Wrong: Querying all workers one-at-a-time for change detection

# BAD — O(N) API calls; hits throttling quickly
for pid in all_person_ids:
    resp = requests.get(f"{base}/workers/{pid}", headers=headers)
    if resp.json()["LastUpdateDate"] > last_sync:
        process_change(resp.json())

Correct: Use HCM Atom Feeds for change detection

# GOOD — single feed request returns all changes
resp = requests.get(f"{base}/atomFeeds/workers?since={last_token}", headers=headers)
for entry in parse_atom(resp.text):
    process_change(entry)

Wrong: Using REST for mass compensation update

# BAD — 10,000 individual PATCH calls
for emp in employees:
    requests.patch(f"{base}/salaries/{emp['id']}", json={"Amount": emp["new"]}, headers=headers)

Correct: Use HDL for bulk compensation changes

# GOOD — single HDL file for any volume
buf = io.StringIO()
buf.write("METADATA|Salary|AssignmentNumber|SalaryAmount|DateFrom\n")
for emp in employees:
    buf.write(f"MERGE|Salary|{emp['asn']}|{emp['new']}|2026-04-01\n")
buf.write("END\n")
# ZIP, base64, upload via hcmImportAndLoadData

Common Pitfalls

Diagnostic Commands

# Test OAuth authentication
curl -s -X POST "https://{idcs}.identity.oraclecloud.com/oauth2/v1/token" \
  -u "{client_id}:{client_secret}" \
  -d "grant_type=client_credentials&scope=urn:opc:resource:consumer::all" | python -m json.tool

# Query first 5 workers (verify connectivity + HCM access)
curl -s -X GET "https://{host}.fa.{dc}.oraclecloud.com/hcmRestApi/resources/11.13.18.05/workers?limit=5&onlyData=true" \
  -H "Authorization: Bearer {token}" | python -m json.tool

# Check HDL import status
curl -s -X GET "https://{host}.fa.{dc}.oraclecloud.com/hcmRestApi/resources/11.13.18.05/hcmImportAndLoadData/{FlowId}" \
  -H "Authorization: Bearer {token}" | python -m json.tool

# Describe workers resource (field metadata)
curl -s -X GET "https://{host}.fa.{dc}.oraclecloud.com/hcmRestApi/resources/11.13.18.05/workers/describe" \
  -H "Authorization: Bearer {token}" | python -m json.tool

Version History & Compatibility

ReleaseRelease DateStatusKey ChangesMigration Notes
24B2024-07CurrentExpanded workers resource; enhanced HDL error reportingEvaluate new child objects
24A2024-01SupportedHCM Atom Feeds GA; new absence REST endpointsAtom Feeds replace polling
23D2023-10SupportedTalent management REST endpointsNew goals/performance resources
23B2023-04SupportedhcmImportAndLoadData REST endpointReplaces UCM-only HDL upload

When to Use / When Not to Use

Use WhenDon't Use WhenUse Instead
Real-time individual worker operations <500 recordsBulk imports >500 recordsHDL via hcmImportAndLoadData
Querying worker details, absencesMass compensation changes (annual review)HDL with Salary business object
Individual absence requestsScheduled outbound HR feedsHCM Extracts
Change detection for real-time syncFull HCM data migrationHDL with full business object set

Important Caveats

Related Units