Workable Jobs Scraper | $1.99 / 1k |
Pricing
from $1.99 / 1,000 job results
Workable Jobs Scraper | $1.99 / 1k |
Scrape live job ads from Workable boards. Search by keyword, location or remote status, or pull one company board. Title, company, domain, city, workplace type, department, apply link and full ad text.
Pricing
from $1.99 / 1,000 job results
Rating
0.0
(0)
Developer
Raffy
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
What does Workable Jobs Scraper do?
Get a live feed of job adverts straight from the employers who posted them: title, company, company domain, city, country, remote or hybrid, department, dates, apply link and the full advert text. It is built for job boards, recruiters and sales teams who need first-party hiring data rather than a second-hand aggregator copy.
Point it at a keyword search, one company's careers page or a single posting and scrape Workable jobs into JSON, CSV or Excel, or read them from the Apify API. It is the practical way to turn the public Workable job board into a remote jobs API or a company hiring data feed without an API key, a headless browser or residential proxies.
Workable hosts the careers pages of tens of thousands of small and mid-sized employers, and its public board carries 170,000+ live openings at any moment. Every advert comes straight out of the employer's own applicant-tracking system, so there are no aggregator duplicates and no stale reposts. The default 20-job run finished in 3.1 seconds on the Apify platform.
It does not log in, solve captchas, circumvent access controls or collect private user data. It reads only pages that anyone can open in a browser.
Use cases for this Workable scraper
- Job board or aggregator seeding listings. Keep a niche board - remote engineering, healthcare, one country - stocked with fresh, complete adverts including
description,departmentandapplyUrl, instead of thin stubs that send users elsewhere. - Sales team finding companies that are hiring. A new opening is a buying signal. Filter on
departmentandtitle, then enrich your CRM withcompany,companyDomainandcountryto reach the buyer while the budget is still open. - Recruitment agency building a client pipeline. Track which employers post engineering or sales roles week after week, and approach the ones whose team is visibly scaling -
createdAtandpublishedAtshow exactly when each search started. - Market researcher tracking hiring trends. Build time series of postings by
department,workplaceandcountry, or measure how quickly a single company grows a team by re-running its board on a schedule. - Talent sourcing and career tools. Power a job-matching feature, a remote-work newsletter or a "who is hiring for X" digest, using
isRemoteandlocationto route each advert to the right audience. - Competitive and portfolio monitoring. Watch a defined list of companies by slug and get an alert the moment one of them opens a role in a new city, a new department or a new language.
What data you get from every Workable job advert
One row per job advert. Every column below exists in the dataset schema; the Jobs overview table view shows title, company, location, workplace, employmentType, department, publishedAt, jobUrl, status, error and scrapedAt, and the Full job records view shows all of them.
Row status and provenance
| Field | Type | Description |
|---|---|---|
url | string | Source URL the row was extracted from. On not_found / error rows this is the page that failed. |
status | string | ok, not_found or error (see the table below). |
error | string | Reason when status is not ok. Absent on ok rows. |
scrapedAt | string | ISO 8601 time of extraction. |
Job identity and links
| Field | Type | Description |
|---|---|---|
jobId | string | Stable UUID of the posting. |
shortcode | string | Short public job code used in the job URL. |
title | string | Job title as published by the employer. |
jobUrl | string | Public job page on the Workable board. |
applyUrl | string | Where the application starts: the employer's external link when there is one, otherwise the job page. |
Company
| Field | Type | Description |
|---|---|---|
company | string | Hiring company name. |
companyDomain | string | Bare company domain, e.g. eurodyn.com. Empty when the employer published no website. |
companyUrl | string | Company page listing all of that employer's open roles. |
accountSlug | string | Workable account slug (apply.workable.com/<slug>), set when the run started from a company slug or careers-site URL, or when the employer lists that page as its website. |
Location and workplace
| Field | Type | Description |
|---|---|---|
location | string | Location as displayed, e.g. Athens, Attica, Greece. |
city | string | City part of the location. |
region | string | State, province or region part of the location. |
country | string | Country name. |
isRemote | boolean | True when the workplace type is remote. |
workplace | string | remote, hybrid or on_site. |
Role details
| Field | Type | Description |
|---|---|---|
employmentType | string | Full-time, Part-time, Contract, ... Empty when the employer left it blank. |
department | string | Department or team, e.g. Engineering. |
language | string | ISO language code of the advert, e.g. en. |
Dates
| Field | Type | Description |
|---|---|---|
createdAt | string | ISO 8601 time the posting was created. |
publishedAt | string | ISO 8601 time the posting was last (re)published. |
Advert text
| Field | Type | Description |
|---|---|---|
description | string | The full advert as plain text: description, requirements and benefits. Needs includeDescription. |
descriptionHtml | string | The same advert with the employer's original HTML markup. Needs includeDescription. |
A missing optional field is honest: it means the employer did not publish that value, never a guess.
Result status (tri-state output)
status | Meaning | Billed? |
|---|---|---|
ok | The advert was found and extracted. | Yes |
not_found | The board answered, but there is no such job or company, or the search has zero hits. | No |
error | The board could not be read after retries (network error or a layout change). error says why. | No |
How to scrape Workable job listings
- Open the Actor in Apify Console and click Try for free.
- Fill in Workable board URLs or company slugs, or type a Search query instead. Every one of these works:
https://jobs.workable.com/search?query=python%20developer- keyword search across all companieshttps://jobs.workable.com/company/<id>/jobs-at-acme- one company's boardhttps://jobs.workable.com/view/<code>/<slug>- a single job postinghttps://apply.workable.com/acme- a company careers site (resolved to its board automatically)acme- just the company slug
- Optionally set Location, Remote jobs only and Maximum results (start with the default 20 to see the output).
- Click Start. The default run finishes in under 10 seconds.
- Open the Output tab or Export the dataset as JSON, CSV, Excel, XML or HTML.
To automate it, use the API tab (Node.js, Python, curl examples) or add a Schedule.
Input
Every field is optional - the prefilled values already produce a complete run. See the Input tab for the full schema.
| Field | Type | Default | When to change it |
|---|---|---|---|
startUrls | array of strings | ["https://jobs.workable.com/search?query=python%20developer"] | Set the exact boards you want: search URLs, company board URLs, single job URLs, apply.workable.com/<slug> URLs or bare company slugs, one per line. Use this whenever you already know the page or the companies to watch. |
query | string | empty | Use it instead of startUrls to search every company on the board by keyword, e.g. react developer or nurse. Ignored when startUrls is set. |
location | string | empty (worldwide) | Add a place filter - Germany, Berlin, Germany - to keep a run small and relevant instead of filtering afterwards. Applies to keyword searches, not to a single company board. |
remoteOnly | boolean | false | Turn it on to keep only postings whose workplace is remote; hybrid and on-site postings are skipped. |
maxItems | integer | 20 | Raise it for production pulls, lower it while testing. The board returns 20 jobs per request, so a multiple of 20 wastes nothing. This is your main spending cap. |
includeDescription | boolean | true | Turn it off when you only need the hiring signal (company, title, location): rows get roughly 10x smaller and export faster. The price per row does not change. |
proxyConfiguration | object | Apify Proxy off | Leave it off - the board answers plain HTTP from datacenter IPs. Enable the Apify Proxy datacenter group only if you start seeing error rows. |
Example input (exactly the prefilled default):
{"startUrls": ["https://jobs.workable.com/search?query=python%20developer"],"maxItems": 20,"includeDescription": true}
Searching by keyword instead of URL:
{"query": "customer support","location": "Germany","remoteOnly": true,"maxItems": 100}
Output
You can download the dataset as JSON, CSV, Excel, XML or HTML. This is a real row from a run of the default input (advert text shortened here; the dataset carries all 3,248 characters):
{"url": "https://jobs.workable.com/view/87gW9bnZMGhiuouxYfmutJ/remote-python-developer-in-athens-at-european-dynamics","status": "ok","scrapedAt": "2026-09-08T11:46:41.856Z","jobId": "399040a9-8c84-4a3d-ab9d-02ab036d6cf8","shortcode": "87gW9bnZMGhiuouxYfmutJ","title": "Python Developer","company": "EUROPEAN DYNAMICS","companyDomain": "eurodyn.com","companyUrl": "https://jobs.workable.com/company/fEngW8oPQVhXrenX1cLyBg/jobs-at-european-dynamics","location": "Athens, Attica, Greece","city": "Athens","region": "Attica","country": "Greece","isRemote": true,"workplace": "remote","employmentType": "Full-time","department": "PRA","createdAt": "2026-09-01T10:15:25.844Z","publishedAt": "2026-09-01T10:15:25.844Z","jobUrl": "https://jobs.workable.com/view/87gW9bnZMGhiuouxYfmutJ/remote-python-developer-in-athens-at-european-dynamics","applyUrl": "https://jobs.workable.com/view/87gW9bnZMGhiuouxYfmutJ/remote-python-developer-in-athens-at-european-dynamics","language": "en","description": "Are you a Python Developer looking for an exciting opportunity to join a dynamic team? Join us in Athens or work remotely, and become part of our expanding development teams working on innovative projects...","descriptionHtml": "<p>Are you a <strong>Python Developer</strong> looking for an exciting opportunity to join a dynamic team? ...</p>"}
Rows that are not ok look like this and are never billed:
[{"url": "https://jobs.workable.com/search?query=python&remote=true","status": "not_found","error": "No results on this page","scrapedAt": "2026-09-08T11:46:42.101Z"},{"url": "https://jobs.workable.com/company/does-not-exist","status": "not_found","error": "HTTP 404: page does not exist","scrapedAt": "2026-09-08T11:46:42.140Z"}]
How much does it cost to scrape Workable jobs?
This Actor uses pay-per-event pricing:
| Event | Price | Charged when |
|---|---|---|
| Actor start | $0.005 per run | Once when the run starts. The platform charges one event per GB of memory and the Actor runs on 1 GB, so this is one event. |
| Job result | $0.00199 per job | One job advert with status: ok was saved to the dataset. |
1,000 job adverts cost about $2.00 ($0.005 to start plus 1,000 x $0.00199); 100 jobs cost about $0.20. You are never charged for a row with status not_found or error, and never for a duplicate: the board can reshuffle its ranking between two paginated requests, so the Actor drops any posting whose jobId it has already emitted in the same run. The free Apify plan's $5 of monthly credit covers about 2,500 jobs in a single run.
You can cap spending per run with Maximum results and with the run's Max total charge option; the Actor stops gracefully when either limit is reached and keeps everything it has already saved.
How it compares
This Actor is built for breadth and freshness on one source. Because every advert comes from the employer's own applicant-tracking system, you get the complete original text, a real companyDomain and no duplicate reposts - and because it is pure HTTP, a full advert costs a fraction of a request and a run finishes in seconds.
It is not for you if you need salary data (the public board does not publish it as a structured field), if you need coverage of large enterprises that use a different hiring system, if you want deep pagination through a single company's board, or if you need a vendor-backed feed with a stability guarantee. It reads one public source, and reports honestly when that source changes.
Integrations, exports and API access
Results export to CSV, JSON, Excel, XML and HTML from the Output tab or the dataset API. From there, Apify integrations and webhooks push the same rows into Google Sheets, Airtable or a CRM, plus Slack, Amazon S3 or your own endpoint - directly, or through Zapier, Make and n8n. Add a Schedule and today's new adverts land in your sheet every morning.
The Actor can also be called from the Apify API (Node.js, Python and curl snippets are on the API tab), from the Apify MCP server, or by any AI agent that can call a tool: the inputs are plain strings and booleans, and every row carries status and error, so an agent can tell an empty search apart from a failure without parsing prose.
Tips
- Keep
maxItemsa multiple of 20 - the board hands out 20 jobs per request, so nothing is wasted. - Pass several start URLs in one run instead of many single-URL runs; you pay the start fee once.
- Combine
querywithlocationandremoteOnlyto keep runs small and relevant instead of filtering afterwards. - Set
includeDescriptiontofalsewhen you only need the hiring signal (company, title, location); rows get roughly 10x smaller and export faster. The price per row is unchanged. - Schedule a daily run with the same search and diff the
jobIdcolumn to get "new jobs today".
Limitations
- A single company board returns its first 20 openings. The public company page server-renders one page of results; larger employers publish more. To reach the rest, use a keyword search (which paginates through thousands of results) or the company's own careers site.
- No salary field. Workable's public board does not expose structured salary data. When an employer mentions pay, it is inside
description. employmentTypeanddepartmentare often empty - they are optional for the employer, and many leave them blank.- Only published, public jobs. Internal, draft, archived and password-protected postings are invisible to this Actor, and it does not log in to reach them.
- Board-hosted adverts only. Employers who redirect applicants to another system get an external
applyUrl, but the advert text still comes from the Workable board. - Results reflect the public page at the time of the run. If the board changes its layout, rows come back as
errorrather than silently wrong; report it in the Issues tab and the Actor is updated quickly.
FAQ
Do I need a Workable API key or an account? No. The Actor reads the same public pages a visitor sees; there is no login and no key. All you need is an Apify account.
How do I get more results? Raise maxItems and search by keyword rather than by company: a keyword search paginates through thousands of hits, while one company board serves only its first 20 openings. Widen the query, drop location or remoteOnly, or pass several start URLs in a single run.
How often does the data change? Continuously. Employers publish, edit and close roles through the day, and publishedAt moves whenever a posting is republished. Schedule a daily run and diff the jobId column if you want a clean "new today" list.
What happens if the board changes? Rows come back with status: error and a reason instead of silently wrong data, so your pipeline can alert on it. Report it in the Issues tab with the run ID; you are not billed for error rows in the meantime.
Does it return recruiter e-mails or phone numbers? No. See the notice below: no personal-contact column exists in the output, and any e-mail address an employer typed into their own advert is removed from the text before the row is saved.
Can I use this Actor from an AI agent or MCP client? Yes. Inputs are plain strings, every row is self-describing (status plus error), and results can be fetched via the dataset API or the Apify MCP server.
Why did I get fewer rows than maxItems? The search had fewer hits, the company board has fewer openings, or the run hit your Max total charge limit. Check the run log for "Stopping gracefully".
Can I scrape several companies at once? Yes. Put one slug or careers-site URL per line in Workable board URLs or company slugs; they are all crawled in the same run and you pay the start fee once.
Legal and data-protection notice
This Actor extracts only data that Workable publishes publicly on its job board, and only business data about jobs and hiring companies: job titles, adverts, locations, departments, workplace types, dates, company names and company websites.
It does not emit recruiter or hiring-manager names, e-mail addresses or phone numbers. The board's public payload contains no such fields, the Actor copies only the columns documented above, and as an extra safeguard any e-mail address or mailto: / tel: link that an employer typed into their own advert text is replaced with [email removed] / [contact removed] before the row is saved. The Actor does not log in, does not solve captchas and does not circumvent access controls.
Job adverts can nevertheless mention individuals. Personal data is protected by the GDPR in the European Union and by other regulations around the world; you should not process personal data without a legitimate reason. If you are unsure whether your reason is legitimate, consult your lawyers. You are responsible for complying with Workable's terms of service and with applicable law when you use the extracted data.
This Actor is an independent tool. It is not affiliated with, endorsed by or sponsored by Workable or its owners. All trademarks belong to their respective owners.