# Workday Jobs Scraper & API: Any Career Site, No Login (`conserving_celerytop/workday-jobs-api`) Actor

Workday jobs scraper and API: every open job on the Workday career sites of the companies you name, read live where robots.txt allows. Title, department, location, job type, posted date and link. $0.10 per company, up to 1,000 jobs. No API key or login.

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

## Pricing

from $70.00 / 1,000 company lookups

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** gets every open job on the **Workday career sites** (myworkdayjobs.com) of the companies you name, read live during your run, where the site's robots.txt allows it: title, department, location, job type, posted date and link. Paste career site links. You pay **$0.10 per company**, with up to 1,000 jobs included, and there is no API key or login.

You pay **$0.10 per company**, including up to 1,000 jobs ($0.09 on the Scale plan, $0.07 on Business). Per job, that is $2 per 1,000 jobs for a company with 50 open jobs, $0.50 for one with 200, and $0.10 for one with 1,000. No API key or login. You bring the companies.

### What the Workday jobs scraper returns

- **Department.** `department` and `departmentPath` are the job category the site lists the job under, when it has one.
- **Location.** `location` as the site shows it; a job in several places shows its first place and how many more, and with descriptions every place.
- **Workplace type.** `workplaceType` is the site's remote type, else read from the location, and `remote` is true only for fully remote jobs.
- **Job type.** `employmentType` is Workday's time type, such as "Full time".
- **Posted date.** `postedAt` is the day the site shows, such as "Posted 3 Days Ago". For jobs 30 or more days old it is `null`, unless you add descriptions.
- **Links.** `url` and `applyUrl` are the job page.
- **Descriptions** need one request per job: $0.01 per started 200 jobs described (`jobDetailBlocksCharged`), and runs take longer.
- **Salary.** Workday has no pay field. Pay written in a description fills `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod`, `salarySource` and `salaryRanges`.
- **Large sites.** Sites with more than 2,000 open jobs are read in full, not cut at 2,000.

### How to scrape Workday jobs, step by step

1. In **Companies** (`companies`), paste Workday career site links (with `myworkdayjobs.com` or `myworkdaysite.com` in them) or company websites, up to 500. A job link reads the whole site. Or pick a list in **Ready-made company lists** (`companyLists`).
2. Set filters if you need them, such as **Title includes**, **Location** or **Posted since**, and turn on **Include job description** for the full text.
3. Run it. Each company costs $0.10, with up to 1,000 jobs included, charged when we contact its Workday site. Descriptions cost $0.01 per started 200 jobs described. Sites whose robots.txt does not allow us are free.
4. Open the **Jobs** view of the results. Set **Rows to return** (`outputMode`) to `companies` for one summary row per company instead.
5. To repeat it, save the input as a task and schedule it, as in [Get only new and closed Workday jobs on a schedule](#get-only-new-and-closed-workday-jobs-on-a-schedule).

### How to find a company's Workday link

If a job's address on the company's careers page contains `myworkdayjobs.com` or `myworkdaysite.com`, paste it: a job link reads the whole site. A search link keeps its filters; an employer's own domain is not recognised.

Or paste the company's website, and we look for its Workday link there. A plain name works only for employers in our directory; one that is not there is `not_found` and free, because no Workday site is contacted. `matchedBy` says how the site was found, and `companySlug` is its host and name.

#### Which sites are read

Each employer decides for its own site: we read its robots.txt first, and a site that does not allow us returns `unsupported_job_board`, free. We keep the load low, with at most 2 requests at a time per site.

### Fields on every job

`jobId` (ends with the requisition number), `jobKey` (the same in every run), `countryCode`, `country`, `city` and `region` from the location text, `locations` and `countryCodes`, `seniority` and `jobFunction` from the title, `employmentTypeNormalized` (such as `full_time`), `language` (read from the description, else the title), and `salaryAnnualMin` and `salaryAnnualMax` (hour x 2,080, day x 260, week x 52, month x 12). With descriptions: `description` without contact details, the `tools` it names, `experienceYearsMin`, `experienceYearsMax`, `experienceLevel`, `educationMin`, `educationRequired`, `visaSponsorship`, `visaSponsorshipText` and `securityClearance`. Rows also have the city's `latitude`, `longitude` and `timeZone`, `remoteRegions`, and `ukVisaSponsor` with `ukSponsorRoutes`.

### Filters

Filters lower the price above 1,000 jobs, and only matching jobs are described.

- **Words and places:** `titleIncludes` and `titleExcludes` (whole words), `department`, `location` (a country name or code, else whole words), `locationExcludes`, `remoteOnly`, `remoteRegions`, and `near` with `radiusKm` (distance from one city).
- **Values:** `workplaceTypes`, `employmentTypes`, `seniorities` and `jobFunctions`.
- **Dates:** `postedSince` and `postedBefore` (a date or a period such as `7 days`).
- **From the description** (they turn on `includeDescription` and its price): `languages`, `hasSalary`, `minAnnualSalary` in `minAnnualSalaryCurrency` (no exchange rates), `descriptionIncludes`, `skills` (sets `matchedSkills`), `maxExperienceYears` and `visaSponsorship`. `descriptionFormat` picks `text`, `html` or `markdown`.
- **Size:** `maxJobsPerCompany` keeps the newest jobs.

A job without the value a filter needs is left out, and `warning` counts them. `startUrls` and `urls` are other names for `companies`. `excludeCompanies` leaves companies out. `ukVisaSponsorOnly` keeps UK visa sponsors. `companyLists` adds ready-made lists and fills `companyName`, `companyIndustry`, `companyCountry` and `companySizeBand`.

### How much does the Workday jobs API cost?

| Event | Price | What you get |
|---|---|---|
| Company lookup (`company-lookup`) | $0.10 (Scale $0.09, Business $0.07) | One company's job list, up to 1,000 jobs, also a first check with **Only new jobs** |
| Extra 1,000 jobs (`extra-1000-jobs`) | $0.05 (see the Store page) | Each further 1,000 job rows of a company, or part of them |
| Description block (`job-details`) | $0.01 | Descriptions of 200 jobs, or part of them |
| New jobs check (`new-jobs-check`) | $0.002 | A later check with **Only new jobs**, per started 1,000 open jobs on the site |

So 100 companies cost $10 ($7 on the Business plan). A daily **Only new jobs** check of them then costs $0.20.

A website that links no job board costs the company price. A company over your spending limit is not charged.

### Get only new and closed Workday jobs on a schedule

Turn on **Only new jobs since my last check** (`onlyNewJobs`), save the input as a task, and schedule it. The first check returns the full list for the company price. Later checks return new and closed jobs (`change`, `alertText`) for $0.002 per started 1,000 open jobs on the site, and describe only new jobs.

**Alert webhook URL** (`alertWebhookUrl`) posts to Slack, Teams, Make, Zapier or n8n after a check with changes (`alertMaxJobs`, `alertOnFirstCheck`).

Rows have `firstSeenAt`, closed rows `closedAt` and `daysOpen`. `reposted` marks a new job matching one closed within 30 days; `skipReposts` leaves those out (`skippedRepostsCount`, `skippedReposts`). `includeUpdatedJobs` adds changed jobs, with `changedFields` and `previous`. Each `monitorName` keeps its own memory in your Apify account.

### For AI agents

Use it to answer "is company X hiring for Y right now?" for companies on Workday. Input (only `companies` is required, up to 500):

`{"companies": ["https://intel.wd1.myworkdayjobs.com/External", "https://adobe.wd5.myworkdayjobs.com/external_experienced"], "jobFunctions": ["engineering"], "postedSince": "7 days", "maxJobsPerCompany": 50}`

Output, one row per job: `company`, `companyStatus`, `title`, `department`, `location`, `workplaceType`, `employmentType`, `jobFunction`, `postedAt`, `url` and more, plus `description` with `includeDescription`. A company with no jobs gets a status row saying why.

Price: $0.10 per company with up to 1,000 jobs, charged when we contact its Workday site, also when that site is `not_found`; $0.01 per started 200 jobs described. More in [How much does the Workday jobs API cost?](#how-much-does-the-workday-jobs-api-cost). Sites whose robots.txt does not allow us, invalid entries, duplicates and other job boards are free.

Many companies, or companies on different job boards? [ATS Jobs API](https://apify.com/conserving_celerytop/live-career-page-jobs-api) reads Workday and 21 other job boards in one run for $0.045 per company.

### Output

A job row for a job on Intel's site on 26 September 2026, shortened. Unknown values are `null`.

```json
{
  "rowType": "job",
  "company": "https://intel.wd1.myworkdayjobs.com/External",
  "ats": "workday",
  "companyStatus": "ok",
  "charged": true,
  "jobId": "Senior-Business-Development-Manager_JR0287384",
  "title": "Senior Business Development Manager",
  "location": "US Washington DC (+2 more)",
  "postedAt": "2026-09-25T00:00:00.000Z",
  "url": "https://intel.wd1.myworkdayjobs.com/External/job/US-Washington-DC/Senior-Business-Development-Manager_JR0287384",
  "applyUrl": "https://intel.wd1.myworkdayjobs.com/External/job/US-Washington-DC/Senior-Business-Development-Manager_JR0287384"
}
```

Set **Rows to return** (`outputMode`) to `companies` for one summary row per company, or `both`. `rowType` is `job`, `company` or `status`. Summary rows have `boardUrl`, `openJobs`, `jobsPostedLast7Days`, `jobsPostedLast30Days`, `jobsOpenOver90Days`, `newestPostedAt`, `oldestPostedAt`, `remoteJobs`, `remoteShare`, `engineeringShare`, `salesShare`, `salaryCoverage`, `salaryMedians`, `medianSalaryMin`, `medianSalaryMax`, `medianSalaryCurrency`, `medianSalaryPeriod`, `topDepartments`, `topLocations`, `countries`, `seniorityCounts`, `functionCounts`, `functionCountsLast30Days`, `leadershipRoles` and `firstHireRoles`. Descriptions add `topTools`, `toolCoverage`, `visaSponsorshipShare` and `medianExperienceYearsMin`. **Only new jobs** adds `newJobs`, `closedJobs`, `updatedJobs`, `repostedJobs`, `medianDaysOpen`, `newFunctions`, `newCountries` and `previousCheckAt`.

The `COMPANIES` record has each company's status, with `inputDomain`, `careerPageSource`, `fetchedAt`, `error`, `chargedEvent`, `chargedEventCount`, `extraJobBlocksCharged`, `upstreamCalls`, `companyTotalOpenJobs`, `companyMatchedJobs`, `companyJobsReturned`, `companyJobsWithoutDate`, `newJobsCount`, `closedJobsCount`, `updatedJobsCount` and `firstCheck`.

### Statuses and charges

| `companyStatus` | Meaning | Charged |
|---|---|---|
| `ok`, `no_matching_jobs`, `no_open_jobs` | The site was read | Yes |
| `not_found` | Workday has no career site at this link | Yes, when we contacted Workday; free for a plain name that is not in our directory |
| `source_error` | Workday failed or did not answer | Yes |
| `no_job_board_found` | The website links no job board | Yes |
| `unsupported_job_board` | Another job board, a site whose robots.txt refuses us, or a blocklisted employer. `error` says why | No |
| `website_unavailable` | We could not read the website | No |
| `invalid_input`, `duplicate` | Not a link, website or name, or the same site as another entry | No |
| `skipped_time_limit`, `skipped_spending_limit` | Out of time, or over your spending limit | No |
| `skipped_client_disconnected` | Only in Live Jobs HTTP API. Your client disconnected first | No |
| `internal_error` | Something failed on our side | Only if it happened after we read the site |

### Other job boards: ATS Jobs API and more

This Actor reads only Workday. The same list of companies works in our other job Actors:

- [ATS Jobs API](https://apify.com/conserving_celerytop/live-career-page-jobs-api): 22 job boards in one run, when you do not know which board a company uses.
- [Greenhouse Jobs Scraper & API](https://apify.com/conserving_celerytop/greenhouse-jobs-api)
- [Lever Jobs Scraper & API](https://apify.com/conserving_celerytop/lever-jobs-api)
- [Ashby Jobs Scraper & API](https://apify.com/conserving_celerytop/ashby-jobs-api)
- [Tech Jobs Search](https://apify.com/conserving_celerytop/tech-jobs-search): search the open jobs of 824 companies by keyword, place and salary.
- [Live Jobs HTTP API](https://apify.com/conserving_celerytop/live-jobs-http-api): the same job data in one HTTP request, for scripts, Clay and no-code tools.
- [Website Tech Stack Detector](https://apify.com/conserving_celerytop/website-tech-stack-detector): the CMS, analytics and other tools on the same companies' websites.

### FAQ

**Is this an official Workday API?** No. It reads the public job lists each Workday career site shows to visitors, where the employer's robots.txt allows it, and never apply or login pages. It is not affiliated with or endorsed by Workday, Inc. or any employer whose site it reads. Workday is a trademark of its owner.

**My company does not want its site read.** Open an issue on the **Issues** tab, and we add it to our blocklist.

**Why `not_found`?** The site name after the host, such as `/External`, is part of the link.

Found a problem? Open an issue on the **Issues** tab.

**Related Actors.** [Live Jobs HTTP API](https://apify.com/conserving_celerytop/live-jobs-http-api) returns jobs in one HTTP response, at its own prices plus platform usage.

# Actor input Schema

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

Workday career site links, up to 500, such as intel.wd1.myworkdayjobs.com/External. A website is searched for its Workday link. A plain name works only for employers in our directory. A site whose robots.txt refuses us is free and not read. $0.10 per company, 1,000 jobs included, also when not found. Other boards' links are free. For other job boards, use the Actor "ATS Jobs API: Greenhouse, Lever & Ashby Jobs, No Login", which reads 22 job boards.

## `companyLists` (type: `array`):

Run on ready-made lists of companies instead of, or next to, your own list in Companies. Each company in a list is one company lookup ($0.10, 1,000 jobs included), and filters such as title, location and posted date apply as usual. To run only the lists, clear Companies. A company in two lists, or in a list and in Companies, is read and charged once. At most 500 companies per run in all. The lists are refreshed monthly. API value: a list such as \["ai-companies"].

## `excludeCompanies` (type: `array`):

Companies to leave out, such as your own employer or companies you already track: company names, websites or job board links, up to 1,000. Most useful with Ready-made company lists. A company left out is not read and not charged. Leave empty to keep every company.

## `outputMode` (type: `string`):

jobs: one row per job. companies: one summary row per company with open jobs, jobs posted in the last 7 and 30 days, remote share, top departments, locations, countries, seniority, job functions, leadership and first-hire roles, salary medians, top tools, and new and closed jobs with Only new jobs. Counts use every job passing your filters. It costs one lookup per company, never the extra 1,000-job charge. both: job rows plus summary rows (rowType job, company or status).

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

true: add each job's full description as plain text, up to 60,000 characters, without emails, phone numbers or profile links, and the tools it names (field tools). Workday needs one request per job, so this costs $0.01 per started 200 jobs described, and a run takes longer. Pay written in a description fills the salary. With Only new jobs, only new jobs are described. At your spending limit, the rest come without one.

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

How each description comes, with Include job description on. text: plain text. html: the board's own HTML, kept safe: no scripts, styles, frames or event handlers, only basic tags such as paragraphs, headings, lists, bold and links. markdown: the same converted to Markdown (headings, lists, links, bold). Every format has emails, phone numbers and profile links removed and is cut at 60,000 characters. Same price.

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

Return at most this many jobs per company, the newest first, for example 50. To answer a quick question, 20 is enough. Leave empty for all jobs, up to 10,000 per company. Set 1,000 or less to never pay the $0.05 charge for each further 1,000 jobs. With Only new jobs, closed jobs come on top of this cap and count toward that charge. Summary rows still count every matching job.

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

true: return only jobs you have not received from this Actor before, plus jobs that closed since your previous check (field change is new or closed). The first check of a company returns all its jobs for $0.10. A later check costs $0.002 per started 1,000 open jobs on the board, so $0.002 for 300 jobs and $0.006 for 2,400. Use it with a schedule. What you received is saved in your own Apify account, per Monitor name and set of filters. Default false.

## `monitorName` (type: `string`):

Only used with Only new jobs. Name of the saved list of jobs you received, so separate watchlists do not mix, for example sales-accounts or competitors. Letters, numbers, - and \_ only, up to 40 characters. Default: default.

## `includeUpdatedJobs` (type: `boolean`):

Only used with Only new jobs. true: also return jobs you received before whose title, location, salary or job type changed since your previous check, with change updated, changedFields and the previous values. Each is one more row, so it counts toward the $0.05 per further 1,000 jobs. Default false: the price stays the same and changes are only counted in summary rows.

## `skipReposts` (type: `boolean`):

Only used with Only new jobs. true: leave out a new job with the same title and location as a job you received that closed in the last 30 days, a repost under a new id. It gets no row, is not counted as new and is not in the alert, and it never comes back as new. The company's status (skippedRepostsCount) and summary row (skippedReposts) say how many were left out. Default false: reposts come as new jobs with reposted true.

## `alertWebhookUrl` (type: `string`):

Only used with Only new jobs. An https link that gets one short message after a check with new or closed jobs, and nothing on days without changes. Paste the incoming webhook link of a Slack, Discord or Teams channel, or a Make, Zapier or n8n webhook, such as https://hooks.slack.com/services/... The message has the counts per company and the jobs with their links. Free. Kept secret. Leave empty for no alert.

## `alertMaxJobs` (type: `integer`):

Only used with Alert webhook URL. How many new and closed jobs the alert lists, one line each with title, location and salary when known, for example 20. More jobs are counted with a link to the dataset. A whole number from 1 to 50. Free. Default 10.

## `alertOnFirstCheck` (type: `boolean`):

Only used with Alert webhook URL. true: also send an alert on the first check of a company, which returns all its open jobs as new. Default false: the first check sends nothing, and later checks alert only on new and closed jobs. Free.

## `titleIncludes` (type: `array`):

Keep only jobs whose title contains one of these words or phrases, ignoring case. Use it to check if a company is hiring for a role, for example data engineer or account executive. Whole words only, so engineer matches Software Engineer but not Engineering Manager. A list of up to 100. Leave empty for all titles.

## `department` (type: `string`):

Keep only jobs whose department, team or department path contains this text, ignoring case, for example engineering. For several, put one per line. A job that matches any of them is kept. In API input, put a line break between values, as in "engineering\nsales". Up to 100. Leave empty for all departments.

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

Keep only jobs in this place, such as London, California or Germany. A country name or code (Germany, DE) keeps jobs in that country, so DE does not keep Rio de Janeiro. A US state or Canadian province keeps its region, so California keeps San Mateo, CA. Other text matches whole words, so York keeps New York, not Yorkshire. For several, put one per line. Any match keeps a job. In API input, put a line break between values. For remote jobs use Remote only. Leave empty for all.

## `locationExcludes` (type: `array`):

Leave out jobs in any of these places, matched like Location: India or IN also leaves out jobs in Bangalore, and California leaves out San Mateo, CA. A job with several places is left out when any of them matches. Jobs with no location are kept. A list of up to 100, for example India and Brazil. Leave empty to keep every location.

## `near` (type: `string`):

Keep only jobs within the distance below of one city, such as Berlin or Austin, TX. Add the country or US state to a shared name (Cambridge, UK). Distances run from each city's center, and every place of a job counts. A remote job is kept only when it lists such a place; do not combine with Remote only. Jobs whose city we do not know (only a country, or a town under 15,000 people) are left out; the warning counts them. An unknown city stops the run free, with close matches.

## `radiusKm` (type: `integer`):

How far from the city in Near a city a job may be, in kilometers, from 1 to 500. Default 50. Used only with Near a city.

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

true: keep only jobs that can be done fully remote. Hybrid and on-site jobs are left out. Default false.

## `remoteRegions` (type: `array`):

Keep only remote jobs open to one of these places: worldwide, americas, us, canada, latam, emea, europe, uk, apac, or a country code such as DE. Read from the job's location and title, for example Remote - US or Remote (EMEA). A job open worldwide matches every value, and a region matches the countries in it: europe keeps a job open in Germany. Remote jobs whose places are unknown are left out, and the warning says how many. Leave empty to keep every job.

## `workplaceTypes` (type: `array`):

Keep only jobs with one of these workplace types: remote, hybrid or onsite (field workplaceType), from the site's remote type where the employer sets one, else read from the location text. Jobs whose workplace type is unknown are left out, and the company's warning says how many. Leave empty for all jobs.

## `employmentTypes` (type: `array`):

Keep only jobs with one of these job types (field employmentTypeNormalized), from the Workday time type (such as Full time or Part time) or title words like Intern. Jobs whose type is unknown are left out, and the company's warning says how many. Leave empty for all.

## `seniorities` (type: `array`):

Keep only jobs at one of these levels (field seniority), read from the title: Senior Engineer is senior, Head of Sales is director. A title without a level word, such as Software Engineer, has no seniority: those jobs are left out, and the company's warning says how many. Leave empty for all levels.

## `jobFunctions` (type: `array`):

Keep only jobs in these functions, read from each job's title, then its department and team (output field jobFunction). Pick one or more, for example Engineering and Data. English and German titles are read, and basic French, Spanish, Dutch and Swedish ones. In our tests about 9 in 10 jobs got the right function. API value: a list such as \["engineering", "data"]. Leave empty for all functions.

## `languages` (type: `array`):

Keep only jobs written in one of these languages, as two-letter codes such as en, de, fr, es, nl or pt (field language). Workday gives no language, so it is read from the description: this turns on Include job description, at $0.01 per started 200 jobs described. Jobs whose language is unknown are left out, and the company's warning says how many.

## `titleExcludes` (type: `array`):

Leave out jobs whose title contains any of these words or phrases, ignoring case. Whole words only, so intern does not match International. A list of up to 100, for example senior and intern. An excluded word wins over Title includes. Leave empty to keep every title.

## `descriptionIncludes` (type: `array`):

Keep only jobs whose description names any of these words or phrases, ignoring case, such as Snowflake, Rust or C++. Whole words only, so Rust does not match trust. A tool also matches its other names, so Postgres finds PostgreSQL. Up to 100. This reads the description, so it turns on Include job description, at $0.01 per started 200 jobs described. Leave empty for all jobs.

## `skills` (type: `array`):

Keep only jobs that name at least one of these skills in their tools, such as Python, Snowflake or Salesforce, ignoring case. Other spellings work, so golang finds Go. Each job lists the ones it has in matchedSkills. A word that is not a skill we know stops the run before any charge and names close skills. Up to 100. This turns on Include job description, with its price on the boards that need one request per job (see Pricing). Leave empty for all jobs.

## `hasSalary` (type: `boolean`):

true: keep only jobs with a salary (salaryMin or salaryMax). Workday has no pay field, so pay is read from the description: this turns on Include job description, at $0.01 per started 200 jobs described. Default false.

## `minAnnualSalary` (type: `integer`):

Keep jobs whose yearly salary reaches this amount, such as 120000: the top of the range (salaryAnnualMax, else salaryAnnualMin), in the currency below. Workday pay is read from the description, so this turns on Include job description, at $0.01 per started 200 jobs described. No exchange rates: jobs paid in another currency, and jobs with no yearly salary are left out; the warning says how many. Empty for no minimum.

## `minAnnualSalaryCurrency` (type: `string`):

Currency of Minimum yearly salary, as a three-letter code such as USD, EUR or GBP. Only jobs whose salary is in this currency can pass. Used only with Minimum yearly salary. Default USD.

## `postedSince` (type: `string`):

Keep only jobs posted on or after this date. Use a date as YYYY-MM-DD, for example 2026-09-01, or a period as a number plus hours, days, weeks, months or years, for example 24 hours or 7 days. A period counts back from the start of each run, which suits schedules. Jobs whose board gives no posting date are left out. Leave empty for all dates.

## `postedBefore` (type: `string`):

Keep only jobs posted before this date. Use a date as YYYY-MM-DD, for example 2026-06-01, or a period such as 30 days for jobs posted more than 30 days ago. With Posted since it gives a date range. Jobs whose board gives no posting date are left out, and the company's warning says how many. Leave empty for all dates.

## `maxExperienceYears` (type: `integer`):

Keep only jobs whose description asks for at most this many years of experience, read from phrases like 5+ years or mindestens 3 Jahre. A whole number from 0 to 50, for example 3. Jobs that give no years are left out, and the warning says how many. This reads the description, so it turns on Include job description, also with Rows to return: companies, at $0.01 per started 200 jobs described. Leave empty for all.

## `visaSponsorship` (type: `boolean`):

true: keep only jobs whose description says the company sponsors visas. Jobs that do not mention it are left out, and the warning says how many. This reads the description, so it turns on Include job description, also with Rows to return: companies, at $0.01 per started 200 jobs described. Default false.

## `ukVisaSponsorOnly` (type: `boolean`):

true: keep only jobs at companies on the UK Home Office register of licensed sponsors for workers (ukVisaSponsor true). The company name must match a register name exactly, once words like Ltd, Limited, PLC and UK are set aside, so a company listed under another legal name is left out, and so is a name too short or too common to match safely. The warning says why. Default false.

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

Another name for Companies, so input written for other Actors works: links as strings or as {"url": "..."} objects. Merged into Companies.

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

Another name for Companies, so input written for other Actors works: links as strings or as {"url": "..."} objects. Merged into Companies.

## Actor input object example

```json
{
  "companies": [
    "https://intel.wd1.myworkdayjobs.com/External",
    "https://adobe.wd5.myworkdayjobs.com/external_experienced",
    "https://salesforce.wd12.myworkdayjobs.com/External_Career_Site"
  ],
  "excludeCompanies": [
    "openai",
    "stripe.com"
  ],
  "outputMode": "jobs",
  "includeDescription": false,
  "descriptionFormat": "text",
  "maxJobsPerCompany": 50,
  "onlyNewJobs": false,
  "monitorName": "default",
  "includeUpdatedJobs": false,
  "skipReposts": false,
  "alertMaxJobs": 10,
  "alertOnFirstCheck": false,
  "titleIncludes": [
    "engineer"
  ],
  "department": "engineering",
  "location": "London",
  "near": "Berlin",
  "radiusKm": 50,
  "remoteOnly": false,
  "jobFunctions": [
    "engineering",
    "data"
  ],
  "descriptionIncludes": [
    "Snowflake",
    "dbt"
  ],
  "skills": [
    "Python",
    "Kubernetes"
  ],
  "hasSalary": false,
  "minAnnualSalaryCurrency": "USD",
  "postedSince": "7 days",
  "visaSponsorship": false,
  "ukVisaSponsorOnly": false
}
```

# Actor output Schema

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

Dataset items, one per job: company, companyName, matchedBy, companyStatus, title, department, team, location, countryCode, city, remote, seniority, jobFunction, employment type, salary with its yearly value, tools (with descriptions), postedAt and url. The dataset has more fields (jobId, applyUrl, description, country, region, salaryRanges, charged, warning, error); read it with fields=... to keep only what you need.

## `companies` (type: `string`):

JSON array, one object per company in input order: companyStatus (ok, no\_open\_jobs, not\_found, no\_job\_board\_found, invalid\_input and others), charged, chargedEvent, companyName, matchedBy (link, website, directory, name or name variant), inputDomain and boardUrl for websites, companyTotalOpenJobs, companyMatchedJobs, companyJobsReturned, newJobsCount, closedJobsCount, updatedJobsCount, error and warning.

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

Dataset items with rowType company, one per company, when Rows to return is companies or both: openJobs, jobs posted in the last 7 and 30 days, jobs open over 90 days, remote, engineering and sales shares, top departments, locations and countries, seniority and job function counts, jobs per function posted in the last 30 days, leadership and first-hire roles, top tools, salary medians, and new, closed, updated and reposted jobs with Only new jobs. With jobs, this view has no summary rows.

# 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://intel.wd1.myworkdayjobs.com/External",
        "https://adobe.wd5.myworkdayjobs.com/external_experienced",
        "https://salesforce.wd12.myworkdayjobs.com/External_Career_Site"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("conserving_celerytop/workday-jobs-api").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://intel.wd1.myworkdayjobs.com/External",
        "https://adobe.wd5.myworkdayjobs.com/external_experienced",
        "https://salesforce.wd12.myworkdayjobs.com/External_Career_Site",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("conserving_celerytop/workday-jobs-api").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://intel.wd1.myworkdayjobs.com/External",
    "https://adobe.wd5.myworkdayjobs.com/external_experienced",
    "https://salesforce.wd12.myworkdayjobs.com/External_Career_Site"
  ]
}' |
apify call conserving_celerytop/workday-jobs-api --silent --output-dataset

```

## MCP server setup

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

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/dzO4AdgqiItCj7RLz/builds/9cPcL2MfXJiBbFGyn/openapi.json
