Workable Jobs Monitor & Scraper avatar

Workable Jobs Monitor & Scraper

Pricing

from $0.90 / 1,000 job rows

Go to Apify Store
Workable Jobs Monitor & Scraper

Workable Jobs Monitor & Scraper

Scrape public jobs from Workable company career pages and jobs.workable.com search: descriptions, locations, departments and optional salary. Monitor mode returns only new, changed and removed jobs.

Pricing

from $0.90 / 1,000 job rows

Rating

0.0

(0)

Developer

Cliqto Media

Cliqto Media

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Workable jobs to clean data: company career pages and job search, with new, changed and removed jobs

Workable Jobs Monitor & Scraper collects public jobs from company career pages on Workable (apply.workable.com/<company>) and from the Workable job search (jobs.workable.com). It returns one clean row per job, and on a schedule it can return only new, changed and removed jobs.

Use it to track hiring at companies you care about, to build a job feed, or to find job leads by keyword and location. The smallest run is one company name, for example costello-medical.

Table of contents

What it does

The Actor reads two public Workable sources. No login, cookie or Workable API key is needed.

  1. Company career pages. Add a company name or its career page URL. The Actor returns every published job of that company with title, locations, department, employment type, experience, industry, posting date, links and the full job description split into description, requirements and benefits. This uses 2 requests per company, even for companies with hundreds of jobs.
  2. Workable job search. Add keywords and/or a location. The Actor goes through the search results page by page (20 jobs per page) and returns each job with company, location, workplace type and description.

Every run also saves a short status report: for each company and search you see complete, partial, not_found, error or skipped, with the reason. A company that does not exist or a blocked request never looks like a successful empty result.

Good fit

  • Watch the career pages of competitors, clients or target accounts and get new jobs every day.
  • Build a job board or a job alert from Workable companies and keywords.
  • Collect hiring signals (department, location, seniority) for sales or market research.

Not a fit / limits

  • Only public, published jobs. No applicant data, no private postings.
  • Companies with their own career site and no apply.workable.com/<company> page are not supported.
  • Salary is published by only some employers. You get it only with Add salary and exact workplace type on, and only for company pages. The search does not return salary.
  • Workable limits how many requests one IP address can make per day. Large runs can stop early with a clear partial status (see Pricing and limits).
  • Up to 5,000 jobs per run.

Quick start

  1. Open the Input tab.
  2. In Companies on Workable (companies) keep the prefilled costello-medical or add your own company name or URL.
  3. Keep the other settings as they are. By default the Actor returns all current jobs (mode: all).
  4. Click Start.
  5. Open the Output tab. The table shows one row per job with title, company, location and job URL.

Expected result: about 20–30 rows for costello-medical (the number changes when the company hires), and status complete in the run summary.

Use cases

Buyer jobInput pathOutput entityKey fieldsNext step
Track hiring at known companiescompanies + mode: changes on a schedulenew / changed / removed jobchange_type, title, location, urlSend new rows to Slack, email or a sheet
Find jobs by keyword and placesearchKeywords + searchLocationjobtitle, company_title, workplace_type, date_postedJob board, alert, CRM
Hiring signals for salescompaniesjobdepartment, experience, function, locationsLead scoring
Salary research (where published)companies + includeDetails: truejobsalary_min, salary_max, salary_currency, salary_periodSpreadsheet

Input

Input fields

FieldPlain nameTypeRequiredDefault / prefillAllowed valuesEffectExampleRecommendation
companiesCompanies on Workablearray of stringsone of companies, searchKeywords, searchLocationprefill ["costello-medical"]up to 200; company name, https://apply.workable.com/<company>/, a job URL of that company, or https://<company>.workable.comReads each company career page["treatwell", "https://apply.workable.com/skroutz/"]Use the name from the career page URL
searchKeywordsSearch keywordsarray of stringssee aboveemptyup to 20, each up to 100 charactersOne Workable search per keyword["data analyst"]Short role names work best
searchLocationSearch locationstringsee aboveemptyup to 100 charactersLocation for every keyword search; can be used alone"United Kingdom"Use a country or city name
postedWithinPosted withinstringnoanyany, 24h, 7d, 30dKeeps only recent jobs (search and companies)"7d"Use 24h or 7d for daily alerts
workplaceTypesWorkplace typearraynoempty (all)remote, hybrid, on_siteKeeps only these workplace types["remote"]For companies, hybrid/on-site need includeDetails
titleKeywordsJob title must containarray of stringsnoemptyup to 50Keeps jobs whose title contains any word["engineer"]Matching is "contains", not case-sensitive
excludeTitleKeywordsJob title must not containarray of stringsnoemptyup to 50Drops jobs whose title contains any word["intern"]"intern" also drops "International"
locationKeywordsLocation must containarray of stringsnoemptyup to 50Keeps jobs with a matching location["germany"]Checks all locations of a job
departmentKeywordsDepartment must containarray of stringsnoemptyup to 50Keeps jobs with a matching department["sales"]Many jobs have no department
includeDetailsAdd salary and exact workplace type (companies)booleannofalsetrue, false+1 request per company job: adds salary and hybrid/on-sitetrueUse for small runs only; Workable limits these requests per day
modeModestringnoallall, changeschanges returns only new, changed and removed jobs since the last run"changes"Use changes on a schedule
monitorStateKeyMonitor namestringnobuilt from your sources and filtersletters, digits, -, _; 1–60Runs with the same name share memory"competitors-daily"Set it if you plan to edit the input later
includeUnchangedAlso return unchanged jobsbooleannofalsetrue, falseIn changes mode also returns unchanged jobstrueUse when you want the full list plus labels
maxJobsPerSourceMax jobs per company or searchintegerno10001–5000Stops one company or search; it becomes partial200Lower it for quick tests
maxJobsTotalMax jobs per runintegerno50001–5000Stops the whole run500Split bigger work into several runs

Empty input: the run fails at once with a clear message and makes no requests. Duplicate companies (for example a name and the same company URL) are read once. Duplicate jobs inside one search are returned once.

Interacting settings

WhenInput AInput BEffective behaviorCost/result effect
Keywords and locationsearchKeywordssearchLocationEach keyword is searched in that locationOne search per keyword
Only a locationsearchLocationno keywordsOne search for all jobs in that locationBig locations reach the limits fast
Workplace filter on companiesworkplaceTypesincludeDetails: falseOnly remote jobs are recognized; hybrid and on-site are unknownTurn on includeDetails to filter hybrid/on-site
LimitsmaxJobsPerSourcemaxJobsTotalThe smaller limit wins; later sources become skippedYou pay only for returned rows
Monitoring and limitsmode: changesa source is partialNo removed rows for that source in that runPrevents false "removed" jobs

Input examples

All jobs of two companies

{
"companies": ["costello-medical", "https://apply.workable.com/treatwell/"]
}

Expected behavior: 4 requests, one row per job. Expected output: title, company_title, locations, department, description_text. Limit or cost note: no salary in this mode.

Search with filters

{
"searchKeywords": ["software engineer"],
"searchLocation": "United States",
"postedWithin": "7d",
"maxJobsPerSource": 100
}

Expected behavior: up to 5 search pages; the search is partial if more jobs exist. Expected output: title, company_title, location, workplace_type, url.

Daily monitoring

{
"companies": ["costello-medical", "treatwell"],
"searchKeywords": ["data analyst"],
"searchLocation": "United Kingdom",
"mode": "changes",
"monitorStateKey": "uk-analysts"
}

Expected behavior: the first run returns all current jobs as new. Next runs return only new, changed and removed jobs.

Output

Each Dataset row is one job (or one change in changes mode). Every row has all fields below. A field is null when Workable does not publish the value or when it does not apply to that source.

Output fields

FieldMeaningTypeCan be empty?Example / enumNotes
idStable job IDstringno266B371E9CCompany: Workable shortcode. Search: Workable job ID
source_typeWhere the row comes fromstringnocompany, search
source_inputCompany name or search textstringnocostello-medical, software engineer @ United States
titleJob titlestringnoAccounts Assistant
statePublication statestringyespublishednull on removed rows
languageJob languagestringyesenSearch, or companies with includeDetails
date_postedPosting date (ISO 8601)stringyes2026-09-23T00:00:00.000ZCompany pages publish the date only
date_updatedLast update (ISO 8601)stringyes2026-04-03T07:23:15.597ZSearch only
urlJob pagestringnohttps://apply.workable.com/costello-medical/j/266B371E9C/
application_urlApply pagestringyes…/j/266B371E9C/apply/Companies only
shortcodeWorkable job shortcodestringyes266B371E9CCompanies only
company_slugCompany name in the URLstringyescostello-medicalCompanies only
company_idWorkable company IDstringyesUUID
company_titleCompany namestringyesCostello Medical
company_websiteCompany websitestringyesURL
company_urlCompany page on Workablestringyeshttps://apply.workable.com/costello-medical/
company_imageCompany logo URLstringyesURL
locationMain locationstringyesBoston, Massachusetts, United States
location_cityCitystringyesBoston
location_subregionState or regionstringyesMassachusetts
location_countryCountrystringyesUnited States
location_country_codeCountry codestringyesUSCompanies only
locationsAll locationsarray of stringsno (can be [])["Boston, Massachusetts, United States"]Search may include TELECOMMUTE
workplace_typeWorkplacestringyesremote, hybrid, on_siteCompanies without includeDetails: only remote or null
employment_typeEmployment typestringyesFull-time, Contract
departmentDepartmentstringyesOperations
experienceSenioritystringyesEntry levelCompanies only
industryIndustrystringyesPharmaceuticalsCompanies only
functionJob functionstringyesFinanceCompanies only
educationEducationstringyesUnspecifiedCompanies only
salary_minSalary fromnumberyes33250Companies + includeDetails, when published
salary_maxSalary tonumberyes43450as above
salary_currencyCurrencystringyesEURas above
salary_periodSalary periodstringyesyearas above
is_featuredFeatured in searchbooleanyesfalseSearch only
social_sharing_descriptionShort summarystringyestextSearch only
description_htmlMain description (HTML)stringyesHTML
description_textMain description (plain text)stringyestext
requirementsRequirements (plain text)stringyestext
requirements_htmlRequirements (HTML)stringyesHTML
benefitsBenefits (plain text)stringyestext
benefits_htmlBenefits (HTML)stringyesHTML
details_errorWhy salary/workplace are missingstringyesDAILY_LIMIT, HTTP_ERROROnly with includeDetails
source_query_keywordSearch keywordstringyessoftware engineerSearch only
source_query_locationSearch locationstringyesUnited StatesSearch only
change_typeChange since last runstringyesnew, changed, unchanged, removednull in mode: all
first_seen_atFirst time this monitor saw the jobstringyesISO 8601changes mode only
content_hashFingerprint of the job contentstringno64 hex charactersUsed to detect changes
scraped_atWhen the row was madestringnoISO 8601

When an employer writes everything in one text, requirements and benefits stay null and the full text is in description_html.

Output surfaces

SituationWhereShapeWhat to do
Normal jobDataset (Output tab)one row per jobOpen, filter or export
Company has no open jobsDataset + OUTPUTno rows; source complete, jobs_found: 0Nothing to fix
Company name does not existOUTPUTsource not_foundCheck the company name
Limit reached or Workable daily limitDataset + OUTPUTrows found so far; source partial with reasonRaise the limit or run the rest later
Every source failedrun status Failed + OUTPUTstatus: failed with reasonRead the message and retry later

The key-value store record OUTPUT has the run result and one entry per company/search: status, reason, jobs_found, jobs_matched, jobs_emitted, new, changed, removed. RUN_SUMMARY adds timing, request counts, filters and the monitor name.

Output example

Input: {"companies": ["costello-medical"]}. One real row, long texts shortened:

{
"id": "266B371E9C",
"source_type": "company",
"source_input": "costello-medical",
"title": "Accounts Assistant",
"state": "published",
"date_posted": "2026-09-23T00:00:00.000Z",
"url": "https://apply.workable.com/costello-medical/j/266B371E9C/",
"application_url": "https://apply.workable.com/costello-medical/j/266B371E9C/apply/",
"company_title": "Costello Medical",
"company_url": "https://apply.workable.com/costello-medical/",
"location": "Boston, Massachusetts, United States",
"location_country_code": "US",
"locations": ["Boston, Massachusetts, United States"],
"workplace_type": null,
"employment_type": "Full-time",
"department": "Operations",
"experience": "Entry level",
"industry": "Pharmaceuticals",
"function": "Finance",
"salary_min": null,
"description_text": "Role Summary\n\n- Responsibilities: By stepping into the Accounts Assistant role at Costello Medical, you will support …",
"requirements": "About You\n\nWe are looking for an enthusiastic and ambitious individual …",
"benefits": "About Costello Medical\n\nCostello Medical is a rapidly growing global healthcare agency …",
"change_type": null,
"content_hash": "…"
}

Monitoring: only new, changed and removed jobs

Set mode to changes and run the same input on a schedule.

  • First run: there is no memory yet, so every current job is returned as new.
  • Next runs: you get only new jobs, changed jobs (title, locations, workplace, department, salary, description or apply link changed) and removed jobs (no longer published). If nothing changed, the Dataset is empty and OUTPUT shows 0 new, 0 changed, 0 removed.
  • Removed jobs are reported only when the company or search was read completely in that run. If a source is partial or failed, its old jobs are kept and checked again next time, so a temporary problem does not create false removed rows.
  • Memory is kept in your account in the key-value store workable-jobs-monitor-state, one record per monitor name. If you change companies, searches or filters, a new monitor name is made automatically and the first run is a new baseline. Set monitorStateKey to keep the same memory.
  • For searches with postedWithin, jobs that only got older than the window are not reported as removed.

Pricing and limits

Pricing unit

This Actor uses pay per event:

  • $0.002 per run start (Apify run start event, one per GB of memory; the default 512 MB counts as one).
  • $0.0009 per job row saved to the Dataset. In changes mode you pay only for returned rows (new, changed, removed, and unchanged only if you ask for them).

The OUTPUT and RUN_SUMMARY records are free. Companies or searches that return nothing do not add row charges. Use Max charge per run in the run options to cap the cost; the Actor stops saving rows when the cap is reached and marks the run partial.

Cost examples

ScenarioInput scopeRowsPrice
One small companycostello-medical~26~$0.025
100 jobssearch with maxJobsPerSource: 100100$0.092
1,000 jobsseveral companies1,000$0.902
Run maximummaxJobsTotal: 50005,000$4.502
Daily monitor, no changesmode: changes0$0.002

Limits

  • 5,000 jobs per run (maxJobsTotal). A tested run returned 5,000 rows in about 6.5 minutes.
  • Workable daily request limits. Workable limits how many search pages and job-detail requests one IP address can make per day. When the limit is reached, Workable asks to wait about 24 hours. The Actor then stops asking for that kind of data, saves everything found so far and marks the source partial with the reason. In a test run this happened after about 400 search pages (about 8,000 search jobs). Company pages without includeDetails use only 2 requests per company and are rarely affected.
  • Default memory 512 MB and timeout 30 minutes are enough for 5,000 rows.

API, export and integrations

  • Export: in the Output tab use Export to download JSON, CSV, Excel, XML or HTML.
  • API: start the Actor with the Apify API and read the Dataset items endpoint. Read OUTPUT from the run's default key-value store to see the status of each company and search.
  • Scheduling: create an Apify schedule with mode: changes to get only new, changed and removed jobs.
  • Webhooks / no-code: use Apify integrations (Make, Zapier, Slack, Google Sheets, webhooks) to send new rows when a run finishes.
  • AI agents / MCP: the Actor can be called from the Apify MCP server like any other Actor.

Troubleshooting

A company returns not_found

Symptom: OUTPUT shows not_found for a company. Likely reason: the name is not a Workable company name, or the company left Workable. Check: open https://apply.workable.com/<name>/ in a browser. Action: copy the name exactly from the career page URL.

A source is partial with "daily request limit"

Symptom: fewer jobs than expected; the reason mentions Workable's daily limit. Likely reason: Workable limited requests from the IP address used by the run. Check: the rows already saved are valid and paid only once. Action: run the remaining companies or searches later or in smaller runs; turn off includeDetails if you do not need salary.

No hybrid or on-site jobs with the workplace filter

Symptom: workplaceTypes: ["hybrid"] returns no company jobs. Likely reason: without includeDetails, company pages show only whether a job is remote. Action: turn on includeDetails for small runs, or leave workplaceTypes empty and check workplace_type later.

The run failed at once

Symptom: run status Failed with "INVALID_INPUT". Likely reason: no company and no search, or a URL that is not a Workable company page. Action: read the message; it lists each wrong value.

FAQ

Do I need a Workable account or API key?

No. The Actor reads public career pages and the public job search only.

Why is salary empty?

Salary needs includeDetails and is filled only when the employer publishes it on the company page. The search never returns salary.

How fresh is the data?

Each run reads Workable at run time. scraped_at shows when each row was made.

Can I get all jobs from Workable?

No. One run returns up to 5,000 jobs, and Workable limits requests per day. Use companies, keywords, locations and postedWithin to focus on the jobs you need.

Are duplicates removed?

Yes. A company added twice is read once, and a job that appears on two search pages is returned once. The same job found by two different keywords appears once per search.

What does partial mean?

Some jobs of that company or search are missing because a limit was reached or Workable refused more requests. The reason is in OUTPUT. Rows that were saved are correct.

Support

For a bug, question or feature request, open the Issues tab of this Actor. Include the run ID, the input mode and the error text from OUTPUT. Never send API tokens or private data.

This Actor is not affiliated with or endorsed by Workable.