# Workday Jobs API: Job Postings from 478 Career Sites (`constanciodev/workday-jobs-scraper`) Actor

Get open job postings from Workday career sites (NVIDIA, Salesforce, Adobe, PayPal...) with salary, seniority, area and remote-from-Brazil filters. Search 478 sites by company name. Jobs API for recruiting, sales signals and market research. No login, no proxy, pay per job.

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

## Pricing

from $1.10 / 1,000 job postings

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 API: job postings from 478 career sites

**Get open job postings from Workday career sites (NVIDIA, Salesforce, Adobe, Intel, PayPal,
Pfizer, Bank of America and more) as clean data, with salary, seniority, area and
remote-from-Brazil filters.** Paste a careers site URL or type a company name, add a keyword or
a location, and receive title, full description, exact posting date, country, work model and
pay range for each job. You pay only for the jobs you receive.

Built by **Constancio Dev**, a small engineering studio focused on data pipelines and B2B
automation. [constanciodev.com.br](https://constanciodev.com.br)

### What you get

- **478 Workday career sites** searchable by name. Each was checked against its public job search
  on 22/10/2026. Use a company name (`Salesforce`, `Capital One`), the careers site URL or the
  short token `nvidia.wd5/NVIDIAExternalCareerSite`.
- **Full job details.** The complete description as plain text, the exact posting date (not
  only "Posted 30+ Days Ago"), every location and the country code.
- **Fields you can filter on.** Country, US and Brazilian state, remote or hybrid when the
  posting says so, salary range and currency, seniority, area (backend, data, ML/AI, product...),
  years of experience required and whether a remote job is open to someone living in Brazil.
- **Filters that save money.** Keywords go to the Workday search itself, and title, date and
  location filters run before the job details are requested. Jobs you filter out cost nothing.
- **No login, no browser, no proxy.** It reads the same public JSON the careers site loads.

### Example output

One dataset item per job. Real item from a local test run on 22/10/2026 (description
shortened):

```json
{
  "id": "nvidia.wd5/NVIDIAExternalCareerSite:JR2015832",
  "title": "Senior Software Engineer, Platform Engineering",
  "company": "NVIDIA",
  "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/US-CA-Santa-Clara/Senior-Software-Engineer--Platform-Engineering_JR2015832",
  "location": "US, CA, Santa Clara",
  "country": "US",
  "state": "CA",
  "work_model": null,
  "employment_type": "Full time",
  "posted_at": "2026-10-20T00:00:00+00:00",
  "salary_min": 168000.0,
  "salary_max": 322000.0,
  "salary_currency": "USD",
  "salary_period": "year",
  "seniority": "senior",
  "area": "other",
  "remote_scope": "unknown",
  "remote_open_to_brazil": false,
  "years_experience": 8,
  "description": "NVIDIA has been transforming computer graphics, PC gaming, and accelerated computing for more than 25 years. ..."
}
```

The real item also has `job_req_id`, `workday_tenant`, `workday_site`, `careers_site_url` and
`scraped_at`. A field the posting does not support is `null` (or `unknown` for the
classification fields), never guessed. Export the dataset as JSON, CSV, Excel or through the
Apify API.

| Field | Meaning |
|---|---|
| `id` | Workday token plus requisition id. Stable across runs, good for deduplication. |
| `location`, `country`, `state` | All locations of the job, ISO country code, US or Brazilian state. |
| `work_model` | `remote`, `hybrid` or `onsite`, only when the posting says so. |
| `salary_min`, `salary_max`, `salary_currency`, `salary_period` | Pay range found in the description. |
| `seniority` | `intern`, `junior`, `mid`, `senior`, `staff_plus` (staff, principal, tech lead), `manager` (manager, head, director, VP) or `unknown` |
| `area` | `backend`, `frontend`, `fullstack`, `data`, `ml_ai`, `devops_sre`, `mobile`, `security`, `qa`, `product`, `design` or `other` |
| `remote_scope` | `remote_global`, `remote_latam_or_americas`, `remote_country_specific`, `hybrid`, `onsite` or `unknown` |
| `remote_open_to_brazil` | `true` when a person living in Brazil can take the job remotely, `false` when not, `null` when the posting does not say |
| `years_experience` | Years of experience the description asks for. |

### Input examples

**1. Engineering jobs posted in the last two weeks at big employers**

```json
{
  "companies": ["NVIDIA", "Salesforce", "Adobe"],
  "keywords": ["engineer"],
  "locations": ["United States"],
  "postedWithinDays": 14,
  "maxItems": 200
}
```

**2. Remote senior jobs a person living in Brazil can take**

```json
{
  "companies": ["Salesforce", "PayPal", "Adobe", "Intel"],
  "remoteOpenToBrazil": true,
  "seniority": ["senior", "staff_plus"],
  "includeDescription": false,
  "maxItems": 100
}
```

**3. Daily hiring signal for sales or market research (schedule it once a day)**

```json
{
  "companies": ["Pfizer", "Bank of America", "Capital One"],
  "keywords": ["data", "analytics"],
  "postedWithinDays": 1,
  "includeDescription": false
}
```

#### Input reference

| Field | What it does |
|---|---|
| `companies` | Workday careers URLs, tokens like `nvidia.wd5/NVIDIAExternalCareerSite`, or company names from the index. |
| `keywords` | Keep jobs whose title contains at least one of these words. Empty keeps every job. |
| `locations` | Keep jobs whose location contains one of these, or whose country matches (`Texas`, `Germany`, `US`). |
| `remoteOnly` | Keep only jobs the posting declares as remote. |
| `seniority`, `area` | Keep only these levels or areas (values in the table above). |
| `remoteOpenToBrazil` | Keep only remote jobs that a person living in Brazil can take. |
| `postedWithinDays` | Keep only jobs posted in the last N days. Jobs with no date are left out when set. |
| `maxItems` | Stop after this many jobs in total (default 50). This is also your cost cap. |
| `maxJobsPerCompany` | Jobs per careers site, in the order the site lists them. 0 splits `maxItems` among the sites. |
| `includeDescription` | Include the full description text (default: true). |

Where to find the URL: open the company's careers page, click any job, and copy the address up
to the site name, for example `https://salesforce.wd12.myworkdayjobs.com/External_Career_Site`.
The `wd1`, `wd5` or `wd12` part matters, so a URL is always the safest input.

### Pricing

Pay per event: a price per job delivered to the dataset, which depends on your Apify plan, plus
$0.00005 per GB of memory when the run starts.

| Apify plan | Price per 1,000 jobs |
|---|---|
| Free | $1.80 |
| Starter (Bronze) | $1.60 |
| Scale (Silver) | $1.20 |
| Business (Gold) and above | $1.10 |

Jobs removed by your filters cost nothing. `maxItems` caps the cost of every run, and a run also
stops when it reaches the maximum cost per run you set in Apify. When the run timeout is near or
the cost cap is reached, the Actor stops cleanly: the run succeeds and keeps every job already
delivered.

### FAQ

**Is it allowed to collect Workday job postings?** The Actor only reads job postings that
companies publish openly for anyone to see, without login, and it respects `robots.txt`. Check
the terms that apply to your own use of the data.

**Does it need proxies?** No. Each company has its own careers site, and the Actor paces its
requests per site.

**How do I get only new jobs every day?** Schedule the Actor with `postedWithinDays: 1` and your
keywords. This Actor has no monitor mode that remembers earlier runs; the ATS Jobs API Actor has
one (see below).

**Can I get Greenhouse, Lever or Ashby jobs too?** Yes, with the companion Actor
[ATS Jobs API](https://apify.com/constanciodev/ats-jobs-worldwide), which covers those
platforms and Workday in one output format and has a monitor mode.

**Something is wrong or missing?** Open an issue on the Actor's Issues tab. It is read and
answered.

### Limits

- **Workday lists at most 2,000 jobs per careers site.** For a big employer, use keywords or
  locations to reach the jobs you need.
- **Slower than other ATS.** Workday needs one request per job to get the description, and the
  Actor waits between requests to the same site, so a site with 100 jobs takes minutes, not
  seconds. Keywords, dates and locations narrow the list before those requests.
- **Only public sites in the index or the URL you paste.** The index is a snapshot of
  22/10/2026. Sites whose `robots.txt` closes the careers path are skipped, and a company that
  moved to another Workday address shows up as a failure line in the log.
- **Work model is often `null`.** Workday has no work model field; it is filled only when the
  location or the description says it.
- **Classification is rules, not AI.** `seniority`, `area`, `remote_scope` and
  `remote_open_to_brazil` come from deterministic rules over the title, location and
  description. A plain "Software Engineer" title has `area: other`, and a title with no level
  and no years of experience has `seniority: unknown`.
- **Salary only when it is written.** It is parsed from the description text; many postings
  have none.
- **No contact fields.** The output has no recruiter name, e-mail or phone field.

### Job classification

Every job gets four extra fields, computed inside the Actor by deterministic rules over the
title, location, work model and description. No paid API, no network call, no AI model: the
same posting always gets the same answer, and it adds about half a second per 1,000 jobs.

- **`seniority`** reads the title first (`Senior`, `Sr.`, `III`, `Staff`, `Principal`,
  `Tech Lead`, `Engineering Manager`, `Head of`, `Director`, `Intern`, `New Grad`, `II`,
  Portuguese `Pleno` and `Estagio` too). "Product Manager", "Account Manager" and "Program
  Manager" are individual roles, not people managers. With no level in the title, the years of
  experience the posting asks for decide: up to 1 year is `junior`, 2 to 4 is `mid`, 5 or more
  is `senior`. With neither, `unknown`.
- **`area`** reads the title. Sales, support, recruiting and other non engineering roles are
  `other`, and so is an engineering title that names no specialty.
- **`remote_scope`** combines the work model, the location text and phrases in the description
  ("3 days a week in the office", "fully remote", "#LI-Hybrid"). A remote job limited to a
  country or region is `remote_country_specific`; one open to Latin America or the Americas is
  `remote_latam_or_americas`; one that says worldwide or names no country is `remote_global`.
- **`remote_open_to_brazil`** is `true` for remote jobs open worldwide (explicitly), in Latin
  America or the Americas, in Brazil, or in a time zone range that includes UTC-3. It is `false`
  for hybrid and onsite jobs and for remote jobs limited to another country. A bare "Remote"
  with no country stays `null`.

The rules are shared with the ATS Jobs API Actor. Measured accuracy, on 150 real jobs from that
Actor's output labeled by hand without looking at the rules:

| Field | Accuracy |
|---|---|
| `seniority` | 89.3% |
| `area` | 96.7% (87.5% on the 32 tech jobs alone) |
| `remote_scope` | 95.3% |
| `remote_open_to_brazil` | 98.7% |

# Changelog

This Actor's version history is a separate document: https://apify.com/constanciodev/workday-jobs-scraper/changelog.md

# Actor input Schema

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

Workday careers site URLs such as https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite, the short token 'nvidia.wd5/NVIDIAExternalCareerSite', or a company name from the built-in index ('NVIDIA', 'Capital One'). A name that is not in the index is reported in the log; paste the careers URL instead.

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

Keep jobs whose title contains at least one of these words (case and accents ignored). Also sent to the Workday search, so fewer pages are read. Empty keeps every job.

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

Keep jobs whose location contains one of these, or whose country matches: 'Texas', 'Germany', 'US', 'Remote'. Empty keeps every location.

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

Keep only jobs the posting declares as remote.

## `seniority` (type: `array`):

Keep only jobs classified with one of these levels (from the title, or from the years of experience the posting asks for). Empty keeps every level.

## `area` (type: `array`):

Keep only jobs classified in one of these areas, read from the title. Empty keeps every area.

## `remoteOpenToBrazil` (type: `boolean`):

Keep only remote jobs that a person living in Brazil can take: remote worldwide, remote in Latin America or the Americas, remote in Brazil, or a time zone range that includes UTC-3. Jobs with no clear evidence are left out.

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

Keep only jobs posted in the last N days. Jobs with no date are left out when this is set. Empty or 0 keeps every date.

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

Stop after this many jobs across all companies, split among the sites as the run goes on. You pay per job delivered, so this is also your cost cap.

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

Jobs per careers site, in the order the site lists them. 0 splits the total limit among the sites. Workday itself stops listing at 2,000 jobs per site.

## `includeDescription` (type: `boolean`):

Turn off for a smaller dataset with only the structured fields.

## Actor input object example

```json
{
  "companies": [
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
  ],
  "remoteOnly": false,
  "remoteOpenToBrazil": false,
  "maxItems": 20,
  "maxJobsPerCompany": 0,
  "includeDescription": true
}
```

# Actor output Schema

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

Every job posting delivered in this run, as dataset items.

# 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": [
        "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
    ],
    "maxItems": 20
};

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

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

```

## MCP server setup

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