# Workday, iCIMS and Oracle Jobs Scraper + 3 more (`djk12/company-jobs-workday-and-more`) Actor

Live job listings from company career pages on Workday, iCIMS, Oracle Recruiting, Personio, Teamtailor and BambooHR. One clean schema, filters, new-job tracking. No login.

- **URL**: https://apify.com/djk12/company-jobs-workday-and-more.md
- **Developed by:** [Dylan Knaup](https://apify.com/djk12) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.80 / 1,000 jobs

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Workday, iCIMS and Oracle Jobs Scraper (plus Personio, Teamtailor and BambooHR)

Get the current job openings of any company whose career page runs on **Workday, iCIMS, Oracle Recruiting (Oracle Fusion HCM), Personio, Teamtailor or BambooHR**, in one clean format, straight from the employer. No login, no cookies, no proxies.

Give it a list of companies, get back one row per open job with title, department, location, remote flag, publish date, apply link and the full description.

This Actor is the companion of *Company Jobs Scraper: Greenhouse, Lever, Ashby and more* (`company-jobs-multi-ats`). That one covers Greenhouse, Lever, Ashby, SmartRecruiters, Recruitee and Workable. This one covers the systems large employers use. The output format is the same, so you can use both in one pipeline.

### Why use this Actor

- **Straight from the employer.** Jobs are read live from the career page the company runs, and every row links to the company's own apply page. No LinkedIn or Indeed reposts.
- **Big employers.** Workday and Oracle Recruiting run the career sites of many large companies (NVIDIA, Salesforce, Mastercard, Pfizer, JPMorgan Chase and thousands more).
- **Complete boards.** Workday cuts every search at 2,000 rows. This Actor splits larger boards by job category, so a board with 2,675 jobs returns about 2,675 jobs, not 2,000.
- **One format for six systems.** Same fields for every job, so one parser is enough.
- **Pay only for jobs you get.** Pay per event: a tiny start fee plus a price per job in your dataset. Companies that cannot be found cost nothing.
- **Built for monitoring.** Switch on *Only jobs not seen in an earlier run*, put the Actor on a schedule, and every run returns only newly posted jobs.
- **Public data only.** The Actor calls the same public job listing interfaces the career pages themselves use. It does not log in, solve captchas or get around protections, and it collects job postings only, no personal data (contact names and e-mails that some systems attach to a posting are left out).

### How to use it

1. Open the **Input** tab and add companies. A career page link is the most reliable way:

   | System | Link looks like |
   |---|---|
   | Workday | `https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite` |
   | iCIMS | `https://careers-rambus.icims.com` |
   | Oracle Recruiting | `https://jpmc.fa.oraclecloud.com/hcmUI/CandidateExperience/en/sites/CX_1001` |
   | Personio | `https://360t.jobs.personio.de` |
   | Teamtailor | `https://polestar.teamtailor.com` |
   | BambooHR | `https://gitkraken.bamboohr.com/careers` |

   Short forms: `workday:nvidia.wd5/NVIDIAExternalCareerSite`, `oracle:jpmc.fa.oraclecloud.com/CX_1001`, `icims:careers-rambus`, `personio:360t`, `teamtailor:polestar`, `bamboohr:gitkraken`. Use them when the company's career page lives on its own domain but the jobs are hosted by one of these systems.
   A plain name such as `polestar` also works for Personio, Teamtailor and BambooHR: the Actor tries them in turn. Workday, Oracle and iCIMS need the link, because their addresses cannot be guessed from a name.
2. Optionally add filters (job title words, location, department, remote only, posted within N days).
3. Click **Start**. Download the results as JSON, CSV, Excel, XML or HTML, or read them through the API.

#### Input example

```json
{
    "companies": [
        "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
        "https://jpmc.fa.oraclecloud.com/hcmUI/CandidateExperience/en/sites/CX_1001",
        "personio:360t"
    ],
    "titleKeywords": ["engineer", "developer"],
    "excludeTitleKeywords": ["intern"],
    "locations": ["Germany", "Remote"],
    "postedWithinDays": 14,
    "maxJobsPerCompany": 100,
    "descriptionFormat": "text"
}
```

#### All input options

| Field | What it does |
|---|---|
| `companies` | Required. Career page links, `system:name` or plain names. |
| `titleKeywords` | Keep jobs whose title contains any of these words. |
| `excludeTitleKeywords` | Drop jobs whose title contains any of these words. |
| `locations` | Keep jobs whose location, city or country text contains any of these words. |
| `departments` | Keep jobs whose department or team contains any of these words (Workday: the job category). |
| `remoteOnly` | Keep only jobs the company flags as remote. |
| `postedWithinDays` | Keep jobs first published in the last N days. |
| `descriptionFormat` | `text` (default), `html`, `both` or `none`. |
| `fetchDetails` | Open every job page for the exact date and all locations (default on). Off is faster on large Workday boards, but then date and some locations stay empty unless a filter needs them. |
| `maxJobsPerCompany` | Newest jobs first where the system gives dates. Default 1000. |
| `maxJobsTotal` | Hard stop for the whole run. Default 5000. |
| `onlyNewSinceLastRun`, `stateStoreName` | New job tracking (see below). |
| `maxConcurrency` | Companies read in parallel (default 3). |

Word filters are not case sensitive and match anywhere in the text. Different filters combine with AND, words inside one filter with OR.

### Output

One dataset row per job, the same fields for every system (they are the fields of Company Jobs Scraper, plus `reqId` and `seniority`):

```json
{
    "id": "JR2026762",
    "ats": "workday",
    "company": "nvidia",
    "companyName": "nvidia",
    "title": "Test Reliability Engineer",
    "reqId": "JR2026762",
    "department": "Engineering",
    "employmentType": "Full-time",
    "location": "Israel, Yokneam",
    "locations": ["Israel, Yokneam"],
    "country": "Israel",
    "postedAt": "2026-11-02T00:00:00Z",
    "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/Israel-Yokneam/Test-Reliability-Engineer_JR2026762",
    "applyUrl": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/Israel-Yokneam/Test-Reliability-Engineer_JR2026762/apply",
    "description": "We are looking for a creative and independent ...",
    "scrapedAt": "2026-11-02T07:33:50Z"
}
```

A `RUN_SUMMARY` record in the run's key-value store lists, for every company you entered, which system was used, how many jobs were found, matched and returned, and the reason for any company that could not be read.

#### What each system provides

Empty means the company's system does not provide it, not that the Actor missed it.

| Field | Workday | Oracle | iCIMS | Personio | Teamtailor | BambooHR |
|---|---|---|---|---|---|---|
| Title, location, link, description | yes | yes | yes | yes | yes | yes |
| Publish date | yes (date) | yes | yes | yes | yes | yes |
| Department | job category | job family | category | yes | yes | yes |
| Team | no | no | no | recruiting category | division | no |
| Employment type | yes | sometimes | sometimes | yes | no | yes |
| Remote or hybrid | when the tenant uses it | sometimes | sometimes | no | yes | sometimes |
| Salary | no | no | no | no | no | when published |

### Track new jobs automatically

Turn on **Only jobs not seen in an earlier run**, choose a **Memory name**, and schedule the Actor. The first run returns every matching job and remembers them; later runs return only new ones, each with `isNew: true`. The memory lives in a key-value store in your own account. Use a new memory name for a new watch list.

### Pricing

Pay per event: a very small fee for starting the run plus a price for each job in your dataset. Companies that cannot be found, bad links and jobs removed by your filters are free. Set a **maximum cost per run** in the run options to cap spending; the Actor stops when it is reached. See the **Pricing** tab for the current price.

### Use it from code

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("<YOUR_USERNAME>/company-jobs-workday-and-more").call(run_input={
    "companies": ["https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"],
    "titleKeywords": ["data"],
    "postedWithinDays": 7,
})
for job in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(job["companyName"], job["title"], job["url"])
```

The Actor also works as a tool for AI agents through the Apify MCP server.

### FAQ

**How do I find a company's Workday link?** Open the company's careers page and click a job. A Workday address looks like `https://<company>.wd<number>.myworkdayjobs.com/<site>/...`. Copy everything up to the site name.

**Oracle: which link?** Open a job on the company's Oracle career site. The address contains `/hcmUI/CandidateExperience/.../sites/<site>`. Paste that address.

**What about Taleo, Jobvite, SuccessFactors, UKG?** Not supported in this version. Taleo and Jobvite are planned.

**Is it legal?** The Actor reads only the public job listing interfaces that these career sites use themselves. It collects job postings, not personal data, and does not log in anywhere. You are responsible for how you use the data; check the employer's terms and your local law, especially if you republish descriptions.

**A big Workday board takes minutes.** A board with 2,600 jobs needs about 140 requests for the list and one more per job returned. Use filters, `maxJobsPerCompany`, or turn off `fetchDetails` and `descriptionFormat` for the fastest run.

**A company shows "not-found".** The link is not the one the system uses, or the board has moved. Copy the link of a job's page.

**Can I get closed jobs?** No. Only jobs open at the time of the run.

### Support

Found a company that is read wrongly, or want another system added? Open an issue in the **Issues** tab with the career page link.

# Changelog

This Actor's version history is a separate document: https://apify.com/djk12/company-jobs-workday-and-more/changelog.md

# Actor input Schema

## `companies` (type: `array`):

One entry per company. Accepted: a career page link on Workday (<code>https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite</code>), iCIMS (<code>https://careers-rambus.icims.com</code>), Oracle Recruiting (<code>https://jpmc.fa.oraclecloud.com/hcmUI/CandidateExperience/en/sites/CX_1001</code>), Personio (<code>https://360t.jobs.personio.de</code>), Teamtailor (<code>https://polestar.teamtailor.com</code>) or BambooHR (<code>https://gitkraken.bamboohr.com/careers</code>); or <code>system:name</code> such as <code>personio:360t</code> or <code>workday:nvidia.wd5/NVIDIAExternalCareerSite</code>; or a plain name (the Actor then tries Personio, Teamtailor and BambooHR).

## `titleKeywords` (type: `array`):

Keep only jobs whose title contains at least one of these words (not case sensitive). Leave empty to keep all.

## `excludeTitleKeywords` (type: `array`):

Drop jobs whose title contains any of these words, for example <code>intern</code> or <code>director</code>.

## `locations` (type: `array`):

Keep only jobs whose location, city or country text contains one of these words, for example <code>Germany</code>, <code>London</code> or <code>Remote</code>.

## `departments` (type: `array`):

For example <code>Engineering</code> or <code>Sales</code>. On Workday this is the job category.

## `remoteOnly` (type: `boolean`):

Keep only jobs that the company marks as remote.

## `postedWithinDays` (type: `integer`):

Keep only jobs first published in the last N days. Jobs without a publish date are dropped when this is set.

## `descriptionFormat` (type: `string`):

Plain text is best for spreadsheets and AI tools. Choose HTML if you want to keep the original formatting. 'None' is fastest and gives the smallest output.

## `maxJobsPerCompany` (type: `integer`):

Newest jobs are kept first.

## `maxJobsTotal` (type: `integer`):

Hard stop for the whole run. Also set a maximum cost per run in the run options if you want a cost cap.

## `onlyNewSinceLastRun` (type: `boolean`):

Turn this on and schedule the Actor to get a feed of new postings. The first run returns every matching job and remembers them; later runs return only additions. Each row gets <code>isNew: true</code>. The memory is stored in your own account.

## `stateStoreName` (type: `string`):

Name of the key-value store that remembers which jobs were already reported. Use a different name for each separate watch list. Lowercase letters, digits and hyphens only.

## `maxConcurrency` (type: `integer`):

Lower this if you read many very large career pages and see memory errors.

## `fetchDetails` (type: `boolean`):

Workday, iCIMS and BambooHR give only a short list; the exact posting date and all locations are on the job page. On (default) the Actor opens each job it returns. Off is faster but those fields can stay empty (filters on location, remote or date still open pages when they need to).

## Actor input object example

```json
{
  "companies": [
    "workday:workday.wd5/Workday",
    "personio:360t",
    "teamtailor:polestar"
  ],
  "remoteOnly": false,
  "descriptionFormat": "text",
  "maxJobsPerCompany": 5,
  "maxJobsTotal": 30,
  "onlyNewSinceLastRun": false,
  "stateStoreName": "company-jobs-more-seen",
  "maxConcurrency": 3,
  "fetchDetails": true
}
```

# Actor output Schema

## `jobs` (type: `string`):

One row per job posting, in the same format for every ATS.

## `summary` (type: `string`):

Per-company report: which ATS was used, how many jobs were found and matched, and any company that could not be read.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "companies": [
        "workday:workday.wd5/Workday",
        "personio:360t",
        "teamtailor:polestar"
    ],
    "maxJobsPerCompany": 5,
    "maxJobsTotal": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("djk12/company-jobs-workday-and-more").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "companies": [
        "workday:workday.wd5/Workday",
        "personio:360t",
        "teamtailor:polestar",
    ],
    "maxJobsPerCompany": 5,
    "maxJobsTotal": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("djk12/company-jobs-workday-and-more").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "companies": [
    "workday:workday.wd5/Workday",
    "personio:360t",
    "teamtailor:polestar"
  ],
  "maxJobsPerCompany": 5,
  "maxJobsTotal": 30
}' |
apify call djk12/company-jobs-workday-and-more --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,djk12/company-jobs-workday-and-more"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/yx2Z3oSql8cKpLhWc/builds/JH4klbOylLcymrA8z/openapi.json
