Oracle Cloud HCM Jobs API
Query jobs from Oracle Cloud HCM boards through one API with ?source=oracle — plus how Oracle's finder-string pagination really behaves.
Oracle Cloud HCM is the recruiting half of Oracle's HR suite, branded Candidate
Experience on the career sites it renders. It's what a large share of the
Fortune 500 runs hiring on, and it's one of the biggest sources in this dataset at
146,650 postings — a number that moves hourly, so read it from
/v1/meta rather than trusting this sentence. Every
customer gets its own *.oraclecloud.com host and its own site code, and the REST
API behind all of them is unauthenticated.
Try it#
curl -G https://api.hyperjobs.io/v1/jobs \
-H "Authorization: Bearer $HYPERJOBS_KEY" \
--data-urlencode "source=oracle" \
--data-urlencode "time_frame=7d" \
--data-urlencode "limit=2"{
"data": [
{
"id": "oracle:acmeglobal_43219",
"title": "Senior Financial Analyst",
"company": {
"slug": "acme-global",
"name": "Acme Global",
"domain": "acmeglobal.com",
"website": "https://acmeglobal.com",
"logo": "https://media.licdn.com/dms/image/…",
"industry": "Industrial Machinery",
"employee_count": 31000
},
"location": {
"remote": false,
"countries": ["United Arab Emirates"],
"cities": ["Dubai"],
"regions": null,
"raw": ["Dubai, United Arab Emirates"]
},
"employment_type": ["FULL_TIME"],
"work_arrangement": "On-site",
"seniority": null,
"salary": null,
"skills": ["ifrs", "financial modelling"],
"taxonomies": ["Finance"],
"apply_url": "https://acmeglobal.fa.em2.oraclecloud.com/hcmUI/CandidateExperience/en/sites/CX_1/job/43219",
"url": "https://acmeglobal.fa.em2.oraclecloud.com/hcmUI/CandidateExperience/en/sites/CX_1/job/43219",
"source": "oracle",
"posted_at": "2026-07-09T00:00:00.000Z",
"expires_at": "2026-09-01T00:00:00.000Z",
"updated_at": "2026-07-14T02:18:44.000Z"
}
],
"total": 2,
"limit": 2,
"offset": 0
}How Oracle Cloud boards actually work#
Two unauthenticated REST endpoints, list then detail:
# 1. List — thin, 200 per page
curl "https://<host>/hcmRestApi/resources/latest/recruitingCEJobRequisitions\
?onlyData=true&expand=requisitionList&finder=findReqs;siteNumber=CX_1,limit=200,offset=0"
# 2. Detail — where the real data is
curl "https://<host>/hcmRestApi/resources/latest/recruitingCEJobRequisitionDetails\
?expand=all&onlyData=true&finder=ById;Id=\"43219\",siteNumber=CX_1"limit and offset are not query parameters#
This is the thing that catches people. Oracle's pagination lives inside the
finder string, not alongside it:
finder=findReqs;siteNumber=CX_1,limit=200,offset=200Append &limit=200&offset=200 the way you would anywhere else and Oracle ignores
them, hands back the first page again, and returns 200 OK while doing it. A loop
written on that assumption spins forever on page one, or dedups itself down to 200
jobs and calls the board finished.
The list is thin, and on many tenants the description is simply absent#
The list gives you titles, ids and a primary location. On a lot of tenants it
ships an empty description, employment type and category, and the detail call
is the only place the real structured data exists: JobSchedule,
Category/JobFunction, RequisitionType, coordinates, StudyLevel, the
posting end date, and salary in flexfields.
So Oracle is an N+1, like Workday. We only pay it for postings we've never seen: the list reports the complete live key set first, so board diffing and expiry run off the cheap call, and only new requisitions get a detail fetch.
The description arrives in three pieces#
There's no single body field. You assemble it:
| Field | What it holds |
|---|---|
ShortDescriptionStr | The opening pitch |
ExternalResponsibilitiesStr | The responsibilities section |
ExternalQualificationsStr | The qualifications section |
Read only the first and you get an intro with no requirements, which looks like a populated field, so nothing alerts you.
The one structured skills field in enterprise ATS
Oracle's detail can carry a real skills[] taxonomy — Java, Python,
Terraform — as ground truth rather than prose mined out of a description. It
only appears on tenants that switched Oracle Recruiting's skills feature on,
which is rare, but it's the only structured skills field found across any of the
big enterprise platforms. Where it's absent, skills are
derived like everywhere else.
What bites you#
Requisition ids are only unique within a tenant
Oracle Ids are tenant-local. Key on the bare id and one company's requisition
silently overwrites another's. Ours is scoped by subdomain, which is why the ids
on this source read oracle:acmeglobal_43219.
A raw job URL is not a board. This one cost real money to learn. The careers
URL and a link to a single posting differ only by a /job/{id} suffix, so a
discovery run that stores whatever URL it found treats every requisition as its
own board. One import produced 5,244 Oracle "boards" for roughly 1,056 real
tenant sites. The board token has to be canonicalised down to host plus site code
before it's stored.
Salary flexfield prompts are employer-typed, and vary wildly. Oracle puts pay
in requisitionFlexFields, where the prompt is whatever the tenant's admin
named it: Salary Minimum, Base Salary Min, Salary Range Minimum,
Minimum Pay Rate, or one combined string like $148,000 - $186,000 annually.
Match one spelling and most tenants return nothing.
JobSchedule is null on roughly 58% of details. It's the reliable employment
signal when it's there. When it isn't, the answer is in ContractType, JobType,
or a flexfield the employer used instead.
Locations drop their country. PrimaryLocation is frequently city-only, with
the country sitting separately in PrimaryLocationCountry as an ISO-2 code. We
append it only when the display string doesn't already end in a country.
StudyLevel is messy free text. High School Graduate, Associate's Degree/College Diploma (±13 years), and a curly-quoted Bachelor's degree that won't match a
straight apostrophe.
Or use ours#
The fetch is two endpoints. The work is everything around them.
You get descriptions already assembled from their three fields, tenant-scoped ids
that stop one company's 43219 from clobbering another's, the country appended
from Oracle's own structured field, salary read across the flexfield prompt
spellings employers actually use, and the company
join — an Oracle board tells you a subdomain and a site
code, not who that is. Descriptions land on 92.9% of the Oracle rows we serve.
Oracle sits in the heavy refresh tier, attempted every third cycle rather than every hour, because the N+1 makes it expensive. A new posting can take several hours to appear and a removed one takes as long to reap; coverage is explicit about that, so don't build anything assuming uniform latency across sources.
Query it with ?source=oracle.
Quickstart · Pricing
Every source above normalises onto the same schema, with the hiring company already joined onto each posting.
Get an API key