# Workday Jobs Scraper – Company Careers & Job Listings (`abotapi/myworkdayjobs-scraper`) Actor

Scrape job postings from any Workday-hosted careers site on Myworkdayjobs.com. Paste careers-page or job URLs and get structured job data, including title, full description, locations, time type, posting dates, employer, apply URL, country, and geo data.

- **URL**: https://apify.com/abotapi/myworkdayjobs-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 24 total users, 4 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 job results

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Workday Jobs Scraper, Any Company

Scrape job postings from any company that hosts its careers site on Workday (the `*.myworkdayjobs.com` domains). Run a keyword search inside a company's careers site, or paste careers-page and direct job URLs to scrape as-is. Get clean, structured job data: title, full description, locations, time type, posting dates, employer, apply URL, and structured country and geo. Fast, reliable, and runs on any Apify plan.

### Two modes

- **Search by keyword** — give one or more company careers sites plus a keyword and optional facets (job category, job type, time type, location). The actor runs the Workday search inside each site. *(Workday has no global search — every employer hosts its own site, so a search is always scoped to the companies you choose.)*
- **Scrape URLs directly** — paste any Workday careers-page or direct job URLs and the actor scrapes them exactly as given. Filters carried inline on the URL (e.g. `?q=engineer`) are honored.

### Why this scraper

- Returns clean, structured data that stays consistent across site redesigns.
- Runs on any Apify plan, including the free tier, with low running cost.
- Comprehensive field set: structured country with ISO code, job posting id, questionnaire id, employer details, apply type, and similar jobs, on top of the standard fields.
- Works with any Workday company and any regional cluster (wd1 through wd103) automatically.
- Keyword and facet filtering in search mode: job category, job type, time type, and location.
- Saves each job as it is collected, so partial runs keep their results.

### Data you get

> Sample shape, values are illustrative placeholders, not from a live listing.

| Field | Example |
| --- | --- |
| `title` | `Sample Software Engineer` |
| `jobReqId` | `JR0000000` |
| `jobPostingId` | `00000000-0000-0000-0000-000000000000` |
| `jobUrl` | `https://company.wd5.myworkdayjobs.com/en-US/SiteName/job/Location/Title_JR0000000` |
| `externalPath` | `/job/Location/Title_JR0000000` |
| `title` description | `Full job description text appears here when fetchDetails is on.` |
| `locationText` | `US, CA, Sample City` |
| `country` | `US` |
| `timeType` | `Full time` |
| `postedOn` | `Posted 5 Days Ago` |
| `startDate` | `2026-01-01` |
| `employerName` | `Sample Company` |
| `applyUrl` | `https://company.wd5.myworkdayjobs.com/en-US/SiteName/job/Location/Title_JR0000000/apply` |
| `applyType` | `workday` |
| `salary` | `{ "rawText": "$120,000 - $150,000", "min": 120000, "max": 150000, "currency": "USD", "period": "year" }` |
| `scrapedAt` | `2026-01-01T00:00:00.000Z` |

The full record also includes `jobPostingSiteId`, `questionnaireId`, `canApply`, `posted`, `includeResumeParsing`, `externalUrl`, the structured `location` object (with `requisitionLocation` and its country code), the full `employer` and `hiringOrganization` objects, `similarJobs`, and a stripped `descriptionText`.

### How to use

**Search mode** — keyword search inside a company careers site:

```json
{
  "mode": "search",
  "companyUrls": ["https://company.wd5.myworkdayjobs.com/en-US/SiteName"],
  "keyword": "engineer",
  "timeType": "Full time",
  "maxItems": 100,
  "fetchDetails": true
}
```

Search across several companies at once (the scheme is optional):

```json
{
  "mode": "search",
  "companyUrls": [
    "company-a.wd1.myworkdayjobs.com/en-US/Careers",
    "company-b.wd5.myworkdayjobs.com/en-US/External"
  ],
  "jobCategory": "Engineering",
  "maxItems": 200,
  "fetchDetails": false
}
```

**URL mode** — scrape any Workday URLs exactly as given:

```json
{
  "mode": "url",
  "urls": [
    "https://company.wd5.myworkdayjobs.com/en-US/SiteName?q=engineer",
    "https://company.wd5.myworkdayjobs.com/en-US/SiteName/job/Location/Title_JR0000000"
  ]
}
```

### Input parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `mode` | string | `search` | `search` = keyword/facet search inside the company sites in `companyUrls`. `url` = scrape the URLs in `urls` as-is. |
| `companyUrls` | array | — | **Search mode.** Company careers-site URLs or hosts to search within (scheme optional). |
| `keyword` | string | (none) | **Search mode.** Keyword applied as the Workday search query. |
| `jobCategory` | string | (none) | **Search mode.** Job category (job family group) filter. |
| `jobType` | string | (none) | **Search mode.** Job type (worker sub type) filter. |
| `timeType` | string | (none) | **Search mode.** Time type filter, for example Full time. |
| `location` | string | (none) | **Search mode.** Location filter. |
| `urls` | array | — | **URL mode.** Workday careers-page and/or direct job URLs, scraped as-is. Mix freely. |
| `fetchDetails` | boolean | `true` | Fetch each job's detail page for the full field set. |
| `maxItems` | integer | `20` | Maximum jobs per company site / careers URL. `0` means unlimited. This is the only result cap. |
| `proxy` | object | Apify datacenter | Proxy configuration. Datacenter is recommended and cheapest. |
| `residentialCountries` | array | major regions | Countries rotated through if the run falls back to residential. |
| `residentialBudgetGb` | string | (none) | Cap on residential bandwidth. `0` forbids residential entirely. |

### Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step **after** the scrape — the Apify dataset is never changed.

**What gets written to the connector:** a condensed, human-readable **summary** of each record — not the full JSON. Each item becomes one entry with a **title** and its key fields flattened to plain text. The **complete record always stays in the Apify dataset**.

1. Authorize a connector once under **Apify → Settings → Integrations** (Notion, Linear, Airtable, or Apify).
2. Select it in the **"Pipe results into your apps"** input field. (If the picker is empty, you haven't authorized a connector yet.)
3. For **Notion**, also set `notionParentPageUrl` to the page where items should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

### Output example

> Sample shape, values are illustrative placeholders, not from a live listing.

```json
{
  "rowType": "job",
  "title": "Sample Software Engineer",
  "jobReqId": "JR0000000",
  "jobPostingId": "00000000-0000-0000-0000-000000000000",
  "jobUrl": "https://company.wd5.myworkdayjobs.com/en-US/SiteName/job/Location/Title_JR0000000",
  "externalPath": "/job/Location/Title_JR0000000",
  "timeType": "Full time",
  "postedOn": "Posted 5 Days Ago",
  "startDate": "2026-01-01",
  "locationText": "US, CA, Sample City",
  "country": "US",
  "employerName": "Sample Company",
  "applyUrl": "https://company.wd5.myworkdayjobs.com/en-US/SiteName/job/Location/Title_JR0000000/apply",
  "applyType": "workday",
  "salary": { "rawText": null, "min": null, "max": null, "currency": null, "period": null },
  "employer": { "name": "Sample Company", "tenantSlug": "company", "careersUrl": "https://company.wd5.myworkdayjobs.com/en-US/SiteName", "url": "https://company.wd5.myworkdayjobs.com/en-US/SiteName" },
  "scrapedAt": "2026-01-01T00:00:00.000Z"
}
```

### Plan requirement

This scraper runs on any Apify plan, including the free tier. Residential proxies are only useful for the rare company that geo-restricts its careers content; if you enable them, you can cap residential bandwidth with `residentialBudgetGb`.

# Actor input Schema

## `mode` (type: `string`):

How to choose jobs. 'Search by keyword' runs a keyword/facet search inside one or more company careers sites you provide. 'Scrape URLs directly' takes any Workday careers or job URLs and scrapes them exactly as given.

## `companyUrls` (type: `array`):

Search mode only. One or more company careers-site URLs or hosts to search within, e.g. https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite (the scheme is optional). The keyword and filters below are applied to each site. Find a company's careers URL on its 'Careers' page.

## `keyword` (type: `string`):

Search mode only. Free-text keyword applied as the Workday search-box query, e.g. 'engineer' or 'data scientist'. Leave empty to list all jobs on the site.

## `jobCategory` (type: `string`):

Search mode only. Filter by Workday 'Job Category' (Job Family Group), e.g. Engineering. Matched against the live facet list for each careers site. Leave empty for all categories.

## `jobType` (type: `string`):

Search mode only. Filter by Workday 'Job Type' (worker sub type), e.g. Regular or Intern. Matched against the live facet list. Leave empty for all.

## `timeType` (type: `string`):

Search mode only. Filter by Workday 'Time Type', e.g. Full time or Part time. Matched against the live facet list. Leave empty for all.

## `location` (type: `string`):

Search mode only. Filter by Workday location facet, e.g. United States of America or a region. Matched against the live facet list. Leave empty for all locations.

## `urls` (type: `array`):

URL mode only. Paste any Workday URLs to scrape as-is. Each can be a careers/search page (e.g. https://company.wd5.myworkdayjobs.com/en-US/SiteName) or a direct job URL. Careers pages are paginated automatically; direct job URLs are fetched as single jobs. Inline filters carried on the URL (e.g. ?q=engineer) are honored; the search-mode keyword/filters above are ignored in this mode.

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

When enabled (default), each job's detail page is fetched for the full description, structured country/geo, employer details, questionnaire id, and similar jobs. Disable for a faster, lighter run that returns only the fields available on the listing.

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

Maximum number of job rows to emit per company site / careers URL. This is the single result cap. Set to 0 for unlimited (walk every page until the site is exhausted; Workday returns at most ~2000 per search).

## `proxy` (type: `object`):

Choose your proxy. The default works on every Apify plan, including the free tier, and is the cheapest option. Residential is only needed for the rare company that geo-restricts its careers content; country rotation and a bandwidth cap are available below.

## `residentialCountries` (type: `array`):

When the run falls back to residential proxies, exit countries are rotated through this list to improve reliability and recover from a flagged IP. Defaults cover major regions.

## `residentialBudgetGb` (type: `string`):

Hard cap on residential bandwidth for the run. When exceeded, the actor stops using residential bandwidth. Set to 0 to disable residential entirely. Leave empty for no cap.

## `mcpConnectors` (type: `array`):

Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON — the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## `resumeFromRunId` (type: `string`):

Paste a previous run ID or dataset ID to continue a large job pull without returning or charging for jobs already collected there. Use this after an interrupted run, or to keep extending one walk-all pull across separate runs. For recurring daily monitoring of the same search, use Incremental mode below instead.

## `incrementalMode` (type: `boolean`):

Turn this on for daily or recurring monitoring. The first run returns all matching jobs as NEW. Later runs normally return only NEW, UPDATED, and REAPPEARED jobs. Turn on "Emit unchanged" or "Emit expired" only when you also want those jobs returned (and billed). State is kept separately per mode + company site/URL/filter configuration; use State key when you want to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above.

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

Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently-configured runs. Leave empty to let the actor derive a key automatically from the mode + company site/URL/filter settings — different searches then never mix state with each other.

## `emitUnchanged` (type: `boolean`):

Off by default. Turn on to also return jobs that have not changed since the last run, marked UNCHANGED. This returns — and bills — extra rows you already have, so leave it off unless you specifically want the full snapshot every run.

## `emitExpired` (type: `boolean`):

Off by default. Turn on to also return jobs that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search — not when Max jobs capped it or when Resume was used. This returns — and bills — extra synthetic rows, so leave it off unless you need expiry tracking.

## Actor input object example

```json
{
  "mode": "search",
  "companyUrls": [
    "https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite"
  ],
  "fetchDetails": true,
  "maxItems": 20,
  "proxy": {
    "useApifyProxy": true
  },
  "residentialCountries": [
    "US",
    "GB",
    "DE",
    "CA",
    "AU",
    "FR",
    "NL",
    "SG"
  ],
  "maxNotifyListings": 50,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# 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 = {
    "mode": "search",
    "companyUrls": [
        "https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite"
    ],
    "proxy": {
        "useApifyProxy": true
    },
    "residentialCountries": [
        "US",
        "GB",
        "DE",
        "CA",
        "AU",
        "FR",
        "NL",
        "SG"
    ],
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/myworkdayjobs-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 = {
    "mode": "search",
    "companyUrls": ["https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite"],
    "proxy": { "useApifyProxy": True },
    "residentialCountries": [
        "US",
        "GB",
        "DE",
        "CA",
        "AU",
        "FR",
        "NL",
        "SG",
    ],
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/myworkdayjobs-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 '{
  "mode": "search",
  "companyUrls": [
    "https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite"
  ],
  "proxy": {
    "useApifyProxy": true
  },
  "residentialCountries": [
    "US",
    "GB",
    "DE",
    "CA",
    "AU",
    "FR",
    "NL",
    "SG"
  ],
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false
}' |
apify call abotapi/myworkdayjobs-scraper --silent --output-dataset

```

## MCP server setup

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