# Workday Jobs Scraper & API: Any Company Career Site (`agentready/workday-jobs-scraper`) Actor

Get every open job from any company's Workday career site (myworkdayjobs.com) in one clean format, with full descriptions, locations, departments and pay ranges when published. Filter by keyword, location, remote and date, or get only new jobs since your last run.

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

## Pricing

from $0.72 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 & API: Any Company Career Site

Get **every open job from any company's Workday career site** (`*.myworkdayjobs.com`) in one clean, flat format. **Just type the company name** (e.g. `NVIDIA`) or paste its career-site URL. You get title, full description, locations, country, department, job type, posting date and **pay range when the posting states one**. Filter by keyword, location, remote and date, or turn on **"only new jobs"** to get just what was posted since your last run.

Thousands of large employers (NVIDIA, Salesforce, Adobe, Mastercard, Intel and many more) run their careers pages on Workday. This Actor reads the same public job data the career page shows in your browser. No login, no API key.

### Why this one

- **Type a company name, not a URL.** The Actor finds the company on Workday and reads every public career site it lists (some have one for students, one per brand, and so on). If a name isn't found, the run report says so and you can paste the URL instead.
- **Past Workday's 2,000-job limit.** Workday stops each search at 2,000 jobs. For bigger employers this Actor reads category by category, so you get the whole site, and the run report tells you if anything could still be missing.
- **Same format as our [ATS Jobs Actor](https://apify.com/agentready/greenhouse-lever-ashby-jobs)** for Greenhouse, Lever and Ashby. Combine both outputs without mapping fields.
- **Departments and pay ranges.** Every job gets its site category (e.g. "Engineering"). Pay is extracted only when the posting writes an explicit range, never guessed.
- **You pay only for jobs you get.** Filters on title and date are applied before a job is opened, and "only new jobs" never re-charges for jobs you already received.
- **Polite and rule-following.** Each site's robots.txt is checked first; sites that disallow it are skipped and reported.

### Quick start

All jobs from one company:

```json
{
  "careerSites": ["NVIDIA"]
}
```

A career-site URL works too: `"https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"`.

#### Daily feed of new jobs across several employers

Schedule this every morning. The first run returns everything that matches; after that only new jobs appear, and **you only pay for those**.

```json
{
  "careerSites": [
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
    "https://salesforce.wd12.myworkdayjobs.com/External_Career_Site"
  ],
  "keywords": ["machine learning", "data engineer"],
  "locations": ["United States", "Remote"],
  "postedWithinDays": 3,
  "onlyNewJobs": true,
  "monitoringList": "ml-roles"
}
```

**Company not found by name?** Paste its career-site URL instead: open the company's careers page, click through to its job search, and copy the address. It looks like `https://<company>.wd<N>.myworkdayjobs.com/<SiteName>`. A link to any single job on the site also works.

### Step-by-step tutorial

[Pull every job from any Workday career site](https://dev.to/wballztrading1/pull-every-job-from-any-workday-career-site-599h): from company name to a daily feed of new jobs, with a real NVIDIA record and pay range.

### Input

| Field | What it does |
| --- | --- |
| `careerSites` | Company names (`NVIDIA`, `Salesforce`) or Workday career-site URLs, up to 200 sites per run. |
| `keywords` / `excludeKeywords` | Whole-word match on the title ('AI' does not match 'maintain'). |
| `searchInDescription` | Also match keywords in the full description. |
| `locations` | Keep jobs whose location or country contains any of these. |
| `remoteOnly` | Only jobs marked remote. |
| `departments` | Only these job categories, e.g. `Engineering`. |
| `postedWithinDays` | Only jobs posted in the last N days (much faster). |
| `onlyNewJobs` / `monitoringList` | Output only jobs not returned in earlier runs under the same list name. |
| `descriptionFormat` | `text` (default), `html`, `both` or `none`. |
| `maxJobsPerCompany` / `maxResults` | Caps per site and in total. |

### Output

One record per job, always with the same fields. Missing values are `null`.

```json
{
  "id": "workday:nvidia/NVIDIAExternalCareerSite:Senior-Manager--Silicon-Speed-Productization---Silicon-Co-Design-Group_JR2026496",
  "ats": "workday",
  "companySlug": "nvidia/NVIDIAExternalCareerSite",
  "companyName": "Nvidia",
  "jobId": "JR2026496",
  "title": "Senior Manager, Silicon Speed Productization — Silicon Co-Design Group",
  "department": "Engineering",
  "team": null,
  "locations": ["US, CA, Santa Clara"],
  "country": "United States of America",
  "workplaceType": null,
  "isRemote": null,
  "employmentType": "Full time",
  "salary": { "min": 232000, "max": 368000, "currency": "USD", "interval": null, "summary": "The base salary range is 232,000 USD - 368,000 USD." },
  "seniority": "senior",
  "yearsExperienceMin": 12,
  "skills": [],
  "salaryYearlyMin": null,
  "salaryYearlyMax": null,
  "postedAt": "2026-09-29",
  "updatedAt": null,
  "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/US-CA-Santa-Clara/...",
  "applyUrl": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/US-CA-Santa-Clara/...",
  "description": "NVIDIA's Silicon Co-Design Group (SCG) sees every silicon program...",
  "descriptionHtml": null,
  "scrapedAt": "2026-09-29T12:00:00Z"
}
```

- `postedAt` is a date only; Workday doesn't publish a time.
- `workplaceType` is set only when the site says remote or hybrid in a location or remote field; text such as "#LI-Hybrid" in a description is not used.
- `salary.interval` is `hour` or `year` only when the posting says so.
- `seniority`, `yearsExperienceMin` and `skills` come only from what the posting says: the level word in the title ("Senior", "Staff", "Director", "Intern", ...), a stated "N+ years of experience", and tools named from a fixed list (Python, SQL, AWS, Salesforce, Excel and about 50 more). Otherwise `null` or an empty list.
- `salaryYearlyMin` / `salaryYearlyMax` restate the pay range per year (hourly x 2,080, monthly x 12, ...), only when the posting gives the pay interval.
- When a posting gives one pay range per job level (e.g. Level 4 and Level 5), `salary.min` and `salary.max` cover all the levels, and `salary.summary` keeps the posting's full sentence.

Each run also saves a **`RUN_SUMMARY`** record with the Workday company and career sites each name was matched to, each site's status (`ok`, `not_found`, `blocked_by_robots`, `error`), jobs listed, checked, matched and output, and `mayBeIncomplete` when a site was too big to read in full.

### Using it from an AI agent (MCP)

Works as a tool in Claude, Cursor and other MCP clients through [Apify's MCP server](https://mcp.apify.com). For example: *"Use Workday Jobs to list data-engineering jobs NVIDIA posted this week."* Set `postedWithinDays` and a small `maxResults` for chat use.

### Pricing

You pay **per job returned**, with no monthly fee. Set a **maximum charge** on any run and the Actor stops cleanly when it's reached.

### Good to know

- Big employers list thousands of jobs, and each job is opened once to read its description, so a full read of a large site takes a few minutes. Date and title filters make runs much faster.
- The company name comes from the Workday address (e.g. "Nvidia"); Workday doesn't publish a display name.
- A company name reads **all** of the public career sites the company lists in its Workday robots.txt. To read just one, paste that site's URL. Names work when the company's Workday id matches its name (NVIDIA, Salesforce, Mastercard and most others); a few use abbreviations, and for those you paste the URL.
- Sites whose robots.txt disallows their career pages are skipped and reported, whether given by name or URL.
- This Actor is not affiliated with or endorsed by Workday, Inc. or any employer listed. Job postings belong to the employers that publish them.

### Support

Found a problem or want a field added? Open an issue on the Actor's **Issues** tab.

# Actor input Schema

## `careerSites` (type: `array`):

Company names (e.g. NVIDIA, Salesforce) or career-site URLs as you see them in your browser: https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite (a link to any job on the site works too). A name is looked up on Workday and reads every public career site that company lists; if it isn't found (some companies use a different id on Workday), paste the URL instead. Up to 200 sites per run.

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

Keep jobs whose title contains any of these words or phrases (whole words, case-insensitive; 'AI' does not match 'maintain'). Leave empty to keep all jobs.

## `excludeKeywords` (type: `array`):

Drop jobs whose title contains any of these words (for example 'intern', 'senior').

## `searchInDescription` (type: `boolean`):

Match 'Keywords' against the full job description as well as the title.

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

Keep jobs whose location or country contains any of these (case-insensitive), for example 'London', 'United States', 'Remote'.

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

Keep only jobs whose location or remote setting says remote.

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

Keep jobs in job categories containing any of these, for example 'Engineering', 'Sales'. Uses each site's own categories; sites without categories return nothing when this is set.

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

Keep jobs posted in the last N days. 0 means any date. Recent-only runs are much faster, because older jobs are never opened.

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

Remember which jobs this account has already received and output only new ones. Ideal for scheduled daily runs; you are only charged for new jobs.

## `monitoringList` (type: `string`):

Keeps separate 'already seen' lists for different searches. Use a different name for each scheduled search (letters, numbers, '-' and '\_').

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

'text' is clean plain text (best for AI agents and spreadsheets), 'html' keeps the original formatting, 'both' returns both, 'none' skips descriptions for smaller output.

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

Stop after this many matching jobs from each company. 0 means no limit.

## `maxResults` (type: `integer`):

Stop after this many jobs across all sites. 0 means no limit. Big employers list thousands of jobs; you can also cap cost with the run's maximum charge.

## Actor input object example

```json
{
  "careerSites": [
    "NVIDIA"
  ],
  "searchInDescription": false,
  "remoteOnly": false,
  "postedWithinDays": 0,
  "onlyNewJobs": false,
  "monitoringList": "default",
  "descriptionFormat": "text",
  "maxJobsPerCompany": 0,
  "maxResults": 100
}
```

# Actor output Schema

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

Every job returned by this run, one record per job, in the format described on the Actor's page.

## `runSummary` (type: `string`):

Per-site status (ok, not_found, blocked_by_robots, error) with jobs listed, checked, matched and output.

# 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 = {
    "careerSites": [
        "NVIDIA"
    ],
    "maxResults": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("agentready/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 = {
    "careerSites": ["NVIDIA"],
    "maxResults": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("agentready/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 '{
  "careerSites": [
    "NVIDIA"
  ],
  "maxResults": 100
}' |
apify call agentready/workday-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,agentready/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/OdZkAyIiZfzGtsm8n/builds/vwUgUFwkr5Bq8RIRU/openapi.json
