All platforms

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.

?source=oraclesource reference

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#

BASH
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"
Illustrative — the shape, not a live response
{
  "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:

BASH
# 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=200

Append &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:

FieldWhat it holds
ShortDescriptionStrThe opening pitch
ExternalResponsibilitiesStrThe responsibilities section
ExternalQualificationsStrThe 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