# Workday Jobs Scraper — Any Company, Salaries & Exact Dates (`angelrxdriguez/workday-jobs-scraper`) Actor

Jobs from any company's Workday careers site: type a company name or paste the URL. Salary ranges parsed from the description, exact posting date, job category, remote/hybrid, all locations. Gets past Workday's 2,000-job limit. Only-new-jobs mode.

- **URL**: https://apify.com/angelrxdriguez/workday-jobs-scraper.md
- **Developed by:** [Ángel Panadero Rodríguez](https://apify.com/angelrxdriguez) (community)
- **Categories:** Jobs
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.90 / 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 Jobs Scraper — Any Company, Salaries & Exact Dates

Get the jobs of **any company that hires through Workday** (NVIDIA, Adobe, Capital One, Salesforce,
Target, universities, hospitals…) as clean, structured data. Just type the company name, or paste its
careers URL (anything on `myworkdayjobs.com` or `myworkdaysite.com`). Each job includes:

- **Salary as numbers**: min, max, currency and period (year or hour), yearly figures and an
  approximate yearly amount in USD. Workday has no salary field: the pay range is read from the job
  description, as US pay-transparency laws require ("$159,200 - $301,600", "272,000 USD – 431,250 USD",
  "$20.82 - $37.48 per hour"). When a company lists one range per city, you get all of them in
  `salaryRanges`, each with its city.
- **Exact posting date** (`2026-11-06`), not Workday's "Posted 30+ Days Ago".
- **Job category**: the company's own job family (Engineering, Sales, Nursing, Finance…), on every job.
- **Every location**: main and additional locations, country and country code, remote / hybrid /
  on-site, full-time or part-time.
- **Requisition ID**, legal entity, the job and apply links, and the full **description** as plain
  text, Markdown or HTML.

### Why this scraper

- **By company name.** No need to hunt for the right `wd5.myworkdayjobs.com/...` address: type
  "Capital One" and it finds the careers site automatically. Companies with several public careers
  sites (e.g. students, experienced, a subsidiary) get all of them, without duplicates. If a name isn't
  found, paste the careers URL.
- **No 2,000-job limit.** Workday stops every search at 2,000 results. Big employers have more, so
  this scraper splits the search by category (or country, or time type) and gets **all** of them.
- **Salaries you can filter on.** *Only jobs with salary* and *Minimum yearly salary (USD)* work across
  hourly and yearly pay and across currencies. Bonuses, sign-on bonuses and shift differentials are
  ignored, so they never get mistaken for the salary.
- **Filters that save you money.** Keywords, country, location, remote / hybrid / on-site, full or
  part-time, category, title words, exclusions, posting date and salary. Jobs that don't match are
  skipped and **not charged**. Country, remote, time type and category are applied on Workday's side
  when the company offers that filter, so filtered runs are also faster.
- **Pay only for what's new.** Turn on *Only new jobs* and schedule the run: each run returns only the
  jobs you haven't received yet. Perfect for job alerts and hiring trackers.
- **Fast mode.** Turn off *Include full details* for title, location, category, approximate date and
  link at 20 jobs per request.
- **Compliant and reliable.** It uses the same public JSON that the careers site loads in your browser,
  reads each company's `robots.txt` and skips any careers site it disallows. Polite pace, slows down
  or stops on its own if Workday asks it to. No login, no cookies, no proxy needed.
- **No personal data.** Recruiters' e-mails and phone numbers are removed from descriptions by
  default, so your dataset stays GDPR-friendly.

### Use cases

- **Job seekers and job alerts**: new jobs at your target companies, every day, with pay.
- **Recruiters and sales teams**: which companies are hiring, for which roles, where.
- **Compensation benchmarking**: real pay ranges by role, level, city and company.
- **Job boards and aggregators**: a clean feed straight from employers' own careers sites.
- **Investors and analysts**: hiring as a growth signal, by department and country.

### Input

| Field | Description |
|---|---|
| `companies` | Company names (`"NVIDIA"`) and/or Workday careers URLs (home page, search with filters, or one job) |
| `keywords` | Searched with Workday's own search (title and description), one search per keyword |
| `countries`, `locations` | e.g. `US`, `Germany`; `Berlin`, `TX`, `Remote` |
| `workplaceTypes`, `timeTypes` | `remote`, `hybrid`, `onsite`; `full-time`, `part-time` |
| `jobCategories`, `titleMustContain`, `excludeTitleKeywords` | e.g. `Engineering`; `engineer`; `intern`, `senior` |
| `postedWithinDays` | Fresh jobs only (exact date) |
| `withSalaryOnly`, `minYearlySalaryUsd` | Pay filters |
| `includeDetails`, `descriptionFormat` | Full details (default) or fast mode; text, Markdown, HTML, all or none |
| `onlyNewJobs` + `stateKey` | Return only jobs not delivered before. One state key per scheduled task. |
| `maxItems`, `maxItemsPerCompany` | Caps per run and per company (0 = no limit) |

Example: data jobs in the US at three companies, posted in the last 7 days, paying at least $150,000
a year, new jobs only:

```json
{
  "companies": ["NVIDIA", "Capital One", "https://adobe.wd5.myworkdayjobs.com/external_experienced"],
  "keywords": ["data engineer", "data scientist"],
  "countries": ["US"],
  "postedWithinDays": 7,
  "minYearlySalaryUsd": 150000,
  "onlyNewJobs": true,
  "stateKey": "data-us"
}
```

### Output

```json
{
  "id": "adobe:Staff-Security-Data-Engineer_R171875-1",
  "jobId": "5d8f0278e5101000c2fce85aee6c0000",
  "jobReqId": "R171875",
  "url": "https://adobe.wd5.myworkdayjobs.com/external_experienced/job/San-Jose/Staff-Security-Data-Engineer_R171875-1",
  "applyUrl": "https://adobe.wd5.myworkdayjobs.com/external_experienced/job/San-Jose/Staff-Security-Data-Engineer_R171875-1/apply",
  "title": "Staff Security Data Engineer",
  "companyName": "Adobe",
  "legalEntity": "Adobe Inc.",
  "companyTenant": "adobe",
  "careerSite": "external_experienced",
  "careerSiteUrl": "https://adobe.wd5.myworkdayjobs.com/external_experienced",
  "jobCategory": "Engineering",
  "timeType": "full-time",
  "location": "San Jose",
  "additionalLocations": ["San Francisco"],
  "locationsCount": 2,
  "country": "United States",
  "countryCode": "US",
  "salaryText": "$159,200 - $301,600",
  "salaryMin": 159200,
  "salaryMax": 301600,
  "salaryCurrency": "USD",
  "salaryPeriod": "YEAR",
  "salaryYearlyMin": 159200,
  "salaryYearlyMax": 301600,
  "salaryYearlyUsdMin": 159200,
  "salaryYearlyUsdMax": 301600,
  "datePosted": "2026-09-28",
  "postedDaysAgo": 30,
  "postedOnText": "Posted 30+ Days Ago",
  "description": "Our Company. Changing the world through digital experiences is what Adobe's all about. ...",
  "searchKeyword": "data engineer",
  "scrapedAt": "2026-11-07T13:20:11Z"
}
```

Other fields when available: `workplaceType` and `remoteType` (remote / hybrid / on-site and the
company's own label), `employmentType`, `validThrough`, `salaryRanges` (one per city or level),
`salaryIsInferred` (period deduced from the amount) and `salaryLooksWrong` (implausible amount).

You can download the results as JSON, CSV, Excel or XML, or get them through the Apify API.

### FAQ

**My company isn't found by name.** Paste its careers URL instead: open the company's careers page,
click any job, and copy the address if it contains `myworkdayjobs.com` or `myworkdaysite.com`. If it
doesn't, the company doesn't use Workday for its public job postings.

**How accurate are the salaries?** They are what the employer wrote in the job description. Amounts in
other currencies are converted to `salaryYearlyUsdMin/Max` with fixed, approximate exchange rates, so
use those for comparing and filtering; the original amount and currency are always kept. Jobs whose
description has no pay range have no salary fields.

**How fast is it?** About 2-3 requests per second: one per job with full details, or one per 20 jobs
in fast mode. A company with 1,000 jobs takes about 7 minutes with full details.

**Is it legal?** The scraper collects publicly available job postings from employers' public careers
sites and respects each site's `robots.txt`. It does not log in. You are responsible for using the data
in line with the sites' terms and applicable law, such as GDPR. This Actor is not affiliated with or
endorsed by Workday, Inc. or any employer; Workday and the company names and logos belong to their
owners.

**Something is missing or broken?** Open an issue on the *Issues* tab. We read every issue and fix
problems as fast as we can.

# Actor input Schema

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

Company names (e.g. 'NVIDIA', 'Capital One') or Workday careers URLs (anything on myworkdayjobs.com or myworkdaysite.com: the careers home page, a search with filters, or a single job). Names are found automatically; if a name isn't found, paste its careers URL.

## `keywords` (type: `array`):

Optional. Searched on each careers site with Workday's own search (title and description), one search per keyword. Leave empty for all jobs.

## `maxItems` (type: `integer`):

Maximum number of jobs to return in total (0 = no limit).

## `countries` (type: `array`):

Country names or 2-letter codes (e.g. 'US', 'Germany', 'IN'). A job matches if its main or any additional location is in one of them.

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

Keep jobs whose location (any of them) contains one of these texts, e.g. 'Berlin', 'TX', 'Remote'.

## `workplaceTypes` (type: `array`):

Remote, hybrid or on-site, from the company's own label (Workday 'remote type' or location type), or from the location when the company doesn't label it.

## `timeTypes` (type: `array`):

Full-time or part-time.

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

Only jobs posted in the last N days (exact posting date, not Workday's '30+ days ago').

## `jobCategories` (type: `array`):

Keep jobs whose category (the company's own job family, e.g. 'Engineering', 'Sales', 'Nursing') contains one of these texts.

## `titleMustContain` (type: `array`):

Keep only jobs whose title contains at least one of these texts (stricter than 'Keywords', which also match the description).

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

Skip jobs whose title contains one of these words, e.g. 'intern', 'senior', 'manager'.

## `withSalaryOnly` (type: `boolean`):

Keep only jobs whose description states a pay range.

## `minYearlySalaryUsd` (type: `integer`):

Keep jobs whose top of the pay range, converted to yearly USD, is at least this much. Implies 'Only jobs with salary'.

## `includeDetails` (type: `boolean`):

Open each job to add the description, salary, exact posting date, all locations, country and legal entity. Turn off for a much faster run with title, location, category, approximate date and link only (20 jobs per request).

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

Plain text, Markdown (keeps headings, lists and bold), the original HTML, all three, or none.

## `maxItemsPerCompany` (type: `integer`):

Optional cap per company, so one big employer doesn't fill the whole run (0 = no limit).

## `removeContactData` (type: `boolean`):

Remove e-mail addresses and phone numbers from job descriptions, so you don't store recruiters' personal data (GDPR).

## `onlyNewJobs` (type: `boolean`):

Skip jobs already returned in previous runs that used the same 'State key'. The first run returns the current jobs; later runs only jobs posted since. Ideal for scheduled runs: you only pay for what's new.

## `stateKey` (type: `string`):

Name of the memory used by 'Only new jobs'. Use a different key for each scheduled task.

## `secondsBetweenRequests` (type: `number`):

Minimum pause between requests to Workday. The scraper slows down by itself if Workday asks it to.

## `proxyConfiguration` (type: `object`):

Not needed.

## Actor input object example

```json
{
  "companies": [
    "NVIDIA",
    "Adobe"
  ],
  "keywords": [
    "data engineer"
  ],
  "maxItems": 100,
  "withSalaryOnly": false,
  "includeDetails": true,
  "descriptionFormat": "text",
  "removeContactData": true,
  "onlyNewJobs": false,
  "stateKey": "default",
  "secondsBetweenRequests": 0.3,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All jobs returned by the run (title, company, category, locations, salary, exact posting date, description, apply link).

# 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": [
        "NVIDIA",
        "Adobe"
    ],
    "keywords": [
        "data engineer"
    ],
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("angelrxdriguez/workday-jobs-scraper").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": [
        "NVIDIA",
        "Adobe",
    ],
    "keywords": ["data engineer"],
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("angelrxdriguez/workday-jobs-scraper").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": [
    "NVIDIA",
    "Adobe"
  ],
  "keywords": [
    "data engineer"
  ],
  "maxItems": 100
}' |
apify call angelrxdriguez/workday-jobs-scraper --silent --output-dataset

```

## MCP server setup

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

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/2OWSN1KAgBfMPlkfU/builds/cuW6julQgDAa3p2zO/openapi.json
