# Workday Jobs Scraper: Any Company's Workday Careers Site (`ataism/workday-jobs`) Actor

Jobs from the Workday careers sites you list: full descriptions, exact dates, filters, only-new alerts. $0.80 per 1,000 jobs. Public postings only.

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

## Pricing

from $0.80 / 1,000 job posting saveds

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's Workday Careers Site

Turn the Workday careers sites of the companies **you pick** into one clean job dataset. Paste the career-site link (`https://<company>.wd5.myworkdayjobs.com/...`) and get every public posting with the full description, exact start date, all locations, workplace type, employment type, requisition ID and the posting link exactly as the employer's Workday site publishes it.

**Price: $0.80 per 1,000 jobs ($0.0008 per job), full description included.** Sites that don't exist, entries that can't be read and jobs that fail are free.

- **Any Workday careers site, one format:** the same fields for every employer, so one sheet or CRM mapping covers all of them. NVIDIA, Adobe, Salesforce and thousands of others run on Workday.
- **Only new jobs:** schedule a daily run that returns (and charges for) only roles you haven't seen, remembered per career site for 120 days.
- **Filters:** search text, filters you set on the career site itself (paste the link with its filters), locations, posted in the last N days, max jobs per site.
- **No recruiter fields are read.** Names written inside a description are passed through as written. Emails and phones are removed by pattern.
- **Quick start:** press *Start*. The prefilled input reads NVIDIA's public careers site and stops at 20 jobs. It takes about 25 seconds and costs about $0.016. No keys or accounts needed.

> **Public job postings only. You list the career sites.** The Actor reads only the public JSON that each Workday careers page already loads in your browser. No logins, no candidate or applicant data, no internal postings. **It never searches for, crawls or discovers companies or career sites.** It checks each site's robots.txt (for the job list and for every job detail), keeps to any `Crawl-delay` it states, sends at most one request per second per site, and never tries to get around a block.

### How to find a company's career-site link (1 minute)

1. Open the company's careers page and click *Search jobs* or any job.
2. The address bar shows something like `https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite` (the `myworkdayjobs.com` part is what matters).
3. Paste that link as it is. A link to a single job works too, and so does one without the `en-US` part.

If the careers page stays on the company's own domain and you can't see a `myworkdayjobs.com` address anywhere (for example behind the *Apply* button), the company may use another system, which this Actor doesn't read. Only `*.myworkdayjobs.com` addresses are accepted.

### What you can do with it

- **Watch the companies you care about.** Daily alert for new roles at target employers (customers, competitors, portfolio companies), with **Only new jobs** on.
- **Hiring-trend research** across several large employers in one dataset.
- **Feed your own tools** (CRM, Slack, sheets, recruiting research) with consistent fields.

### Input

| Field | What it does |
|---|---|
| **Career site URLs** | Required. One Workday careers link per line (up to 100). Read one after the other. |
| **Search text** | Optional words sent to the career site's own search box, e.g. `data engineer`. |
| **Locations (contains)** | Keep jobs whose location text contains any of these, e.g. `Berlin`, `Germany`. |
| **Posted in the last N days** | Uses Workday's "Posted 5 Days Ago" text; for 30 days or more the exact start date is read from each job. |
| **Max jobs per career site** / **Max jobs in total** | Hard limits (default total 20, up to 5,000). Sites are read in the order you list them. |
| **Include full description** | HTML plus plain text, exact posted date, employment type, workplace type and all locations. Needs one extra request per job. On by default. |
| **Only new jobs** / **Only-new memory name** | Skips jobs you were already delivered, remembered per career site for 120 days. |
| **Seconds between requests to one site** | 1 (default) to 10. Never faster than one request per second. |

#### Filters you set on the career site

Workday's own filters (job family, country, time type and so on) use internal IDs, so there is no list of them to pick from here. Instead: open the career site, set the filters you want, copy the address from the browser (it now ends in something like `?locationCountry=...&jobFamilyGroup=...`) and paste it into **Career site URLs**. The Actor sends the search text (`q=`) and those filters to the site's own list. Use **Locations (contains)** for simple place matching on top.

#### Example inputs

The sites below are examples: replace them with the companies you follow.

**1. Daily alert: new roles at a few large employers** (schedule it daily; with *Only new jobs* each run returns only roles you haven't seen):

```json
{
  "careerSites": [
    "https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite",
    "https://adobe.wd5.myworkdayjobs.com/external_experienced"
  ],
  "searchText": "data engineer",
  "postedSinceDays": 7,
  "maxItems": 200,
  "onlyNew": true
}
```

**2. Fast snapshot: light rows without descriptions** (20 jobs per request instead of one request per job; title, location, "Posted ..." text and link only):

```json
{
  "careerSites": ["https://salesforce.wd12.myworkdayjobs.com/External_Career_Site"],
  "includeDescription": false,
  "maxJobsPerCompany": 500,
  "maxItems": 500
}
```

**3. Berlin or Munich roles from a pre-filtered site link** (filters copied from the career site, plus a location match):

```json
{
  "careerSites": ["https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite?jobFamilyGroup=0c40f6bd1d8f10ae43ffaefd46dc7e78"],
  "locations": ["Berlin", "Munich"],
  "maxItems": 100
}
```

The default input is NVIDIA's public careers site with 20 jobs in total.

### Output

One item per job:

```json
{
  "vendor": "workday",
  "companySlug": "nvidia",
  "site": "NVIDIAExternalCareerSite",
  "company": "nvidia",
  "hiringOrganization": "AM01 NVIDIA Armenia LLC",
  "jobId": "JR2028039",
  "title": "Research Scientist - New College Grad 2027",
  "location": "Armenia, Yerevan",
  "locations": ["Armenia, Yerevan"],
  "country": "Armenia",
  "remote": null,
  "workplaceType": null,
  "employmentType": "Full time",
  "postedText": "Posted Today",
  "publishedAt": "2026-10-20T00:00:00.000Z",
  "applicationDeadline": null,
  "applyUrl": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/Armenia-Yerevan/Research-Scientist---New-College-Grad-2027_JR2028039",
  "jobUrl": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/Armenia-Yerevan/Research-Scientist---New-College-Grad-2027_JR2028039",
  "description": "<p>…</p>",
  "descriptionText": "…",
  "source": "Workday public career site",
  "retrievedAt": "2026-10-20T09:19:35.580Z"
}
```

The shape matches our [Greenhouse, Lever & Ashby Jobs Scraper](https://apify.com/ataism/ats-jobs) where Workday has the data (no department, team or salary range: Workday's public JSON doesn't carry them).

- `company` is the tenant name from the address (`nvidia`); Workday does not publish a display name on these endpoints. `hiringOrganization` is the hiring legal entity when the description is included.
- `remote: null` means "unknown", not "no". `workplaceType` is only filled when the employer fills in Workday's remote type (`Office - Flexible` is read as hybrid).
- `publishedAt` is the posting start date (00:00 UTC). It, `employmentType`, `workplaceType`, the full `locations` list and the description need **Include full description**. Without it you get Workday's own `postedText`, and a job listed as "2 Locations" has `location: null` and an empty `locations` list.
- Every run also saves a `RUN_SUMMARY` record: per-site counts, failures by code, requests, bytes, why the run stopped.
- **Free error rows:** a site or job that could not be read becomes a row with `error` and `errorMessage` instead of a job. These are never charged. Codes: `invalid-entry`, `robots` (the site's robots.txt disallows the job list), `robots-unreachable`, `blocked-by-site` (HTTP 401/403/429/999 or a bot-check page; never retried), `not-found`, `redirect`, `http-error`, `bad-response`, `network`, `timeout`, `host-skipped` (the site refused twice, so it is skipped for the rest of the run), `crawl-delay` (robots.txt asks for more than 2.5 s between requests, or more than the run's time left allows; the delay is never shortened, so the site is skipped), `retry-after` (the site answered 5xx with a `Retry-After` over 20 s; not waited for or retried), `unpaid-filter-cap` (200 job details in a row, or more than 200 + 3 per delivered job in the run, were read and then filtered out; the site or the run is stopped), `row-too-large`, `push-failed`. A `robots` row with a `jobPath` means robots.txt disallows that job's detail page and your filters needed it.

Export as JSON, CSV, Excel or XML, or read it through the Apify API.

### Pricing

Pay per event:

- **$0.0008 per job** saved to the dataset.
- Apify's standard tiny start fee per run.

| Jobs delivered | Cost |
|---|---|
| 20 | $0.016 |
| 100 | $0.08 |
| 1,000 | $0.80 |
| 5,000 | $4.00 |

Sites that don't exist, invalid entries, failed jobs and jobs filtered out are free. Cap any run with Apify's *Max total charge*; the Actor stops at the cap and remembers what it delivered.

### Limits and speed

- **One request per second per site, or the site's own `Crawl-delay` if that is longer.** The delay is honoured in full and never shortened; a site that asks for more than 2.5 s between requests (or more than the time left allows) is skipped with a free `crawl-delay` row. With descriptions that is about 1 job per second: 1,000 jobs take about 17 minutes. Switch off *Include full description* for 20 jobs per request. Set the run timeout to match (the default prefill needs under a minute). A run stops cleanly after 5.5 hours or just before the Apify timeout.
- **Workday returns at most about 2,000 results per search.** For a larger employer, split the run with *Search text* or a pre-filtered site link (one entry per filter).
- 100 career sites, 5,000 jobs and 300 list pages per site per run.
- The run stops after 30 failed jobs (unpaid work) and skips a site that refuses twice. A site is stopped after 200 job details in a row that were read and then filtered out, and the whole run after more than 200 + 3 per delivered job such reads (free `unpaid-filter-cap` rows): use a narrower search text or a pre-filtered site link. A `Retry-After` longer than 20 s ends that request as a free error instead of waiting.
- If a site's robots.txt disallows the job detail pages, jobs are delivered as list-only rows (no description, date or employment type) when your filters can be decided from the list; jobs whose filters need the detail are skipped with a free `robots` row. `RUN_SUMMARY.perSite[].detailsBlockedByRobots` counts them.
- Memory: 256 MB is enough.

### Use it via API, n8n or Make

Get an API token in Apify Console → *Settings* → *API & Integrations*, and keep it in an environment variable (`APIFY_TOKEN` below). Never paste it into shared code.

**cURL** (starts a run, waits for it and returns the jobs as JSON; this synchronous endpoint waits up to 5 minutes, so keep `maxItems` to a few hundred and use the clients below for more):

```bash
curl -X POST "https://api.apify.com/v2/acts/ataism~workday-jobs/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"careerSites": ["https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite"], "searchText": "engineer", "maxItems": 50}'
```

**JavaScript** (`npm install apify-client`):

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('ataism/workday-jobs').call({
    careerSites: ['https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite'],
    onlyNew: true,
    maxItems: 200,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const job of items) console.log(job.company, job.title, job.jobUrl);
```

**Python** (`pip install "apify-client>=3"`):

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("ataism/workday-jobs").call(run_input={
    "careerSites": ["https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite"],
    "onlyNew": True,
    "maxItems": 200,
})
for job in client.dataset(run.default_dataset_id).iterate_items():
    print(job["company"], job["title"], job["jobUrl"])
```

(With apify-client versions before 3.0, `call()` returns a dict: use `run["defaultDatasetId"]`.)

**n8n** (new jobs to Slack, a sheet or your CRM):

1. Add a *Schedule Trigger* (for example daily at 08:00).
2. Add the **Apify** node, operation **Run an Actor and get dataset**, Actor `ataism/workday-jobs`, and paste your input JSON with `"onlyNew": true`.
3. Add a *Slack*, *Google Sheets* or CRM node and map `company`, `title`, `location` and `jobUrl`.

**Make:**

1. Add the **Apify** module **Run an Actor**, choose `ataism/workday-jobs`, paste the input JSON and set *Run synchronously* to *Yes*.
2. Add the **Apify** module **Get Dataset Items** and map the run's default dataset ID.
3. Add your destination (Google Sheets *Bulk Add Rows*, Slack, CRM) and map the fields. Schedule the scenario daily.

You can also schedule the Actor directly in Apify Console (*Schedules*) and export each run as JSON, CSV or Excel. Test hooks and the self-test input exist only for the maintainer.

### Terms and how the Actor behaves

We read Workday's website terms and the robots.txt of several public career sites before building this (copies and the verdict are in the Actor's repository, `docs/terms/VERDICT.md`). In short:

- The robots.txt of the career sites we checked (NVIDIA, Salesforce, Adobe on 2026-10-20) allows their career-site paths and does not disallow the `/wday/cxs/` JSON the careers page itself loads; the Actor reads each site's robots.txt once per run, checks the exact path of the job list and of every job detail before requesting it, keeps to a stated `Crawl-delay`, and skips a site that disallows the job list or whose robots.txt it cannot read.
- Workday's Online Terms of Service prohibit using "data mining, robots or similar data gathering or extraction methods designed to scrape or extract data from our Sites". We read their scope as workday.com and pages that reference those terms, not employers' own career sites on `myworkdayjobs.com`, and the career-site page we checked does not reference them. That is our reading, not a licence: Workday has published no terms for this endpoint either way, and could take a different view. If Workday asks us to stop, we will.
- Job postings are each employer's content. **You are responsible for having the right to use the career sites you list and for how you use the data.** We are not affiliated with Workday or any employer.

The Actor sends at most one request per second per site (slower if robots.txt asks for it), sequentially, sends no cookies, uses no proxy, never follows redirects, and never tries to get around a block, login or bot check: a 401, 403, 429 or bot-check page becomes a free error row, and after two refusals the site is skipped for the run.

### Privacy

Job postings only, never applicant or candidate data. **No recruiter fields are read. Names written inside a description are passed through as written. Emails and phones are removed by pattern.** Recruiters sometimes put their email or phone number in a posting, so the Actor removes email addresses (including spelled-out ones such as `name [at] domain [dot] com` or `name(at)domain.com`) and phone numbers from titles, locations, the posted text, the job ID and descriptions (you will see `[email removed]` or `[phone removed]`; generic addresses such as a recruiting mailbox are removed too). A run of digits (10 to 15 digits, or 9 to 15 with spaces, dots or dashes such as `Tel. 030 12345678`) is removed as a phone number only when a phone cue stands within 20 characters before it with nothing but filler such as *us at* or *number* in between (*tel*, *phone*, *call*, *mobile*, *cell*, *WhatsApp*, *fax*, *contact*, *text*, *SMS*, *Telefon*, *Tél*, *Teléfono*). Numbers with a leading `+` or brackets are removed as before. Digit runs without such a cue are kept: salaries (`Salary 1200000000 IDR`), user counts, timestamps, GTINs, requisition and position numbers, a job ID field that is just digits, and values inside HTML attributes. A number right next to a currency code or symbol is kept even after a cue. Removal is pattern-based and bounded, so unusual formats can slip through and a name can never be recognised as such: tell us on the Issues tab and we will fix it.

### Reliability

- Reads the careers page's own JSON, not web pages, so redesigns of the page don't break it. Workday can change that JSON without notice.
- A daily self-test checks the parsing, mapping, redaction and robots logic offline, then reads robots.txt, one list page and three jobs from a public career site (a spare site is used only if the first is unreachable). It fails on HTTP errors, a robots.txt that disallows us, or a changed format; a network error or timeout is only a notice.
- **Only new jobs** saves its memory at least every 5 jobs and when a run is aborted or migrated. A restarted run reconciles with its own dataset (read to the end, whatever the dataset's item count says), so jobs already delivered are neither delivered nor charged twice, and jobs recovered that way are remembered too. Jobs are remembered after their row is saved and charged; if the run crashes between the charge and the next save, a job recovered from the dataset on restart is remembered then. If the dataset cannot be read on restart the run fails with its progress kept, so nothing is delivered or charged twice; run it again to resume.
- When Apify migrates a run to another server, the Actor stops reading, saves its progress and waits for the restart (it never ends such a run as a success with partial results); the restarted run continues from the saved progress.
- Descriptions longer than 400,000 characters are cut (`descriptionTruncated: true`).

### FAQ

**Can it find which companies use Workday?** No, by design. You list the career sites. It does not search, crawl or guess company names.

**Why was my site not found?** The address is wrong, the tenant uses another host (only `*.myworkdayjobs.com` is read), or the site is closed. Check the link in the careers page. If none of your sites can be read, the run fails and names them.

**Why does a job show `location: null`?** Workday lists multi-location jobs as "2 Locations". Switch on *Include full description* to get all places.

**Why are there fewer jobs than on the careers page?** Workday caps a search at about 2,000 results; split with search text or filters. Jobs removed between the list and the detail read are skipped.

**Does Max jobs count filtered-out jobs?** No. Only delivered jobs count.

**Can it apply to jobs or read applicants?** No. Read-only, public postings.

**Why did my run stop early?** The jobs ran out, a limit was reached, or *Max total charge* was hit. `RUN_SUMMARY.stoppedBy` says which (`end-of-sites`, `maxItems`, `max-charge`, `unpaid-cap`, `time-limit`, `migrating`).

**Something's wrong?** Open an issue on the Actor's Issues tab. We aim to reply within 2 working days.

# Actor input Schema

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

Workday career-site addresses, one per line, e.g. https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite (a link to a single job or the locale part is fine too). Up to 100 per run, read one after the other. To narrow a site, set the filters on the career site first and paste the address with its ?query part: its search text and filters are used. Addresses on other hosts, and sites that do not exist, are listed as free error rows. To find a company's address: open its careers page and copy the myworkdayjobs.com link.

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

Optional. Words sent to the career site's own search box (for example "data engineer"). Used for every site that has no ?q= in its address.

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

Keep jobs whose location text contains any of these (not case sensitive), e.g. "Berlin", "Germany", "Remote". Jobs listed as "2 Locations" need one extra request to check their places.

## `postedSinceDays` (type: `integer`):

Keep jobs posted within this many days. Workday lists only "Posted 5 Days Ago" and "Posted 30+ Days Ago", so for 30 days or more the exact start date is read from each job.

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

Stop taking jobs from a site after this many. Leave empty for no per-site limit (the total limit below still applies).

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

Hard limit on delivered (and charged) jobs for the whole run. Sites are read in the order you list them; later ones are only read if the limit is not reached yet. Large employers have thousands of jobs, so set this on purpose.

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

Adds the description (HTML and plain text), exact posted date, employment type, workplace type and all locations. This needs one extra request per job, so a 1,000-job run takes about 17 minutes at one request per second. Switch off for fast list-only rows (title, location, posted text, link): 20 jobs per request.

## `onlyNew` (type: `boolean`):

Skip jobs you were already delivered on an earlier run (remembered per career site for 120 days in a named store in your account). Only jobs that were delivered and charged are remembered.

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

Use a different name to keep separate only-new histories (for example one per project). Only used with Only new jobs.

## `secondsBetweenRequests` (type: `integer`):

Politeness delay for each career site. 1 is the fastest allowed; raise it for very large runs.

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

Internal: "selfTest" runs the maintainer health check (offline checks plus one small live read), saves no jobs and charges nothing.

## Actor input object example

```json
{
  "careerSites": [
    "https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite"
  ],
  "maxItems": 20,
  "includeDescription": true,
  "onlyNew": false,
  "stateKey": "default",
  "secondsBetweenRequests": 1,
  "mode": "scrape"
}
```

# Actor output Schema

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

Public job postings from the Workday career sites you listed, one item per job (JSON, CSV, Excel or XML). Free error rows show sites or jobs that could not be read.

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

Per-site counts, failures by code, requests, bytes, why the run stopped.

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

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

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

```

## MCP server setup

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

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/IhXQgJzOURMhmgwHb/builds/n9A1fjj7RZS51KfET/openapi.json
