# Workday Jobs Scraper: Careers, Salaries, New-Job Alerts (`signalscouter/workday-jobs-scraper`) Actor

Scrape jobs from any Workday career site (myworkdayjobs.com) via its public JSON feed. Paste career-site URLs; get titles, locations, dates, full descriptions, parsed salaries, new-job monitoring and per-company hiring signals.

- **URL**: https://apify.com/signalscouter/workday-jobs-scraper.md
- **Developed by:** [Signal Scout](https://apify.com/signalscouter) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

Get job postings from any company's **Workday career site** (`*.myworkdayjobs.com`): titles, locations, posting dates, full descriptions, parsed salaries, new-job monitoring, and a hiring-signal summary per company. Paste the career-site URLs and run.

Thousands of employers (NVIDIA, Salesforce, Adobe, Workday itself and many more) host their careers pages on Workday. This Actor reads the same public JSON feed those pages use to show their jobs. It needs no login, no browser and no proxies.

### What you get

- **One row per job:** title, requisition ID, primary location and all locations, country, remote flag, time type (full/part time), posting date, job URL and apply URL, hiring legal entity, description text (HTML optional) and salary range where the employer publishes one.
- **One hiring summary per company** (optional): open jobs, jobs posted in the last 7 and 30 days, remote jobs, top locations, and with monitoring on, how many jobs are new since the last run.
- **Error rows** for inputs that couldn't be read (bad URL, site not found, robots.txt disallows the site, access refused). They are **never charged**.

### How to use it

1. Open the company's careers page and copy the URL, for example `https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite`. A link to any single job on the site also works, and so does the short form `tenant|wd5|site`.
2. Add filters if you want them:
   - **Search text** goes to Workday's own search box.
   - **Title keywords**, **exclude title keywords**, **locations**, **remote only** and **posted within days** are applied by the Actor.
3. Set **max jobs per site** or **max jobs in total** if you only need a sample.
4. For alerts, turn on **Only new jobs** and schedule the Actor. Each run then outputs only jobs it hasn't delivered before.

#### Example input

```json
{
  "startUrls": ["https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite", "https://salesforce.wd12.myworkdayjobs.com/External_Career_Site"],
  "titleKeywords": ["engineer"],
  "locations": ["united kingdom", "remote"],
  "postedWithinDays": 14,
  "includeDetails": true
}
```

#### Example job row (shortened)

```json
{
  "recordType": "job",
  "companyName": "Workday",
  "tenant": "workday",
  "site": "Workday",
  "jobId": "JR-0109588",
  "title": "Principal Managing Partner",
  "location": "USA, TX, Frisco",
  "locations": ["USA, TX, Frisco", "USA, OR, Remote", "USA, WA, Seattle"],
  "country": "United States of America",
  "isRemote": true,
  "employmentType": "Full Time",
  "postedAt": "2026-10-12",
  "postedAtIsApproximate": false,
  "url": "https://workday.wd5.myworkdayjobs.com/Workday/job/USA-TX-Frisco/Principal-Managing-Partner_JR-0109588",
  "hiringEntity": "Workday, Inc.",
  "salaryMin": null,
  "descriptionText": "Your work days are brighter here. …"
}
```

### Good to know

- **Details cost one request per job.** Descriptions, all locations, country, time type, exact posting date and salary come from each job's detail page. Without details (`includeDetails: false`), a multi-location job shows e.g. "3 Locations", and the posting date is worked out from Workday's "Posted 5 Days Ago" text (`postedAtIsApproximate: true`). "Posted 30+ Days Ago" only tells us the job is at least 30 days old, so it is flagged with `postedAtIsLowerBound`.
- **Workday shows at most 2,000 results per search.** For larger sites the Actor splits the search by one of the site's own filters (for example job family) and merges the results, so sites like NVIDIA (2,700+ jobs) can be listed in full. If a site can't be split, the summary row says `listingComplete: false`.
- **The company summary reads the whole site's list** (one request per 20 jobs), even when you set a small max. For a quick sample, turn the summary off.
- **Run time:** requests to one site are sent one at a time with a polite delay (0.5 s by default). A 300-job site takes about 1 minute to list, plus about 1 s per job for details. Several sites run in parallel.
- **Salary** is parsed from pay-transparency text in the description (common in US postings). It is best effort, and many postings don't include pay.
- **Monitoring state** is kept per career site in your named key-value store `signalscouter-workday-jobs-state`. Jobs that a spending limit or max cut off are still treated as new next time. If you change your filters, delete that store to start fresh.
- **Company name** comes from the tenant ID (for example `nvidia` becomes NVIDIA). Use the `companyNames` input to set your own names.

### Pricing

Pay per event:

| Event | Price |
|---|---|
| Job row (`job-result`) | $1.00 per 1,000 jobs ($0.001 each) |
| Company hiring summary (`company-summary`) | $5.00 per 1,000 summaries ($0.005 each, at most one per career site per run) |

Error rows, run starts, filtered-out jobs and already-seen jobs (onlyNew) are not charged. Apify platform usage is included. Example: 500 jobs from 3 companies with summaries costs $0.515. If you set a maximum charge for the run, the Actor stops when it is reached. Jobs that were cut off are not marked as seen.

### Respectful and legal use

- **Public data only.** The Actor reads only the unauthenticated job feed that each employer's public careers page uses. It uses no logins and no proxies, and it doesn't bypass bot protection. If Workday refuses a request, the site is skipped and you get an error row.
- **robots.txt is respected** for each career-site host. If a host disallows a career-site path (some companies hide internal or referral sites this way), that site is skipped with a `ROBOTS_DISALLOWED` error row.
- **Polite rate:** one request at a time per host, at least 0.25 s apart (0.5 s by default), with backoff on 429/5xx. The user-agent identifies signalscouter and gives a contact email.
- **No personal data:** job ads only. No recruiter or applicant details are collected.
- Job ads belong to the employers who post them. You are responsible for using the data lawfully and in line with the employer's and Workday's terms. Workday is a trademark of Workday, Inc. This Actor is not affiliated with or endorsed by Workday.

### More signalscouter Actors

| Actor | What it gives you |
|---|---|
| [Career Site Jobs Scraper](https://apify.com/signalscouter/career-site-jobs-scraper) | Jobs from 12 ATSes (Greenhouse, Lever, Ashby, Workday, Workable and more) in one schema, from company domains |
| [UK Public Sector Jobs Scraper](https://apify.com/signalscouter/uk-public-sector-jobs-scraper) | NHS Jobs, Teaching Vacancies and DWP Find a Job |
| [Company Tech Stack & Domain Signals](https://apify.com/signalscouter/company-tech-stack-signals) | What a company's website runs on, plus DNS, email security and domain age |
| [SEC Form D Funding Signals](https://apify.com/signalscouter/sec-form-d-funding-signals) | Newly funded US companies from SEC Form D filings |

### Support and contact

Report bugs or request features in the Issues tab. We aim to reply within 14 days. For anything else, email **signalscouter.data@gmail.com**.

### Changelog

- **0.1:** first version.

# Actor input Schema

## `startUrls` (type: `array`):

Workday career-site URLs (or any job URL from the site), e.g. https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite. Also accepts 'tenant|wd5|site'.

## `searchText` (type: `string`):

Sent to Workday's own search box (searches title and description server-side). Leave empty for all jobs.

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

Keep jobs whose title contains any of these (case-insensitive).

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

Drop jobs whose title contains any of these.

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

Keep jobs whose location text contains any of these, e.g. 'London', 'Germany', 'Remote'.

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

Keep only jobs marked remote.

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

Keep jobs posted in the last N days (0 = any).

## `maxJobsPerSite` (type: `integer`):

Stop after this many jobs per site (0 = no limit).

## `maxTotalJobs` (type: `integer`):

Stop after this many jobs across all sites (0 = no limit).

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

One extra request per output job: full description, all locations, exact posting date, time type, country, salary. Turn off for a faster, cheaper list-only run.

## `includeHtml` (type: `boolean`):

Also output descriptionHtml.

## `includeCompanySummary` (type: `boolean`):

Add one companySummary row per site (open jobs, posted last 7/30 days, remote count, top locations). Charged as company-summary.

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

Output only jobs not delivered by an earlier run with this option (state kept in your named key-value store 'signalscouter-workday-jobs-state'). Seen jobs skip the detail request, so repeat runs are cheaper.

## `companyNames` (type: `object`):

Optional map of tenant to display name, e.g. {"nvidia": "NVIDIA"}.

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

Different career sites processed at once. Requests to one site are always sequential.

## `requestDelaySecs` (type: `number`):

Politeness delay per Workday host. Minimum 0.25 s.

## Actor input object example

```json
{
  "startUrls": [
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
    "https://salesforce.wd12.myworkdayjobs.com/External_Career_Site"
  ],
  "remoteOnly": false,
  "maxJobsPerSite": 0,
  "maxTotalJobs": 0,
  "includeDetails": true,
  "includeHtml": false,
  "includeCompanySummary": true,
  "onlyNewJobs": false,
  "maxConcurrency": 3,
  "requestDelaySecs": 0.5
}
```

# Actor output Schema

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

Job postings (recordType=job).

## `companySummaries` (type: `string`):

One row per career site (recordType=companySummary).

## `errors` (type: `string`):

Inputs that couldn't be processed (recordType=error). Never charged.

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

RUN_SUMMARY: totals, errors, HTTP requests.

# 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 = {
    "startUrls": [
        "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
        "https://salesforce.wd12.myworkdayjobs.com/External_Career_Site"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("signalscouter/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 = { "startUrls": [
        "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
        "https://salesforce.wd12.myworkdayjobs.com/External_Career_Site",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("signalscouter/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 '{
  "startUrls": [
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
    "https://salesforce.wd12.myworkdayjobs.com/External_Career_Site"
  ]
}' |
apify call signalscouter/workday-jobs-scraper --silent --output-dataset

```

## MCP server setup

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