Workday Jobs Scraper | Descriptions & Salaries
Pricing
from $0.06 / 1,000 delivered jobs
Workday Jobs Scraper | Descriptions & Salaries
Scrape public Workday career sites for jobs, descriptions, locations and published salaries. Search keywords, filter posting dates and export JSON/CSV across multiple company boards.
Pricing
from $0.06 / 1,000 delivered jobs
Rating
0.0
(0)
Developer
tingyou333 zhuang
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Scrape public Workday career sites for jobs, descriptions, locations and published salaries. Search keywords, filter posting dates and export JSON/CSV across multiple company boards.
Useful for: Collect jobs from company career sites; filter newly posted roles; compare published salary ranges.
Why choose this Actor: Collect from multiple public Workday boards with job descriptions, exact posting-date filters and salary evidence. Saved results remain available if a later source request fails.
Try a small sample
- Click Try for free, then open Input and switch to JSON.
- Paste the example below and click Start. It uses a small result limit.
- Open the dataset to inspect results, then export JSON, CSV or Excel. Source restrictions can still cause partial or failed runs.
{"startUrls": [{"url": "https://workday.wd5.myworkdayjobs.com/Workday"}],"maxJobsPerSite": 5,"includeDetails": true}
Cost at a glance
Primary billing unit: Delivered job. Rates below are per 1,000 primary events.
| Free plan | Starter / Bronze | Scale / Silver | Business / Gold and higher |
|---|---|---|---|
| $0.08 | $0.08 | $0.072 | $0.064 |
Platform runtime usage is included. The Actor-start event is $0.0005 per GB of run memory, with a minimum of one event. Other event types, where enabled, are listed in the Pricing tab. “Try for free” uses available account credits; it does not make usage unlimited or unmetered.
Coverage to know: Use public career-site URLs, not internal HR portals. Salary fields depend on employer disclosures. Runtime is included in pricing; a platform Actor-start event also applies.
For Greenhouse, Lever, Ashby and other ATS jobs, see our companion Actor. It runs and bills separately.
Guides and full reference
Collect jobs from public Workday career sites without personal login credentials. This is an independently developed tool, not affiliated with or endorsed by Workday. Prices include platform runtime usage.
Inputs
startUrls accepts public career-site URLs using either tenant.wdN.myworkdayjobs.com/[locale/]Site or wdN.myworkdaysite.com/[locale/]recruiting/tenant/Site. Workday and Microchip sites have been cloud verified. Internal HR portals and application submission are not supported.
searchText: source-native keyword search; default empty.maxJobsPerSite: hard output cap per site; default0collects all matching jobs.includeDetails: defaulttrue; fetch native job details.descriptionFormat:both(default),html, ortext.postedAfter: inclusiveYYYY-MM-DDcutoff. Requires details; with details disabled it is ignored with a warning for competitor compatibility. Missing exact dates cause failure rather than guessed filtering.detailConcurrency: 1–10, default 5.errorOutputMode:report(default) for a jobs-only dataset, ordatasetto include unbilled source-error records alongside jobs.
Date filtering traverses the list until exhaustion or the output cap. A restrictive date filter may still require fetching every detail and incur resource costs despite few or zero returned jobs. No date-order early stop is assumed.
For API input, supply startUrls as URL objects, as shown above.
Output and delivery
Native job IDs, company, locations, country, exact posted date, description and source URLs are retained when available. Missing source fields remain null. Country can fall back to the native location country. Salary extraction preserves explicit currencies and multiple labeled ranges; ambiguous dollar signs do not imply USD, and sales deal amounts are excluded. Apply URLs are derived from public job paths. Rendered application pages were verified for Workday and Microchip; this does not establish support for every regional variant.
Validated batches are saved to the default dataset during traversal. If a later source page fails, previously delivered rows remain available and other requested sites are attempted. The overall run fails when any site fails; consult RUN_REPORT and RUN_ERROR for the affected site and its delivered count. SITE_SUMMARY includes successful and source-failed sites in attempted order. Failed entries have status: "failed", traversalComplete: false, confirmed deliveredRows and an error object. Available collection metadata is retained; unknown totals are omitted rather than reported as zero. Unattempted sites are counted separately in RUN_REPORT.unprocessedSites; uncertain storage failures still stop immediately. Successful entries retain source totals, facets and cap indicators. DELIVERY_PROGRESS records confirmed delivery counts. Its complete flag means processing finished without a recorded source failure or event-budget interruption; use each site's traversalComplete to distinguish a capped result from a full crawl.
An uncertain dataset write stops the run without application-level replay. Progress records do not implement restart/resume or an exactly-once guarantee. Some details fetched concurrently may exceed the requested output cap, although delivered results respect it.
Verified scope and current limits
Real cloud checks cover Workday's 388-job feed, full details, Workday and Microchip URL families, multiple sites, date and description filters, empty search, output limits and continued delivery after a failed site. Job-result event counts were verified against delivered rows for normal, empty, budget-limited and mixed-error runs. These owner-account tests establish behavior, not customer revenue or universal employer coverage.
A subsequent NVIDIA cloud run completed 15 public category branches and returned 2,606 unique full-detail jobs, beyond the unfiltered API's 2,000-result window. All 2,606 native IDs were unique, dataset fields passed schema checks, and job-result events matched delivered jobs. The three independently checked older jobs missing from the unfiltered result were present. This verifies one source snapshot; it is not a guarantee of every employer or future source changes.
Mid-stream transport and uncertain-write failures are covered by local fault injection. No exactly-once recovery or automatic restart of a failed crawl is promised. The API export example resumes observation and download of an existing run; it does not restart collection.
Result fields and integrations
| Group | Fields | Availability |
|---|---|---|
| Identity | resultType, title, tenant, siteId, sourceUrl, url, scrapedAt, totalJobsOnSite | List and detail modes |
| Listing | locationsText, postedOn, jobReqId, remoteType | Source dependent; details can refine values |
| Detail identity | workdayInternalId, jobPostingId, company, applyUrl | Detail mode; company may be null |
| Location | primaryLocation, additionalLocations, country, countryCode | Detail mode; native values only |
| Dates and work | postedDate, endDate, timeLeftToApply, timeType, canApply | Detail mode; source dependent |
| Description | descriptionHtml, descriptionText | Selected by descriptionFormat |
| Salary | salaryMin, salaryMax, salaryCurrency, salaryText, salaryRanges | Detail mode; extraction from published description |
salaryRanges contains {text, min, max, currency} records. The source text matters: the same posting can contain several geographic pay bands. Missing fields in list mode are not a promise of null-filled detail fields. Native dates and relative listing dates are distinct.
The dataset supports JSON/CSV export through Apify. Jobs, Salary evidence, Source identity and Diagnostics table views have been inspected with real output in Console. Output links expose the dataset, run report, site summaries and delivery progress.
For API automation, submit the input object to POST https://api.apify.com/v2/acts/peerless_columbine~workday-public-jobs-data/runs with your own Apify token in the Authorization header. Poll the returned run ID, then use its defaultDatasetId and defaultKeyValueStoreId to retrieve data and reports. Use your own Apify account token and check the current Pricing tab before starting a run. Check run status and reports before treating a dataset as complete. A dedicated n8n node is implemented under integrations/n8n in the source. Its installed-runtime validation and remaining distribution limits are described below. MCP uses Apify's hosted service.
Dedicated n8n node — installation preview
The n8n-nodes-workday-public-jobs package provides Get Jobs, Start Run and Resume Run operations. It retains the competing node's careersUrls, searchText, maxResults, includeDetails, descriptionFormat, postedAfter, output and fields parameters. Defaults are 25 jobs per site, full details, text descriptions and simplified output. Changing node type and selecting your own credentials is required; this is not a drop-in replacement for a third-party package name.
Jobs appear on the first output; run IDs, terminal status and source/delivery reports appear on the second. Exports paginate in batches of 1,000. Failed or budget-limited runs are rejected unless you explicitly allow partial output, which retains complete: false. An expired local wait returns the existing run ID for Resume Run. Disable automatic retry on Start Run/Get Jobs to avoid creating another paid run after a lost response. For long jobs, connect Start Run's second output through your durable Wait/Resume workflow. Full source exhaustion is separate from successful capped processing; inspect SITE_SUMMARY.
Installed n8n 2.38.1 validation covers loading the package, encrypted API-token credentials, resuming an existing run, and a new one-job Start → Resume workflow. The same run ID passed between nodes, a full-detail job and completion reports were returned, and cloud events matched one job plus one start. Separately, the node execute method downloaded an existing 2,606-job dataset in three pages and retained explicit failure state for a partial three-job dataset.
In n8n AI Agent tool mode, version 0.1.1 returns {jobs, run} envelopes so status, limits and reports remain visible alongside jobs. Ordinary nodes retain their two outputs. This fixes version 0.1.0's loss of the second output when n8n converted the node into an AI tool. Actual AI Agent 3.1 workflows in n8n 2.38.1 verified both a successful one-job run and a failed three-job partial run: the agent received the correct run IDs and complete/incomplete flags. These tests used a deterministic local chat-model fixture that requests the tool and echoes its response; they validate integration, not external LLM reasoning. No test model is bundled with the product.
The package and an inactive example workflow are included in the Actor source under integrations/n8n; a local tarball has been produced. Version 0.1.2 was also checked in the actual n8n 2.38.1 editor: manual Resume execution returned one job and one successful report item. Resume hides controls that only apply to new runs, and the Docs button links to this README. Version 0.1.3 additionally passed OAuth browser consent and an existing-run export in isolated n8n 2.38.1, using only the OAuth credential. An initial connection-closed error was followed by a successful retry of the same read: one job and one report, with no new Actor start. The local client was registered dynamically with Apify and used full_api_access and PKCE. No client secret or user token is included in the package. Token refresh, production callbacks, public npm distribution and public customer access remain unverified. Do not attempt an npm registry install under this name until a published package is announced. API-token credentials must belong to the invoking user; no credential is bundled with the node.
AI clients through MCP
Connect a client supporting Streamable HTTP to Apify's hosted MCP service. The configuration below uses the client's OAuth flow; each customer authorizes their own Apify account. Clients without OAuth can use their own token in an Authorization header. See the official MCP setup guide.
{"mcpServers": {"workday-jobs": {"url": "https://mcp.apify.com/?tools=peerless_columbine/workday-public-jobs-data,get-actor-run,get-dataset-items,get-key-value-store-record&telemetry-enabled=false"}}}
- Load tools and select
peerless_columbine--workday-public-jobs-data(client display names can differ). - Supply the Actor inputs, including an explicit
maxJobsPerSitecap. For example, use the input below.waitSecscontrols MCP waiting, not the Actor's execution deadline. - Save the returned
runId. If the run is still active, callget-actor-runwith that ID. A waiting timeout is not a reason to start a second paid run. - Retrieve jobs with
get-dataset-items, using the returned default dataset ID. Paginate withoffsetandlimit; a tool preview is not proof that all jobs have been retrieved. - Use
get-key-value-store-recordwith the returned default key-value-store ID to readRUN_REPORT,DELIVERY_PROGRESSandSITE_SUMMARY. Check failures, budget stops and each site'straversalCompletebefore treating a capped dataset as a complete source crawl.
{"startUrls":[{"url":"https://workday.wd5.myworkdayjobs.com/Workday"}],"maxJobsPerSite":1,"includeDetails":true,"descriptionFormat":"both","waitSecs":0}
Owner-account hosted MCP validation on September 9, 2026 completed tool discovery, asynchronous start, status polling, job retrieval and report retrieval: one full-detail job, one job-result event and one start event. The source listed 392 jobs; this deliberately capped test did not crawl all 392. It does not establish public customer access while the Actor remains private, client-specific OAuth UI acceptance, or x402 payment acceptance. No independent MCP server or separate MCP fee is bundled; normal Actor pricing applies. The hosted service may include auxiliary tools such as abort-run.
Example result
Selected fields from a verified public job, shown as a dated example rather than a guarantee that the job is still open. Description and other fields are omitted here for readability.
{"resultType": "job","title": "BT Strategic Operations & Enablement - Senior Director","company": "Workday, Inc.","tenant": "workday","siteId": "Workday","jobReqId": "JR-0109093","jobPostingId": "BT-Strategic-Operations---Enablement---Senior-Director_JR-0109093-1","workdayInternalId": "d70e85d4b5881001589826cf95cf0000","primaryLocation": "USA, CA, Pleasanton","additionalLocations": ["USA, GA, Atlanta"],"countryCode": "US","postedDate": "2026-09-08","salaryMin": 264700,"salaryMax": 397100,"salaryCurrency": "USD","url": "https://workday.wd5.myworkdayjobs.com/Workday/job/USA-CA-Pleasanton/BT-Strategic-Operations---Enablement---Senior-Director_JR-0109093-1","applyUrl": "https://workday.wd5.myworkdayjobs.com/Workday/job/USA-CA-Pleasanton/BT-Strategic-Operations---Enablement---Senior-Director_JR-0109093-1/apply"}
Pricing
| Event | Free / Bronze | Silver | Gold / Platinum / Diamond |
|---|---|---|---|
| 1,000 delivered jobs | $0.08 | $0.072 | $0.064 |
| Start, per allocated GB (minimum one) | $0.0005 | $0.0005 | $0.0005 |
Platform runtime resource usage is included. The automatic start fee also applies to empty and failed runs; filtered-out jobs and failed source requests have no job-result fee. At the default 128 MB allocation, the start event is charged once. Post-run storage/API access can incur standard Apify account costs. The Pricing tab shows the current configured rates.
Default run resources are 128 MB and 3,600 seconds. The 2,606-job NVIDIA run used 128 MB, concurrency 10 and a 1,800-second timeout, completing in about 728 seconds. The longer default timeout accommodates the default concurrency of 5 and larger sources; it is a time limit, not a fixed run duration. Larger sites or unusually large descriptions may need different run resources. Lower memory can take longer. Missing or failed pages produce an explicit failure, not a silently truncated success.
A site counted in completedSites has fulfilled the requested processing or output cap; this does not necessarily mean every source job was returned. Check traversalComplete for source exhaustion. If the output cap and spending limit are reached together, that site is complete for the requested cap while subsequent sites can remain unprocessed.
Error-row integration mode
Set errorOutputMode to dataset when your integration expects source errors in the dataset. The default report keeps a jobs-only dataset. In dataset mode, records with resultType: "error" include the site identity, error type and message, a troubleshooting hint and the number of jobs delivered before that site failed. They do not incur a job-result event charge; the run start fee still applies. The whole run remains failed if any site fails, while successful site jobs remain available. Filter resultType == "job" in job-processing workflows.
RUN_REPORT.deliveredRows counts jobs; errorRows counts diagnostics and totalDatasetRows counts both. Dataset row count alone is therefore not the billable job count in this mode. Invalid top-level inputs are rejected before collection. This provides the documented error-row workflow, but exact competitor error object keys have not been verified against a paid competitor run.
Source records without a public job page
Some career sites include a requisition identifier in their list but omit both its title and public path. The Actor continues through later pages and delivers valid jobs. It reports these unavailable records with their source offsets in RUN_ERROR.failures[].unavailableJobs, and marks the run failed rather than claiming full data completeness. collectionSummary.sourceTraversalComplete describes pagination only; it does not mean that unavailable job details were obtained. Unavailable records incur no job-result event. With errorOutputMode: "dataset", a diagnostic record is also saved without a job-result event.
Cross-page repeated jobs are not delivered or billed twice. The Actor continues later pages, records the repeated path and offset in the failure report, and marks the run incomplete: repeated listings can indicate that the live source changed while paging, so deduplicating alone cannot prove that no other job was missed. Source record diagnostics may contain either a requisition identifier or an external path, depending on what the public feed supplied.
For incomplete sources, RUN_ERROR.failures[].collectionSummary separates unavailableRows (no usable public job page), duplicateRows (repeated source positions), and sourceIssueRows (their sum). If a later source request fails, sourceFailure retains that cause alongside previously observed issues. sourceTraversalComplete reports whether all source pages were walked; traversalComplete remains false when distinct-job completeness cannot be established.
Python export and resume example
The Python client below uses only the standard library. Save it as export_jobs.py, and save the following input as input.json. The same files are included under examples/ in the source, but access to the Actor source is not required. Set APIFY_TOKEN in your environment, then run:
python3 export_jobs.py --input input.json --out-dir workday-export
It saves the run ID immediately and exports the dataset in pages, including datasets larger than 1,000 records. To observe an existing run without creating or paying for another run:
python3 export_jobs.py --run-id YOUR_RUN_ID --out-dir workday-export
The client saves available results even when the run fails or exhausts its event budget, marks the exported report incomplete, and exits with code 2. If a submission response is lost, inspect Console before submitting again. This is an API example, not a custom n8n node. Event caps do not universally limit platform resource spending.
Save as input.json
{"startUrls": [{"url": "https://workday.wd5.myworkdayjobs.com/Workday"}],"maxJobsPerSite": 20,"includeDetails": true,"descriptionFormat": "both","errorOutputMode": "dataset"}
Save as export_jobs.py
#!/usr/bin/env python3"""Standard-library API client; explicit resume and partial-result reporting."""import argparse,json,os,time,sysfrom pathlib import Pathfrom urllib.request import Request,urlopenfrom urllib.error import HTTPErrorfrom urllib.parse import urlencode,quoteBASE='https://api.apify.com/v2/'TERMINAL={'SUCCEEDED','FAILED','ABORTED','TIMED-OUT'}def request(path,token,body=None,missing_ok=False):data=json.dumps(body).encode() if body is not None else Nonereq=Request(BASE+path,data=data,headers={'Authorization':'Bearer '+token,'Content-Type':'application/json'})try:with urlopen(req,timeout=60) as response:return json.load(response)except HTTPError as exc:if missing_ok and exc.code==404:return Noneraise RuntimeError(f'Apify HTTP {exc.code}; inspect account access and run status') from Noneexcept (OSError,ValueError):detail='Run submission outcome is uncertain; inspect Console before submitting again.' if body is not None else 'Read failed; resume with the saved run ID.'raise RuntimeError(detail) from Nonedef download_dataset(dataset_id,token,call=request):rows=[]while True:batch=call('datasets/'+quote(dataset_id,safe='')+'/items?'+urlencode({'format':'json','clean':'true','limit':1000,'offset':len(rows)}),token)if not isinstance(batch,list):raise RuntimeError('Expected dataset array')rows.extend(batch)if len(batch)<1000:return rowsdef main(argv=None):parser=argparse.ArgumentParser(description=__doc__)source=parser.add_mutually_exclusive_group(required=True)source.add_argument('--input',type=Path,help='Actor input JSON file')source.add_argument('--run-id',help='Resume observing an existing run; does not create another run')parser.add_argument('--out-dir',type=Path,default=Path('workday-export'))parser.add_argument('--max-charge',type=float,default=.05,help='Per-run event spending cap in USD')args=parser.parse_args(argv)token=os.environ.get('APIFY_TOKEN')if not token:parser.error('Set APIFY_TOKEN in your environment; do not put it in the input JSON')if args.max_charge<=0:parser.error('--max-charge must be positive')args.out_dir.mkdir(parents=True,exist_ok=True);handle=args.out_dir/'run-id.txt'if args.input:if handle.exists():parser.error('This output directory already has a run ID. Resume with --run-id or choose another directory.')body=json.loads(args.input.read_text())result=request('acts/peerless_columbine~workday-public-jobs-data/runs?'+urlencode({'maxTotalChargeUsd':args.max_charge}),token,body)run_id=result['data']['id'];handle.write_text(run_id+'\n')else:run_id=args.run_idif handle.exists() and handle.read_text().strip()!=run_id:parser.error('Output directory belongs to a different run')handle.write_text(run_id+'\n')print('Run ID:',run_id,flush=True)while True:run=request('actor-runs/'+quote(run_id,safe=''),token)['data']if run['status'] in TERMINAL:breaktime.sleep(5)rows=download_dataset(run['defaultDatasetId'],token)report=request('key-value-stores/'+quote(run['defaultKeyValueStoreId'],safe='')+'/records/RUN_REPORT',token,missing_ok=True)incomplete=run['status']!='SUCCEEDED' or report is None or report.get('stoppedByBudget',False)(args.out_dir/'jobs-and-diagnostics.json').write_text(json.dumps(rows,ensure_ascii=False,indent=2))(args.out_dir/'report.json').write_text(json.dumps({'runId':run_id,'status':run['status'],'incomplete':incomplete,'recordCount':len(rows),'report':report},indent=2))print(f"{run['status']}: {len(rows)} records saved; incomplete={incomplete}")return 2 if incomplete else 0if __name__=='__main__':try:sys.exit(main())except RuntimeError as exc:print(str(exc),file=sys.stderr);sys.exit(1)
Large boards and capped source totals
The public NVIDIA feed was verified to report total=2000 and wrap offset2,000 back to its first page. Source-native category filters exposed older jobs absent from that unfiltered result. For large requests, the Actor snapshots public facet branches before fetching details, recursively adding another available facet when a branch remains capped. It then merges public paths and fetches each unique job once. A small output cap without a date filter keeps the direct path.
The original totalJobsOnSite remains the source's reported number for compatibility. listedCandidates is the merged candidate count. partitionReport records branch filters, counts, pages, cross-branch overlaps and missing requisition IDs. In this mode sourcePositionsTraversed counts positions processed in the merged candidate snapshot; partitionReport.partitionSourcePositions counts leaf-branch source positions, including overlaps. Neither is automatically a count of distinct complete jobs.
Changing branch counts, repeated pages within a branch, or a capped branch without another public facet cause explicit failure. Cross-branch overlap is expected and is deduplicated. Reported facet counts are never simply summed and advertised as distinct jobs. The partition implementation passed the 2,606-job NVIDIA cloud check described above; the earlier unfiltered 2,000-job run was incomplete. listPages counts merged-candidate processing pages in this mode; partitionReport.sourceListPages records actual source list requests.